@ohif/app 3.8.0-beta.71 → 3.8.0-beta.72

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/{155.bundle.091ace1591aff1f6b679.js → 155.bundle.bebcbc0ca715c7163f18.js} +53 -43
  2. package/dist/{191.bundle.ef35ed1f90a988b3952b.js → 191.bundle.c0ea2d031ffddeca32c9.js} +34 -127
  3. package/dist/{342.bundle.9be178d7555a64de203a.js → 342.bundle.521c0217f82380c0c2ad.js} +22 -8
  4. package/dist/{41.bundle.b5a6c70f88cf565cad3e.js → 41.bundle.9db45ce95f2fd889447d.js} +18 -7
  5. package/dist/{504.bundle.5ccd6d4269fa77a0a7e7.js → 433.bundle.6f2308ab10593784778c.js} +135 -11
  6. package/dist/{530.bundle.566bfd08dccb4cf6d98b.js → 530.bundle.f4b7966fb33eafb8cd5d.js} +17 -16
  7. package/dist/{559.bundle.fb8ac10c41eb734e2f3d.js → 540.bundle.792745c8d390c3fc83cf.js} +75 -42
  8. package/dist/{595.bundle.c25147a450c67defb3d5.js → 595.bundle.d9e4c2a6311ce8ed929b.js} +156 -67
  9. package/dist/{726.bundle.c8de818cf1a3ff0cf7d2.js → 726.bundle.0b3d9277d22fe7e15b89.js} +2 -2
  10. package/dist/{889.bundle.1c17d0d13e157ac21d38.js → 889.bundle.9ca0963a74448c6b0366.js} +1 -1
  11. package/dist/{90.bundle.27637ef740946d5c8948.js → 90.bundle.3c0e23243f8ad444dcb5.js} +2 -2
  12. package/dist/{987.bundle.6bdfb3cd8762b8889632.js → 987.bundle.e19408decfd59aadd118.js} +50 -137
  13. package/dist/{app.bundle.d1c8b09ab30d221fddf0.js → app.bundle.8aa9dfeaad37206d66e3.js} +28 -21
  14. package/dist/cornerstoneDICOMImageLoader.min.js +1 -1
  15. package/dist/cornerstoneDICOMImageLoader.min.js.map +1 -1
  16. package/dist/index.html +1 -1
  17. package/dist/{polySeg.bundle.01449e456b7d4a737d4f.js → polySeg.bundle.fe47718e6a8414f175b1.js} +3 -3
  18. package/dist/sw.js +1 -1
  19. package/package.json +18 -18
  20. /package/dist/{164.bundle.fcc94cd4e142a409769d.js → 164.bundle.403c8665844596f8a320.js} +0 -0
  21. /package/dist/{188.bundle.0081530bd886a18676eb.js → 188.bundle.c23415079424cb48aa70.js} +0 -0
  22. /package/dist/{2.bundle.ab8937194aad592bc7b4.js → 2.bundle.a423ca428b035655c6eb.js} +0 -0
  23. /package/dist/{425.bundle.e44cfce041ba5209a878.js → 425.bundle.fa277d2575477589ff4a.js} +0 -0
  24. /package/dist/{448.bundle.599d81471e1d7f7962bc.js → 448.bundle.2f5b66d084f92c556edd.js} +0 -0
  25. /package/dist/{574.bundle.b262cbe9f2afd7275271.js → 574.bundle.2b3369042aad5d553463.js} +0 -0
  26. /package/dist/{594.bundle.b70ca7a91d85ebd5d8c4.js → 594.bundle.2af345e8ec58d538a9ae.js} +0 -0
  27. /package/dist/{699.bundle.02c15c3cc4c04dbf7f51.js → 699.bundle.3783f122f84be6a5eb30.js} +0 -0
  28. /package/dist/{724.bundle.d50ce9fb0ab01b9378b7.js → 724.bundle.abdadacc4d7497aa7431.js} +0 -0
  29. /package/dist/{862.bundle.809c87a7ba9da6fb29c8.js → 862.bundle.47305c27f0fb939c2f97.js} +0 -0
  30. /package/dist/{905.bundle.206e44c3bbd1df1a900b.js → 905.bundle.aa96c1209ab1b78fdf2b.js} +0 -0
  31. /package/dist/{907.bundle.11700f7af989b5af8bc3.js → 907.bundle.f8db9076d882586ac6e6.js} +0 -0
  32. /package/dist/{961.bundle.a1ffb667eb04cbe07210.js → 961.bundle.0114ec1cc534b2b7739f.js} +0 -0
@@ -1,4 +1,4 @@
1
- (globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push([[504],{
1
+ (globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push([[433],{
2
2
 
3
3
  /***/ 79697:
4
4
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
@@ -4592,6 +4592,8 @@ var isViewportPreScaled = __webpack_require__(97022);
4592
4592
  var getModalityUnit = __webpack_require__(73801);
4593
4593
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/math/basic/index.js + 2 modules
4594
4594
  var basic = __webpack_require__(83112);
4595
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/contours/calculatePerimeter.js
4596
+ var calculatePerimeter = __webpack_require__(53891);
4595
4597
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/tools/base/ContourSegmentationBaseTool.js + 1 modules
4596
4598
  var ContourSegmentationBaseTool = __webpack_require__(76840);
4597
4599
  ;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/tools/annotation/PlanarFreehandROITool.js
@@ -4618,6 +4620,7 @@ var ContourSegmentationBaseTool = __webpack_require__(76840);
4618
4620
 
4619
4621
 
4620
4622
 
4623
+
4621
4624
 
4622
4625
 
4623
4626
  const { pointCanProjectOnLine } = math.polyline;
@@ -4653,7 +4656,7 @@ class PlanarFreehandROITool extends ContourSegmentationBaseTool/* default */.A {
4653
4656
  enabled: false,
4654
4657
  epsilon: 0.1,
4655
4658
  },
4656
- calculateStats: false,
4659
+ calculateStats: true,
4657
4660
  getTextLines: defaultGetTextLines,
4658
4661
  statsCalculator: basic.BasicStatsCalculator,
4659
4662
  },
@@ -4691,6 +4694,7 @@ class PlanarFreehandROITool extends ContourSegmentationBaseTool/* default */.A {
4691
4694
  else {
4692
4695
  this.activateOpenContourEdit(evt, annotation, viewportIdsToRender);
4693
4696
  }
4697
+ evt.preventDefault();
4694
4698
  };
4695
4699
  this.isPointNearTool = (element, annotation, canvasCoords, proximity) => {
4696
4700
  const enabledElement = (0,esm.getEnabledElement)(element);
@@ -4730,7 +4734,7 @@ class PlanarFreehandROITool extends ContourSegmentationBaseTool/* default */.A {
4730
4734
  this._calculateCachedStats = (annotation, viewport, renderingEngine, enabledElement) => {
4731
4735
  const { data } = annotation;
4732
4736
  const { cachedStats } = data;
4733
- const { polyline: points } = data.contour;
4737
+ const { polyline: points, closed } = data.contour;
4734
4738
  const targetIds = Object.keys(cachedStats);
4735
4739
  for (let i = 0; i < targetIds.length; i++) {
4736
4740
  const targetId = targetIds[i];
@@ -4831,6 +4835,7 @@ class PlanarFreehandROITool extends ContourSegmentationBaseTool/* default */.A {
4831
4835
  cachedStats[targetId] = {
4832
4836
  Modality: metadata.Modality,
4833
4837
  area,
4838
+ perimeter: (0,calculatePerimeter/* default */.A)(canvasCoordinates, closed),
4834
4839
  mean: stats.mean?.value,
4835
4840
  max: stats.max?.value,
4836
4841
  stdDev: stats.stdDev?.value,
@@ -4940,7 +4945,7 @@ class PlanarFreehandROITool extends ContourSegmentationBaseTool/* default */.A {
4940
4945
  const onInterpolationComplete = (annotation) => {
4941
4946
  annotation.data.handles.points.length = 0;
4942
4947
  };
4943
- return esm.utilities.deepMerge(contourAnnotation, {
4948
+ const annotation = esm.utilities.deepMerge(contourAnnotation, {
4944
4949
  data: {
4945
4950
  contour: {
4946
4951
  polyline: [[...worldPos]],
@@ -4950,6 +4955,7 @@ class PlanarFreehandROITool extends ContourSegmentationBaseTool/* default */.A {
4950
4955
  },
4951
4956
  onInterpolationComplete,
4952
4957
  });
4958
+ return annotation;
4953
4959
  }
4954
4960
  getAnnotationStyle(context) {
4955
4961
  return super.getAnnotationStyle(context);
@@ -5021,7 +5027,7 @@ class PlanarFreehandROITool extends ContourSegmentationBaseTool/* default */.A {
5021
5027
  }
5022
5028
  function defaultGetTextLines(data, targetId) {
5023
5029
  const cachedVolumeStats = data.cachedStats[targetId];
5024
- const { area, mean, stdDev, max, isEmptyArea, areaUnit, modalityUnit } = cachedVolumeStats || {};
5030
+ const { area, mean, stdDev, perimeter, max, isEmptyArea, areaUnit, modalityUnit, } = cachedVolumeStats || {};
5025
5031
  const textLines = [];
5026
5032
  if (area) {
5027
5033
  const areaLine = isEmptyArea
@@ -5038,6 +5044,9 @@ function defaultGetTextLines(data, targetId) {
5038
5044
  if (stdDev) {
5039
5045
  textLines.push(`Std Dev: ${(0,utilities.roundNumber)(stdDev)} ${modalityUnit}`);
5040
5046
  }
5047
+ if (perimeter) {
5048
+ textLines.push(`Perimeter: ${(0,utilities.roundNumber)(perimeter)} ${modalityUnit}`);
5049
+ }
5041
5050
  return textLines;
5042
5051
  }
5043
5052
  PlanarFreehandROITool.toolName = 'PlanarFreehandROI';
@@ -6580,24 +6589,30 @@ function validate(segmentationRepresentationData) {
6580
6589
 
6581
6590
  /***/ }),
6582
6591
 
6583
- /***/ 57313:
6592
+ /***/ 33944:
6584
6593
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
6585
6594
 
6586
6595
  "use strict";
6587
6596
 
6588
6597
  // EXPORTS
6589
6598
  __webpack_require__.d(__webpack_exports__, {
6590
- u: () => (/* reexport */ surfaceDisplay)
6599
+ A: () => (/* binding */ displayTools_SegmentationDisplayTool)
6591
6600
  });
6592
6601
 
6593
6602
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/index.js + 383 modules
6594
6603
  var esm = __webpack_require__(50719);
6595
- // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/segmentation/segmentationState.js + 2 modules
6596
- var segmentationState = __webpack_require__(30322);
6597
6604
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/enums/SegmentationRepresentations.js
6598
6605
  var SegmentationRepresentations = __webpack_require__(83946);
6606
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/segmentation/index.js + 31 modules
6607
+ var stateManagement_segmentation = __webpack_require__(63421);
6608
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/segmentation/config/segmentationVisibility.js
6609
+ var segmentationVisibility = __webpack_require__(23308);
6610
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/segmentation/segmentationState.js + 2 modules
6611
+ var segmentationState = __webpack_require__(30322);
6599
6612
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/store/ToolGroupManager/index.js
6600
6613
  var ToolGroupManager = __webpack_require__(52610);
6614
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/tools/base/index.js
6615
+ var base = __webpack_require__(96214);
6601
6616
  ;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/tools/displayTools/Surface/removeSurfaceFromElement.js
6602
6617
 
6603
6618
  function removeContourFromElement(element, segmentationRepresentationUID, removeFromCache = false) {
@@ -6686,8 +6701,6 @@ function addOrUpdateSurfaceToElement(element, surface, segmentationRepresentatio
6686
6701
  }
6687
6702
  /* harmony default export */ const Surface_addOrUpdateSurfaceToElement = (addOrUpdateSurfaceToElement);
6688
6703
 
6689
- // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/segmentation/index.js + 31 modules
6690
- var stateManagement_segmentation = __webpack_require__(63421);
6691
6704
  ;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/tools/displayTools/Surface/surfaceDisplay.js
6692
6705
 
6693
6706
 
@@ -6768,6 +6781,117 @@ function _removeSurfaceFromToolGroupViewports(toolGroupId, segmentationRepresent
6768
6781
 
6769
6782
 
6770
6783
 
6784
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/tools/displayTools/Contour/index.js
6785
+ var Contour = __webpack_require__(2884);
6786
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/tools/displayTools/Labelmap/index.js
6787
+ var Labelmap = __webpack_require__(94318);
6788
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/store/index.js + 4 modules
6789
+ var store = __webpack_require__(61738);
6790
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/tools/annotation/PlanarFreehandContourSegmentationTool.js
6791
+ var PlanarFreehandContourSegmentationTool = __webpack_require__(20070);
6792
+ ;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/tools/displayTools/SegmentationDisplayTool.js
6793
+
6794
+
6795
+
6796
+
6797
+
6798
+
6799
+
6800
+
6801
+
6802
+
6803
+
6804
+
6805
+
6806
+ const planarContourToolName = PlanarFreehandContourSegmentationTool/* default */.A.toolName;
6807
+ class SegmentationDisplayTool extends base/* BaseTool */.oS {
6808
+ constructor(toolProps = {}, defaultToolProps = {
6809
+ configuration: {},
6810
+ }) {
6811
+ super(toolProps, defaultToolProps);
6812
+ this.renderSegmentation = (toolGroupId) => {
6813
+ const toolGroup = (0,ToolGroupManager.getToolGroup)(toolGroupId);
6814
+ if (!toolGroup) {
6815
+ return;
6816
+ }
6817
+ const toolGroupSegmentationRepresentations = (0,segmentationState.getSegmentationRepresentations)(toolGroupId);
6818
+ if (!toolGroupSegmentationRepresentations ||
6819
+ toolGroupSegmentationRepresentations.length === 0) {
6820
+ return;
6821
+ }
6822
+ const toolGroupViewports = toolGroup.viewportsInfo.map(({ renderingEngineId, viewportId }) => {
6823
+ const enabledElement = (0,esm.getEnabledElementByIds)(viewportId, renderingEngineId);
6824
+ if (enabledElement) {
6825
+ return enabledElement.viewport;
6826
+ }
6827
+ });
6828
+ const segmentationRenderList = toolGroupSegmentationRepresentations.map((representation) => {
6829
+ const config = this._getMergedRepresentationsConfig(toolGroupId);
6830
+ const viewportsRenderList = [];
6831
+ const renderers = {
6832
+ [SegmentationRepresentations/* default */.A.Labelmap]: Labelmap/* labelmapDisplay */.Zy,
6833
+ [SegmentationRepresentations/* default */.A.Contour]: Contour/* contourDisplay */.T,
6834
+ [SegmentationRepresentations/* default */.A.Surface]: surfaceDisplay,
6835
+ };
6836
+ if (representation.type === SegmentationRepresentations/* default */.A.Contour) {
6837
+ this.addPlanarFreeHandToolIfAbsent(toolGroupId);
6838
+ }
6839
+ const display = renderers[representation.type];
6840
+ for (const viewport of toolGroupViewports) {
6841
+ const renderedViewport = display.render(viewport, representation, config);
6842
+ viewportsRenderList.push(renderedViewport);
6843
+ }
6844
+ return viewportsRenderList;
6845
+ });
6846
+ Promise.allSettled(segmentationRenderList).then(() => {
6847
+ toolGroupViewports.forEach((viewport) => {
6848
+ viewport.render();
6849
+ });
6850
+ });
6851
+ };
6852
+ }
6853
+ onSetToolEnabled() {
6854
+ const toolGroupId = this.toolGroupId;
6855
+ const toolGroupSegmentationRepresentations = (0,segmentationState.getSegmentationRepresentations)(toolGroupId);
6856
+ if (!toolGroupSegmentationRepresentations ||
6857
+ toolGroupSegmentationRepresentations.length === 0) {
6858
+ return;
6859
+ }
6860
+ toolGroupSegmentationRepresentations.forEach((segmentationRepresentation) => {
6861
+ (0,segmentationVisibility.setSegmentationVisibility)(toolGroupId, segmentationRepresentation.segmentationRepresentationUID, true);
6862
+ });
6863
+ }
6864
+ onSetToolDisabled() {
6865
+ const toolGroupId = this.toolGroupId;
6866
+ const toolGroupSegmentationRepresentations = (0,segmentationState.getSegmentationRepresentations)(toolGroupId);
6867
+ if (!toolGroupSegmentationRepresentations ||
6868
+ toolGroupSegmentationRepresentations.length === 0) {
6869
+ return;
6870
+ }
6871
+ toolGroupSegmentationRepresentations.forEach((segmentationRepresentation) => {
6872
+ (0,segmentationVisibility.setSegmentationVisibility)(toolGroupId, segmentationRepresentation.segmentationRepresentationUID, false);
6873
+ });
6874
+ }
6875
+ addPlanarFreeHandToolIfAbsent(toolGroupId) {
6876
+ if (!(planarContourToolName in store/* state */.wk.tools)) {
6877
+ (0,store/* addTool */.Gx)(PlanarFreehandContourSegmentationTool/* default */.A);
6878
+ }
6879
+ const toolGroup = (0,ToolGroupManager.getToolGroup)(toolGroupId);
6880
+ if (!toolGroup.hasTool(planarContourToolName)) {
6881
+ toolGroup.addTool(planarContourToolName);
6882
+ toolGroup.setToolPassive(planarContourToolName);
6883
+ }
6884
+ }
6885
+ _getMergedRepresentationsConfig(toolGroupId) {
6886
+ const toolGroupConfig = stateManagement_segmentation.config.getToolGroupSpecificConfig(toolGroupId);
6887
+ const globalConfig = stateManagement_segmentation.config.getGlobalConfig();
6888
+ const mergedConfig = esm.utilities.deepMerge(globalConfig, toolGroupConfig);
6889
+ return mergedConfig;
6890
+ }
6891
+ }
6892
+ SegmentationDisplayTool.toolName = 'SegmentationDisplay';
6893
+ /* harmony default export */ const displayTools_SegmentationDisplayTool = (SegmentationDisplayTool);
6894
+
6771
6895
 
6772
6896
  /***/ }),
6773
6897
 
@@ -134,6 +134,11 @@ function OHIFCornerstoneSRViewport(props) {
134
134
  // not throwing an error?
135
135
  console.warn('More than one SOPClassUID in the same series is not yet supported.');
136
136
  }
137
+
138
+ // if (!srDisplaySet.measurements || !srDisplaySet.measurements.length) {
139
+ // return;
140
+ // }
141
+
137
142
  _getViewportReferencedDisplaySetData(srDisplaySet, newMeasurementSelected, displaySetService).then(({
138
143
  referencedDisplaySet,
139
144
  referencedDisplaySetMetadata
@@ -238,12 +243,16 @@ function OHIFCornerstoneSRViewport(props) {
238
243
  * if it is hydrated we don't even use the SR viewport.
239
244
  */
240
245
  (0,react__WEBPACK_IMPORTED_MODULE_1__.useEffect)(() => {
241
- if (!srDisplaySet.isLoaded) {
242
- srDisplaySet.load();
243
- }
244
- const numMeasurements = srDisplaySet.measurements.length;
245
- setMeasurementCount(numMeasurements);
246
- }, [srDisplaySet]);
246
+ const loadSR = async () => {
247
+ if (!srDisplaySet.isLoaded) {
248
+ await srDisplaySet.load();
249
+ }
250
+ const numMeasurements = srDisplaySet.measurements.length;
251
+ setMeasurementCount(numMeasurements);
252
+ updateViewport(measurementSelected);
253
+ };
254
+ loadSR();
255
+ }, [dataSource, srDisplaySet]);
247
256
 
248
257
  /**
249
258
  * Hook to update the tracking identifiers when the selected measurement changes or
@@ -260,18 +269,10 @@ function OHIFCornerstoneSRViewport(props) {
260
269
  * Todo: what is this, not sure what it does regarding the react aspect,
261
270
  * it is updating a local variable? which is not state.
262
271
  */
263
- let isLocked = trackedMeasurements?.context?.trackedSeries?.length > 0;
272
+ const [isLocked, setIsLocked] = (0,react__WEBPACK_IMPORTED_MODULE_1__.useState)(trackedMeasurements?.context?.trackedSeries?.length > 0);
264
273
  (0,react__WEBPACK_IMPORTED_MODULE_1__.useEffect)(() => {
265
- isLocked = trackedMeasurements?.context?.trackedSeries?.length > 0;
274
+ setIsLocked(trackedMeasurements?.context?.trackedSeries?.length > 0);
266
275
  }, [trackedMeasurements]);
267
-
268
- /**
269
- * Data fetching for the SR displaySet, which updates the measurements and
270
- * also gets the referenced image displaySet that SR is based on.
271
- */
272
- (0,react__WEBPACK_IMPORTED_MODULE_1__.useEffect)(() => {
273
- updateViewport(measurementSelected);
274
- }, [dataSource, srDisplaySet]);
275
276
  (0,react__WEBPACK_IMPORTED_MODULE_1__.useEffect)(() => {
276
277
  viewportActionCornersService.setComponents([{
277
278
  viewportId,
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
- (globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push([[559],{
2
+ (globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push([[540],{
3
3
 
4
- /***/ 89559:
4
+ /***/ 53540:
5
5
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
6
6
 
7
7
  // ESM COMPAT FLAG
@@ -91,6 +91,9 @@ class DICOMSRDisplayTool extends dist_esm.AnnotationTool {
91
91
  toolName: this.getToolName(),
92
92
  viewportId: enabledElement.viewport.id
93
93
  };
94
+ const {
95
+ style: annotationStyle
96
+ } = dist_esm.annotation.config;
94
97
  for (let i = 0; i < filteredAnnotations.length; i++) {
95
98
  const annotation = filteredAnnotations[i];
96
99
  const annotationUID = annotation.annotationUID;
@@ -104,13 +107,15 @@ class DICOMSRDisplayTool extends dist_esm.AnnotationTool {
104
107
  referencedImageId
105
108
  } = annotation.metadata;
106
109
  styleSpecifier.annotationUID = annotationUID;
110
+ const groupStyle = annotationStyle.getToolGroupToolStyles(this.toolGroupId)[this.getToolName()];
107
111
  const lineWidth = this.getStyle('lineWidth', styleSpecifier, annotation);
108
112
  const lineDash = this.getStyle('lineDash', styleSpecifier, annotation);
109
113
  const color = cachedStats.TrackingUniqueIdentifier === activeTrackingUniqueIdentifier ? 'rgb(0, 255, 0)' : this.getStyle('color', styleSpecifier, annotation);
110
114
  const options = {
111
115
  color,
112
116
  lineDash,
113
- lineWidth
117
+ lineWidth,
118
+ ...groupStyle
114
119
  };
115
120
  Object.keys(renderableData).forEach(GraphicType => {
116
121
  const renderableDataForGraphicType = renderableData[GraphicType];
@@ -143,20 +148,21 @@ class DICOMSRDisplayTool extends dist_esm.AnnotationTool {
143
148
  };
144
149
  }
145
150
  _getTextBoxLinesFromLabels(labels) {
146
- // TODO -> max 3 for now (label + shortAxis + longAxis), need a generic solution for this!
151
+ // TODO -> max 5 for now (label + shortAxis + longAxis), need a generic solution for this!
147
152
 
148
- const labelLength = Math.min(labels.length, 3);
153
+ const labelLength = Math.min(labels.length, 5);
149
154
  const lines = [];
150
155
  for (let i = 0; i < labelLength; i++) {
151
156
  const labelEntry = labels[i];
152
- lines.push(`${_labelToShorthand(labelEntry.label)}${labelEntry.value}`);
157
+ lines.push(`${_labelToShorthand(labelEntry.label)}: ${labelEntry.value}`);
153
158
  }
154
159
  return lines;
155
160
  }
156
161
  renderPolyLine(svgDrawingHelper, viewport, renderableData, annotationUID, referencedImageId, options) {
157
162
  const drawingOptions = {
158
163
  color: options.color,
159
- width: options.lineWidth
164
+ width: options.lineWidth,
165
+ lineDash: options.lineDash
160
166
  };
161
167
  let allCanvasCoordinates = [];
162
168
  renderableData.map((data, index) => {
@@ -233,7 +239,8 @@ class DICOMSRDisplayTool extends dist_esm.AnnotationTool {
233
239
  const lineUID = `${index}`;
234
240
  dist_esm.drawing.drawEllipse(svgDrawingHelper, annotationUID, lineUID, canvasCorners[0], canvasCorners[1], {
235
241
  color: options.color,
236
- width: options.lineWidth
242
+ width: options.lineWidth,
243
+ lineDash: options.lineDash
237
244
  });
238
245
  });
239
246
  return canvasCoordinates;
@@ -313,16 +320,14 @@ const toolNames = {
313
320
  SRPlanarFreehandROI: 'SRPlanarFreehandROI'
314
321
  };
315
322
  /* harmony default export */ const tools_toolNames = (toolNames);
316
- ;// CONCATENATED MODULE: ../../../extensions/cornerstone-dicom-sr/src/utils/addMeasurement.ts
323
+ ;// CONCATENATED MODULE: ../../../extensions/cornerstone-dicom-sr/src/utils/addDICOMSRDisplayAnnotation.ts
317
324
 
318
325
 
319
326
 
320
327
 
321
328
 
322
329
  const EPSILON = 1e-4;
323
- const supportedLegacyCornerstoneTags = (/* unused pure expression or super */ null && (['cornerstoneTools@^4.0.0']));
324
- function addMeasurement(measurement, imageId, displaySetInstanceUID) {
325
- // TODO -> Render rotated ellipse .
330
+ function addDICOMSRDisplayAnnotation(measurement, imageId, frameNumber) {
326
331
  const toolName = tools_toolNames.DICOMSRDisplay;
327
332
  const measurementData = {
328
333
  TrackingUniqueIdentifier: measurement.TrackingUniqueIdentifier,
@@ -338,20 +343,23 @@ function addMeasurement(measurement, imageId, displaySetInstanceUID) {
338
343
  if (measurementData.renderableData[GraphicType] === undefined) {
339
344
  measurementData.renderableData[GraphicType] = [];
340
345
  }
341
- measurementData.renderableData[GraphicType].push(_getRenderableData(GraphicType, GraphicData, imageId, measurement.TrackingIdentifier));
346
+ measurementData.renderableData[GraphicType].push(_getRenderableData(GraphicType, GraphicData, imageId));
342
347
  });
343
-
344
- // Use the metadata provider to grab its imagePlaneModule metadata
345
348
  const imagePlaneModule = core_dist_esm.metaData.get('imagePlaneModule', imageId);
346
- const annotationManager = dist_esm.annotation.state.getAnnotationManager();
347
349
 
348
- // Create Cornerstone3D Annotation from measurement
349
- const frameNumber = measurement.coords[0].ReferencedSOPSequence && measurement.coords[0].ReferencedSOPSequence[0]?.ReferencedFrameNumber || 1;
350
+ /**
351
+ * This annotation (DICOMSRDisplay) is only used by the SR viewport.
352
+ * This is used before the annotation is hydrated. If hydrated the measurement will be added
353
+ * to the measurement service and will be available for the other viewports.
354
+ */
350
355
  const SRAnnotation = {
351
356
  annotationUID: measurement.TrackingUniqueIdentifier,
357
+ highlighted: false,
358
+ isLocked: false,
359
+ invalidated: false,
352
360
  metadata: {
353
- FrameOfReferenceUID: imagePlaneModule.frameOfReferenceUID,
354
361
  toolName: toolName,
362
+ FrameOfReferenceUID: imagePlaneModule.frameOfReferenceUID,
355
363
  referencedImageId: imageId
356
364
  },
357
365
  data: {
@@ -363,23 +371,13 @@ function addMeasurement(measurement, imageId, displaySetInstanceUID) {
363
371
  TrackingUniqueIdentifier: measurementData.TrackingUniqueIdentifier,
364
372
  renderableData: measurementData.renderableData
365
373
  },
366
- frameNumber: frameNumber
374
+ frameNumber
367
375
  }
368
376
  };
377
+ const annotationManager = dist_esm.annotation.state.getAnnotationManager();
369
378
  annotationManager.addAnnotation(SRAnnotation);
370
- measurement.loaded = true;
371
- measurement.imageId = imageId;
372
- measurement.displaySetInstanceUID = displaySetInstanceUID;
373
-
374
- // Remove the unneeded coord now its processed, but keep the SOPInstanceUID.
375
- // NOTE: We assume that each SCOORD in the MeasurementGroup maps onto one frame,
376
- // It'd be super weird if it didn't anyway as a SCOORD.
377
- measurement.ReferencedSOPInstanceUID = measurement.coords[0].ReferencedSOPSequence.ReferencedSOPInstanceUID;
378
- measurement.frameNumber = frameNumber;
379
- delete measurement.coords;
380
379
  }
381
- function _getRenderableData(GraphicType, GraphicData, imageId, TrackingIdentifier) {
382
- const [cornerstoneTag, toolName] = TrackingIdentifier.split(':');
380
+ function _getRenderableData(GraphicType, GraphicData, imageId) {
383
381
  let renderableData;
384
382
  switch (GraphicType) {
385
383
  case scoordTypes.POINT:
@@ -488,7 +486,7 @@ var adapters_es = __webpack_require__(83342);
488
486
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone-dicom-sr/src/utils/isRehydratable.js
489
487
 
490
488
  const cornerstoneAdapters = adapters_es/* adaptersSR */.QX.Cornerstone3D.MeasurementReport.CORNERSTONE_TOOL_CLASSES_BY_UTILITY_TYPE;
491
- const isRehydratable_supportedLegacyCornerstoneTags = ['cornerstoneTools@^4.0.0'];
489
+ const supportedLegacyCornerstoneTags = ['cornerstoneTools@^4.0.0'];
492
490
  const CORNERSTONE_3D_TAG = cornerstoneAdapters.CORNERSTONE_3D_TAG;
493
491
 
494
492
  /**
@@ -521,7 +519,7 @@ function isRehydratable(displaySet, mappings) {
521
519
  } = measurements[i] || {};
522
520
  const hydratable = adapters.some(adapter => {
523
521
  let [cornerstoneTag, toolName] = TrackingIdentifier.split(':');
524
- if (isRehydratable_supportedLegacyCornerstoneTags.includes(cornerstoneTag)) {
522
+ if (supportedLegacyCornerstoneTags.includes(cornerstoneTag)) {
525
523
  cornerstoneTag = CORNERSTONE_3D_TAG;
526
524
  }
527
525
  const mappedTrackingIdentifier = `${cornerstoneTag}:${toolName}`;
@@ -675,7 +673,7 @@ function _getDisplaySetsFromSeries(instances, servicesManager, extensionManager)
675
673
  displaySet.load = () => _load(displaySet, servicesManager, extensionManager);
676
674
  return [displaySet];
677
675
  }
678
- function _load(displaySet, servicesManager, extensionManager) {
676
+ async function _load(displaySet, servicesManager, extensionManager) {
679
677
  const {
680
678
  displaySetService,
681
679
  measurementService
@@ -685,6 +683,28 @@ function _load(displaySet, servicesManager, extensionManager) {
685
683
  const {
686
684
  ContentSequence
687
685
  } = displaySet.instance;
686
+ async function retrieveBulkData(obj, parentObj = null, key = null) {
687
+ for (const prop in obj) {
688
+ if (typeof obj[prop] === 'object' && obj[prop] !== null) {
689
+ await retrieveBulkData(obj[prop], obj, prop);
690
+ } else if (Array.isArray(obj[prop])) {
691
+ await Promise.all(obj[prop].map(item => retrieveBulkData(item, obj, prop)));
692
+ } else if (prop === 'BulkDataURI') {
693
+ const value = await dataSource.retrieve.bulkDataURI({
694
+ BulkDataURI: obj[prop],
695
+ StudyInstanceUID: displaySet.instance.StudyInstanceUID,
696
+ SeriesInstanceUID: displaySet.instance.SeriesInstanceUID,
697
+ SOPInstanceUID: displaySet.instance.SOPInstanceUID
698
+ });
699
+ if (parentObj && key) {
700
+ parentObj[key] = new Float32Array(value);
701
+ }
702
+ }
703
+ }
704
+ }
705
+ if (displaySet.isLoaded !== true) {
706
+ await retrieveBulkData(ContentSequence);
707
+ }
688
708
  displaySet.referencedImages = _getReferencedImagesList(ContentSequence);
689
709
  displaySet.measurements = _getMeasurements(ContentSequence);
690
710
  const mappings = measurementService.getSourceMappings(CORNERSTONE_3D_TOOLS_SOURCE_NAME, CORNERSTONE_3D_TOOLS_SOURCE_VERSION);
@@ -769,7 +789,18 @@ function _checkIfCanAddMeasurementsToDisplaySet(srDisplaySet, newDisplaySet, dat
769
789
  });
770
790
  }
771
791
  if (_measurementReferencesSOPInstanceUID(measurement, SOPInstanceUID, frameNumber)) {
772
- addMeasurement(measurement, imageId, newDisplaySet.displaySetInstanceUID);
792
+ const frame = measurement.coords[0].ReferencedSOPSequence && measurement.coords[0].ReferencedSOPSequence?.ReferencedFrameNumber || 1;
793
+
794
+ /** Add DICOMSRDisplay annotation for the SR viewport (only) */
795
+ addDICOMSRDisplayAnnotation(measurement, imageId, frame);
796
+
797
+ /** Update measurement properties */
798
+ measurement.loaded = true;
799
+ measurement.imageId = imageId;
800
+ measurement.displaySetInstanceUID = newDisplaySet.displaySetInstanceUID;
801
+ measurement.ReferencedSOPInstanceUID = measurement.coords[0].ReferencedSOPSequence.ReferencedSOPInstanceUID;
802
+ measurement.frameNumber = frame;
803
+ delete measurement.coords;
773
804
  unloadedMeasurements.splice(j, 1);
774
805
  }
775
806
  }
@@ -783,7 +814,7 @@ function _measurementReferencesSOPInstanceUID(measurement, SOPInstanceUID, frame
783
814
 
784
815
  // NOTE: The ReferencedFrameNumber can be multiple values according to the DICOM
785
816
  // Standard. But for now, we will support only one ReferenceFrameNumber.
786
- const ReferencedFrameNumber = measurement.coords[0].ReferencedSOPSequence && measurement.coords[0].ReferencedSOPSequence[0]?.ReferencedFrameNumber || 1;
817
+ const ReferencedFrameNumber = measurement.coords[0].ReferencedSOPSequence && measurement.coords[0].ReferencedSOPSequence?.ReferencedFrameNumber || 1;
787
818
  if (frameNumber && Number(frameNumber) !== Number(ReferencedFrameNumber)) {
788
819
  return false;
789
820
  }
@@ -1341,24 +1372,25 @@ function addToolInstance(name, toolClass, configuration) {
1341
1372
  function init({
1342
1373
  configuration = {}
1343
1374
  }) {
1344
- (0,dist_esm.addTool)(DICOMSRDisplayTool);
1345
- addToolInstance(tools_toolNames.SRLength, dist_esm.LengthTool, {});
1375
+ addToolInstance(tools_toolNames.DICOMSRDisplay, DICOMSRDisplayTool);
1376
+ addToolInstance(tools_toolNames.SRLength, dist_esm.LengthTool);
1346
1377
  addToolInstance(tools_toolNames.SRBidirectional, dist_esm.BidirectionalTool);
1347
1378
  addToolInstance(tools_toolNames.SREllipticalROI, dist_esm.EllipticalROITool);
1348
1379
  addToolInstance(tools_toolNames.SRCircleROI, dist_esm.CircleROITool);
1349
1380
  addToolInstance(tools_toolNames.SRArrowAnnotate, dist_esm.ArrowAnnotateTool);
1350
1381
  addToolInstance(tools_toolNames.SRAngle, dist_esm.AngleTool);
1382
+ addToolInstance(tools_toolNames.SRPlanarFreehandROI, dist_esm.PlanarFreehandROITool);
1383
+ addToolInstance(tools_toolNames.SRRectangleROI, dist_esm.RectangleROITool);
1384
+
1351
1385
  // TODO - fix the SR display of Cobb Angle, as it joins the two lines
1352
1386
  addToolInstance(tools_toolNames.SRCobbAngle, dist_esm.CobbAngleTool);
1353
- // TODO - fix the rehydration of Freehand, as it throws an exception
1354
- // on a missing polyline. The fix is probably in CS3D
1355
- addToolInstance(tools_toolNames.SRPlanarFreehandROI, dist_esm.PlanarFreehandROITool);
1356
1387
 
1357
1388
  // Modify annotation tools to use dashed lines on SR
1358
1389
  const dashedLine = {
1359
1390
  lineDash: '4,4'
1360
1391
  };
1361
1392
  dist_esm.annotation.config.style.setToolGroupToolStyles('SRToolGroup', {
1393
+ [tools_toolNames.DICOMSRDisplay]: dashedLine,
1362
1394
  SRLength: dashedLine,
1363
1395
  SRBidirectional: dashedLine,
1364
1396
  SREllipticalROI: dashedLine,
@@ -1367,6 +1399,7 @@ function init({
1367
1399
  SRCobbAngle: dashedLine,
1368
1400
  SRAngle: dashedLine,
1369
1401
  SRPlanarFreehandROI: dashedLine,
1402
+ SRRectangleROI: dashedLine,
1370
1403
  global: {}
1371
1404
  });
1372
1405
  }