All files / packages/tools/src/stateManagement/segmentation addSegmentationRepresentation.ts

86.95% Statements 20/23
78.57% Branches 11/14
66.66% Functions 2/3
86.95% Lines 20/23

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109                                                    20x     20x         20x   20x   20x                           20x         2x   2x         2x                 20x         20x 3x               20x       20x     20x     20x 20x     20x 20x   20x        
import { getRenderingEngine, utilities } from '@cornerstonejs/core';
import type { Types } from '@cornerstonejs/core';
import {
  SegmentationRepresentationConfig,
  RepresentationPublicInput,
  ToolGroupSpecificRepresentation,
  RepresentationPublicInputOptions,
} from '../../types/SegmentationStateTypes';
import * as SegmentationConfig from './config/segmentationConfig';
import {
  addSegmentationRepresentation as addSegmentationRepresentationToState,
  getNextColorLUTIndex,
  addColorLUT,
} from './segmentationState';
import { getRepresentationSpecificConfig } from './helpers/getRepresentationSpecificConfig';
import CORNERSTONE_COLOR_LUT from '../../constants/COLOR_LUT';
import { getToolGroup } from '../../store/ToolGroupManager';
import { triggerAnnotationRenderForViewportIds } from '../../utilities';
import { SegmentationRepresentations } from '../../enums';
 
async function addSegmentationRepresentation(
  toolGroupId: string,
  representationInput: RepresentationPublicInput,
  toolGroupSpecificConfig?: SegmentationRepresentationConfig
): Promise<string> {
  const { segmentationId, options = {} as RepresentationPublicInputOptions } =
    representationInput;
 
  const segmentationRepresentationUID =
    representationInput.options?.segmentationRepresentationUID ||
    utilities.uuidv4();
 
  // Todo: make segmentsHidden also an option that can get passed by
  // the user
  const segmentsHidden = new Set() as Set<number>;
 
  const colorLUTIndexToUse = getColorLUTIndex(options);
 
  const toolGroupSpecificRepresentation: ToolGroupSpecificRepresentation = {
    segmentationId,
    segmentationRepresentationUID,
    type: representationInput.type,
    segmentsHidden,
    colorLUTIndex: colorLUTIndexToUse,
    active: true,
    segmentationRepresentationSpecificConfig: {},
    segmentSpecificConfig: {},
    config: getRepresentationSpecificConfig(representationInput),
    polySeg: options.polySeg,
  };
 
  // Update the toolGroup specific configuration
  if (toolGroupSpecificConfig) {
    // Since setting configuration on toolGroup will trigger a segmentationRepresentation
    // update event, we don't want to trigger the event twice, so we suppress
    // the first one
    const currentToolGroupConfig =
      SegmentationConfig.getToolGroupSpecificConfig(toolGroupId);
 
    const mergedConfig = utilities.deepMerge(
      currentToolGroupConfig,
      toolGroupSpecificConfig
    );
 
    SegmentationConfig.setToolGroupSpecificConfig(toolGroupId, {
      renderInactiveSegmentations:
        mergedConfig.renderInactiveSegmentations || true,
      representations: {
        ...mergedConfig.representations,
      },
    });
  }
 
  addSegmentationRepresentationToState(
    toolGroupId,
    toolGroupSpecificRepresentation
  );
 
  if (representationInput.type === SegmentationRepresentations.Contour) {
    getToolGroup(toolGroupId)
      .getViewportsInfo()
      .forEach(({ viewportId, renderingEngineId }) => {
        const renderingEngine = getRenderingEngine(renderingEngineId);
        triggerAnnotationRenderForViewportIds(renderingEngine, [viewportId]);
      });
  }
 
  return segmentationRepresentationUID;
}
 
function getColorLUTIndex(options = {} as RepresentationPublicInputOptions) {
  const colorLUTOrIndexInput = options.colorLUTOrIndex;
  let colorLUTIndexToUse;
 
  Iif (typeof colorLUTOrIndexInput === 'number') {
    colorLUTIndexToUse = colorLUTOrIndexInput;
  } else {
    const nextIndex = getNextColorLUTIndex();
    const colorLUTToAdd = Array.isArray(colorLUTOrIndexInput)
      ? colorLUTOrIndexInput
      : CORNERSTONE_COLOR_LUT;
    addColorLUT(colorLUTToAdd as Types.ColorLUT, nextIndex);
    colorLUTIndexToUse = nextIndex;
  }
  return colorLUTIndexToUse;
}
 
export { addSegmentationRepresentation };