@cornerstonejs/adapters 1.58.1 → 1.58.2

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.
@@ -48430,6 +48430,262 @@ let state = {
48430
48430
  handleRadius: 6
48431
48431
  };
48432
48432
 
48433
+ const defaultContourConfig$1 = {
48434
+ renderOutline: true,
48435
+ outlineWidthAutoGenerated: 3,
48436
+ outlineWidthActive: 2,
48437
+ outlineWidthInactive: 1,
48438
+ outlineOpacity: 1,
48439
+ outlineOpacityInactive: 0.85,
48440
+ outlineDashActive: undefined,
48441
+ outlineDashInactive: undefined,
48442
+ outlineDashAutoGenerated: '5,3',
48443
+ activeSegmentOutlineWidthDelta: 0,
48444
+ renderFill: true,
48445
+ fillAlpha: 0.5,
48446
+ fillAlphaInactive: 0.3,
48447
+ fillAlphaAutoGenerated: 0.3
48448
+ };
48449
+ function getDefaultContourConfig() {
48450
+ return defaultContourConfig$1;
48451
+ }
48452
+
48453
+ const defaultLabelmapConfig$1 = {
48454
+ renderOutline: true,
48455
+ outlineWidthActive: 3,
48456
+ outlineWidthInactive: 2,
48457
+ activeSegmentOutlineWidthDelta: 0,
48458
+ renderFill: true,
48459
+ renderFillInactive: true,
48460
+ fillAlpha: 0.7,
48461
+ fillAlphaInactive: 0.65,
48462
+ outlineOpacity: 1,
48463
+ outlineOpacityInactive: 0.85
48464
+ };
48465
+ function getDefaultLabelmapConfig() {
48466
+ return defaultLabelmapConfig$1;
48467
+ }
48468
+
48469
+ const defaultSurfaceConfig$1 = {
48470
+ renderFill: true,
48471
+ fillAlpha: 1
48472
+ };
48473
+ function getDefaultSurfaceConfig() {
48474
+ return defaultSurfaceConfig$1;
48475
+ }
48476
+
48477
+ const defaultLabelmapConfig = getDefaultLabelmapConfig();
48478
+ const defaultContourConfig = getDefaultContourConfig();
48479
+ const defaultSurfaceConfig = getDefaultSurfaceConfig();
48480
+ const newGlobalConfig = {
48481
+ renderInactiveSegmentations: true,
48482
+ representations: {
48483
+ [Representations.Labelmap]: defaultLabelmapConfig,
48484
+ [Representations.Contour]: defaultContourConfig,
48485
+ [Representations.Surface]: defaultSurfaceConfig
48486
+ }
48487
+ };
48488
+ const initialDefaultState = {
48489
+ colorLUT: [],
48490
+ segmentations: [],
48491
+ globalConfig: newGlobalConfig,
48492
+ toolGroups: {}
48493
+ };
48494
+ class SegmentationStateManager {
48495
+ constructor(uid) {
48496
+ if (!uid) {
48497
+ uid = uuidv4$1();
48498
+ }
48499
+ this.state = cloneDeep(initialDefaultState);
48500
+ this.uid = uid;
48501
+ }
48502
+ getState() {
48503
+ return this.state;
48504
+ }
48505
+ getToolGroups() {
48506
+ return Object.keys(this.state.toolGroups);
48507
+ }
48508
+ getColorLUT(lutIndex) {
48509
+ return this.state.colorLUT[lutIndex];
48510
+ }
48511
+ getNextColorLUTIndex() {
48512
+ return this.state.colorLUT.length;
48513
+ }
48514
+ resetState() {
48515
+ this.state = cloneDeep(initialDefaultState);
48516
+ }
48517
+ getSegmentation(segmentationId) {
48518
+ return this.state.segmentations.find(segmentation => segmentation.segmentationId === segmentationId);
48519
+ }
48520
+ addSegmentation(segmentation) {
48521
+ if (this.getSegmentation(segmentation.segmentationId)) {
48522
+ throw new Error(`Segmentation with id ${segmentation.segmentationId} already exists`);
48523
+ }
48524
+ this.state.segmentations.push(segmentation);
48525
+ }
48526
+ getSegmentationRepresentations(toolGroupId) {
48527
+ const toolGroupSegRepresentationsWithConfig = this.state.toolGroups[toolGroupId];
48528
+ if (!toolGroupSegRepresentationsWithConfig) {
48529
+ return;
48530
+ }
48531
+ return toolGroupSegRepresentationsWithConfig.segmentationRepresentations;
48532
+ }
48533
+ getAllSegmentationRepresentations() {
48534
+ const toolGroupSegReps = {};
48535
+ Object.entries(this.state.toolGroups).forEach(([toolGroupId, toolGroupSegRepresentationsWithConfig]) => {
48536
+ toolGroupSegReps[toolGroupId] = toolGroupSegRepresentationsWithConfig.segmentationRepresentations;
48537
+ });
48538
+ return toolGroupSegReps;
48539
+ }
48540
+ addSegmentationRepresentation(toolGroupId, segmentationRepresentation) {
48541
+ if (!this.state.toolGroups[toolGroupId]) {
48542
+ this.state.toolGroups[toolGroupId] = {
48543
+ segmentationRepresentations: [],
48544
+ config: {}
48545
+ };
48546
+ }
48547
+ this.state.toolGroups[toolGroupId].segmentationRepresentations.push(segmentationRepresentation);
48548
+ this._handleActiveSegmentation(toolGroupId, segmentationRepresentation);
48549
+ }
48550
+ getGlobalConfig() {
48551
+ return this.state.globalConfig;
48552
+ }
48553
+ setGlobalConfig(config) {
48554
+ this.state.globalConfig = config;
48555
+ }
48556
+ getSegmentationRepresentationByUID(toolGroupId, segmentationRepresentationUID) {
48557
+ const toolGroupSegRepresentations = this.getSegmentationRepresentations(toolGroupId);
48558
+ const segmentationData = toolGroupSegRepresentations?.find(representation => representation.segmentationRepresentationUID === segmentationRepresentationUID);
48559
+ return segmentationData;
48560
+ }
48561
+ removeSegmentation(segmentationId) {
48562
+ this.state.segmentations = this.state.segmentations.filter(segmentation => segmentation.segmentationId !== segmentationId);
48563
+ }
48564
+ removeSegmentationRepresentation(toolGroupId, segmentationRepresentationUID) {
48565
+ const toolGroupSegmentationRepresentations = this.getSegmentationRepresentations(toolGroupId);
48566
+ if (!toolGroupSegmentationRepresentations || !toolGroupSegmentationRepresentations.length) {
48567
+ throw new Error(`No viewport specific segmentation state found for viewport ${toolGroupId}`);
48568
+ }
48569
+ const state = toolGroupSegmentationRepresentations;
48570
+ const index = state.findIndex(segData => segData.segmentationRepresentationUID === segmentationRepresentationUID);
48571
+ if (index === -1) {
48572
+ console.warn(`No viewport specific segmentation state data found for viewport ${toolGroupId} and segmentation data UID ${segmentationRepresentationUID}`);
48573
+ }
48574
+ const removedSegmentationRepresentation = toolGroupSegmentationRepresentations[index];
48575
+ toolGroupSegmentationRepresentations.splice(index, 1);
48576
+ this._handleActiveSegmentation(toolGroupId, removedSegmentationRepresentation);
48577
+ }
48578
+ setActiveSegmentationRepresentation(toolGroupId, segmentationRepresentationUID) {
48579
+ const toolGroupSegmentations = this.getSegmentationRepresentations(toolGroupId);
48580
+ if (!toolGroupSegmentations || !toolGroupSegmentations.length) {
48581
+ throw new Error(`No segmentation data found for toolGroupId: ${toolGroupId}`);
48582
+ }
48583
+ const segmentationData = toolGroupSegmentations.find(segmentationData => segmentationData.segmentationRepresentationUID === segmentationRepresentationUID);
48584
+ if (!segmentationData) {
48585
+ throw new Error(`No segmentation data found for segmentation data UID ${segmentationRepresentationUID}`);
48586
+ }
48587
+ segmentationData.active = true;
48588
+ this._handleActiveSegmentation(toolGroupId, segmentationData);
48589
+ }
48590
+ getToolGroupSpecificConfig(toolGroupId) {
48591
+ const toolGroupStateWithConfig = this.state.toolGroups[toolGroupId];
48592
+ if (!toolGroupStateWithConfig) {
48593
+ return;
48594
+ }
48595
+ return toolGroupStateWithConfig.config;
48596
+ }
48597
+ getSegmentationRepresentationSpecificConfig(toolGroupId, segmentationRepresentationUID) {
48598
+ const segmentationRepresentation = this.getSegmentationRepresentationByUID(toolGroupId, segmentationRepresentationUID);
48599
+ if (!segmentationRepresentation) {
48600
+ return;
48601
+ }
48602
+ return segmentationRepresentation.segmentationRepresentationSpecificConfig;
48603
+ }
48604
+ setSegmentationRepresentationSpecificConfig(toolGroupId, segmentationRepresentationUID, config) {
48605
+ const segmentationRepresentation = this.getSegmentationRepresentationByUID(toolGroupId, segmentationRepresentationUID);
48606
+ if (!segmentationRepresentation) {
48607
+ return;
48608
+ }
48609
+ segmentationRepresentation.segmentationRepresentationSpecificConfig = config;
48610
+ }
48611
+ getSegmentSpecificConfig(toolGroupId, segmentationRepresentationUID, segmentIndex) {
48612
+ const segmentationRepresentation = this.getSegmentationRepresentationByUID(toolGroupId, segmentationRepresentationUID);
48613
+ if (!segmentationRepresentation) {
48614
+ return;
48615
+ }
48616
+ return segmentationRepresentation.segmentSpecificConfig[segmentIndex];
48617
+ }
48618
+ setSegmentSpecificConfig(toolGroupId, segmentationRepresentationUID, config, options) {
48619
+ const segmentationRepresentation = this.getSegmentationRepresentationByUID(toolGroupId, segmentationRepresentationUID);
48620
+ if (!segmentationRepresentation) {
48621
+ return;
48622
+ }
48623
+ if (!segmentationRepresentation.segmentSpecificConfig || options?.clear) {
48624
+ segmentationRepresentation.segmentSpecificConfig = {};
48625
+ }
48626
+ Object.keys(config).forEach(key => {
48627
+ segmentationRepresentation.segmentSpecificConfig[key] = config[key];
48628
+ });
48629
+ }
48630
+ setSegmentationRepresentationConfig(toolGroupId, config) {
48631
+ let toolGroupStateWithConfig = this.state.toolGroups[toolGroupId];
48632
+ if (!toolGroupStateWithConfig) {
48633
+ this.state.toolGroups[toolGroupId] = {
48634
+ segmentationRepresentations: [],
48635
+ config: {
48636
+ renderInactiveSegmentations: true,
48637
+ representations: {}
48638
+ }
48639
+ };
48640
+ toolGroupStateWithConfig = this.state.toolGroups[toolGroupId];
48641
+ }
48642
+ toolGroupStateWithConfig.config = {
48643
+ ...toolGroupStateWithConfig.config,
48644
+ ...config
48645
+ };
48646
+ }
48647
+ addColorLUT(colorLUT, lutIndex) {
48648
+ if (this.state.colorLUT[lutIndex]) {
48649
+ console.warn('Color LUT table already exists, overwriting');
48650
+ }
48651
+ this.state.colorLUT[lutIndex] = structuredClone(colorLUT);
48652
+ }
48653
+ removeColorLUT(colorLUTIndex) {
48654
+ delete this.state.colorLUT[colorLUTIndex];
48655
+ }
48656
+ _handleActiveSegmentation(toolGroupId, recentlyAddedOrRemovedSegmentationRepresentation) {
48657
+ const segmentationRepresentations = this.getSegmentationRepresentations(toolGroupId);
48658
+ if (segmentationRepresentations.length === 0) {
48659
+ return;
48660
+ }
48661
+ if (segmentationRepresentations.length === 1) {
48662
+ segmentationRepresentations[0].active = true;
48663
+ return;
48664
+ }
48665
+ const activeSegmentationRepresentations = segmentationRepresentations.filter(representation => representation.active);
48666
+ if (activeSegmentationRepresentations.length === 0) {
48667
+ segmentationRepresentations[0].active = true;
48668
+ return;
48669
+ }
48670
+ if (recentlyAddedOrRemovedSegmentationRepresentation.active) {
48671
+ segmentationRepresentations.forEach(representation => {
48672
+ if (representation.segmentationRepresentationUID !== recentlyAddedOrRemovedSegmentationRepresentation.segmentationRepresentationUID) {
48673
+ representation.active = false;
48674
+ }
48675
+ });
48676
+ }
48677
+ }
48678
+ }
48679
+ const defaultSegmentationStateManager = new SegmentationStateManager('DEFAULT');
48680
+
48681
+ function getDefaultSegmentationStateManager() {
48682
+ return defaultSegmentationStateManager;
48683
+ }
48684
+ function getSegmentation(segmentationId) {
48685
+ const segmentationStateManager = getDefaultSegmentationStateManager();
48686
+ return segmentationStateManager.getSegmentation(segmentationId);
48687
+ }
48688
+
48433
48689
  const {
48434
48690
  isEqual: isEqual$1
48435
48691
  } = utilities;
@@ -49370,6 +49626,7 @@ function updateContourPolyline(annotation, polylineData, transforms, options) {
49370
49626
  invalidateAnnotation(annotation);
49371
49627
  }
49372
49628
 
49629
+ const DEFAULT_CONTOUR_SEG_TOOLNAME = 'PlanarFreehandContourSegmentationTool';
49373
49630
  function getInterpolationData(viewportData, filterParams = []) {
49374
49631
  const {
49375
49632
  viewport,
@@ -49377,8 +49634,24 @@ function getInterpolationData(viewportData, filterParams = []) {
49377
49634
  annotation
49378
49635
  } = viewportData;
49379
49636
  const interpolationDatas = new Map();
49380
- const annotations = getAnnotations(annotation.metadata.toolName, viewport.element);
49381
- if (!annotations) {
49637
+ const {
49638
+ toolName,
49639
+ originalToolName
49640
+ } = annotation.metadata;
49641
+ const testToolName = originalToolName || toolName;
49642
+ const annotations = getAnnotations(testToolName, viewport.element) || [];
49643
+ const modifiedAnnotations = getAnnotations(DEFAULT_CONTOUR_SEG_TOOLNAME, viewport.element);
49644
+ if (modifiedAnnotations?.length) {
49645
+ modifiedAnnotations.forEach(annotation => {
49646
+ const {
49647
+ metadata
49648
+ } = annotation;
49649
+ if (metadata.originalToolName === testToolName && !annotations.find(it => it === annotation)) {
49650
+ annotations.push(annotation);
49651
+ }
49652
+ });
49653
+ }
49654
+ if (!annotations?.length) {
49382
49655
  return interpolationDatas;
49383
49656
  }
49384
49657
  for (let i = 0; i < sliceData.numberOfSlices; i++) {
@@ -49557,7 +49830,7 @@ function _getBoundingPair(sliceIndex, sliceRange, interpolationData) {
49557
49830
  const {
49558
49831
  PointsManager: PointsManager$1
49559
49832
  } = utilities;
49560
- function selectHandles(polyline, handleCount = 8) {
49833
+ function selectHandles(polyline, handleCount = 12) {
49561
49834
  const handles = PointsManager$1.create3(handleCount);
49562
49835
  handles.sources = [];
49563
49836
  const {
@@ -49569,10 +49842,9 @@ function selectHandles(polyline, handleCount = 8) {
49569
49842
  } = polyline;
49570
49843
  const distance = 6;
49571
49844
  if (length < distance * 3) {
49572
- console.log('Adding subselect handles', handleCount, length);
49573
49845
  return polyline.subselect(handleCount);
49574
49846
  }
49575
- const interval = Math.min(30, Math.floor(length / 3));
49847
+ const interval = Math.floor(Math.max(2 * length / handleCount, distance * 5));
49576
49848
  sourcePoints.forEach(() => destPoints.push(PointsManager$1.create3(handleCount)));
49577
49849
  const dotValues = createDotValues(polyline, distance);
49578
49850
  const minimumRegions = findMinimumRegions(dotValues, handleCount);
@@ -49731,12 +50003,10 @@ const {
49731
50003
  PointsManager
49732
50004
  } = utilities;
49733
50005
  const dP = 0.2;
49734
- let interpolating = false;
49735
50006
  function interpolate(viewportData) {
49736
- if (interpolating || !viewportData.annotation) {
50007
+ if (!viewportData.annotation) {
49737
50008
  return;
49738
50009
  }
49739
- interpolating = true;
49740
50010
  const {
49741
50011
  isInterpolationUpdate,
49742
50012
  annotation
@@ -49749,7 +50019,6 @@ function interpolate(viewportData) {
49749
50019
  }
49750
50020
  startInterpolation(viewportData);
49751
50021
  } finally {
49752
- interpolating = false;
49753
50022
  if (isInterpolationUpdate) {
49754
50023
  annotation.autoGenerated = true;
49755
50024
  }
@@ -50117,6 +50386,31 @@ function deleteRelatedAnnotations(viewportData) {
50117
50386
  }
50118
50387
  }
50119
50388
 
50389
+ function addContourSegmentationAnnotation(annotation) {
50390
+ if (!annotation.data.segmentation) {
50391
+ throw new Error('addContourSegmentationAnnotation: annotation does not have a segmentation data');
50392
+ }
50393
+ const {
50394
+ segmentationId,
50395
+ segmentIndex
50396
+ } = annotation.data.segmentation;
50397
+ const segmentation = getSegmentation(segmentationId);
50398
+ if (!segmentation.representationData.CONTOUR) {
50399
+ segmentation.representationData.CONTOUR = {
50400
+ annotationUIDsMap: new Map()
50401
+ };
50402
+ }
50403
+ const {
50404
+ annotationUIDsMap
50405
+ } = segmentation.representationData.CONTOUR;
50406
+ let annotationsUIDsSet = annotationUIDsMap.get(segmentIndex);
50407
+ if (!annotationsUIDsSet) {
50408
+ annotationsUIDsSet = new Set();
50409
+ annotationUIDsMap.set(segmentIndex, annotationsUIDsSet);
50410
+ }
50411
+ annotationUIDsMap.set(segmentIndex, annotationsUIDsSet.add(annotation.annotationUID));
50412
+ }
50413
+
50120
50414
  const {
50121
50415
  uuidv4
50122
50416
  } = utilities;
@@ -50144,10 +50438,14 @@ class InterpolationManager {
50144
50438
  }
50145
50439
  for (const annotation of annotations) {
50146
50440
  const {
50441
+ interpolationUID,
50147
50442
  data,
50148
50443
  autoGenerated,
50149
50444
  metadata
50150
50445
  } = annotation;
50446
+ if (interpolationUID) {
50447
+ annotation.interpolationCompleted = true;
50448
+ }
50151
50449
  if (!autoGenerated) {
50152
50450
  continue;
50153
50451
  }
@@ -50160,6 +50458,7 @@ class InterpolationManager {
50160
50458
  if (segmentationId && segmentationId !== data.segmentation.segmentationId) {
50161
50459
  continue;
50162
50460
  }
50461
+ addContourSegmentationAnnotation(annotation);
50163
50462
  annotation.autoGenerated = false;
50164
50463
  }
50165
50464
  }
@@ -50171,11 +50470,13 @@ class InterpolationManager {
50171
50470
  return;
50172
50471
  }
50173
50472
  const {
50174
- toolName
50473
+ toolName,
50474
+ originalToolName
50175
50475
  } = annotation.metadata;
50176
- if (!this.toolNames.includes(toolName)) {
50476
+ if (!this.toolNames.includes(toolName) && !this.toolNames.includes(originalToolName)) {
50177
50477
  return;
50178
50478
  }
50479
+ console.log('Interpolation annotation', annotation.annotationUID);
50179
50480
  const viewport = getViewportForAnnotation(annotation);
50180
50481
  if (!viewport) {
50181
50482
  console.warn('Unable to find viewport for', annotation);
@@ -50209,11 +50510,21 @@ class InterpolationManager {
50209
50510
  parentKey: annotation => annotation.metadata
50210
50511
  }];
50211
50512
  let interpolationAnnotations = getInterpolationDataCollection(viewportData, filterData);
50212
- interpolationAnnotations = interpolationAnnotations.filter(interpolationAnnotation => interpolationAnnotation.interpolationUID);
50213
- if (!annotation.interpolationUID) {
50214
- annotation.interpolationUID = interpolationAnnotations[0]?.interpolationUID || uuidv4();
50215
- viewportData.interpolationUID = annotation.interpolationUID;
50216
- }
50513
+ const {
50514
+ sliceIndex
50515
+ } = annotation.metadata;
50516
+ const skipUIDs = new Set();
50517
+ interpolationAnnotations.forEach(interpolationAnnotation => {
50518
+ if (interpolationAnnotation.interpolationCompleted || interpolationAnnotation.metadata.sliceIndex === sliceIndex) {
50519
+ const {
50520
+ interpolationUID
50521
+ } = interpolationAnnotation;
50522
+ skipUIDs.add(interpolationUID);
50523
+ }
50524
+ });
50525
+ interpolationAnnotations = interpolationAnnotations.filter(interpolationAnnotation => !skipUIDs.has(interpolationAnnotation.interpolationUID));
50526
+ annotation.interpolationUID = interpolationAnnotations[0]?.interpolationUID || uuidv4();
50527
+ viewportData.interpolationUID = annotation.interpolationUID;
50217
50528
  interpolate(viewportData);
50218
50529
  };
50219
50530
  }
@@ -50227,9 +50538,10 @@ class InterpolationManager {
50227
50538
  return;
50228
50539
  }
50229
50540
  const {
50230
- toolName
50541
+ toolName,
50542
+ originalToolName
50231
50543
  } = annotation.metadata;
50232
- if (!this.toolNames.includes(toolName) || !ChangeTypesForInterpolation.includes(changeType)) {
50544
+ if (!this.toolNames.includes(toolName) && !this.toolNames.includes(originalToolName) || !ChangeTypesForInterpolation.includes(changeType)) {
50233
50545
  return;
50234
50546
  }
50235
50547
  const viewport = getViewportForAnnotation(annotation);
@@ -50237,7 +50549,10 @@ class InterpolationManager {
50237
50549
  console.warn('Unable to find matching viewport for annotation interpolation', annotation);
50238
50550
  return;
50239
50551
  }
50240
- annotation.autoGenerated = false;
50552
+ if (annotation.autoGenerated) {
50553
+ addContourSegmentationAnnotation(annotation);
50554
+ annotation.autoGenerated = false;
50555
+ }
50241
50556
  const sliceData = getSliceData(viewport);
50242
50557
  const viewportData = {
50243
50558
  viewport,