All files / packages/tools/src/tools/segmentation/strategies/compositions determineSegmentIndex.ts

11.11% Statements 3/27
6.25% Branches 1/16
33.33% Functions 1/3
11.11% Lines 3/27

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                                            1x 1x 1x                                                                                                                            
import type { InitializedOperationData } from '../BrushStrategy';
import pointInShapeCallback from '../../../../utilities/pointInShapeCallback';
import StrategyCallbacks from '../../../../enums/StrategyCallbacks';
 
/**
 * This function determines whether to fill or erase based on what the user
 * initially clicks on.  The behaviour is:
 * 1. If the user clicks on an area that has no active segment index in it,
 *    then assume the user using the active segment index for filling
 * 2. Find the segment index of the pixel the user clicked on, and assume they
 *    want to fill with that segment index.  Use the given segment index for
 *    the fill colour.
 *    a. If the user clicks on the active segment index, then they will fill
 *       with the active segment
 *    b. If the user clicks on the 0 segment index, they will clear the segment
 *       index, erasing the segment.
 *    c. If the user clicks on another segment index, they will "restore" that
 *       segment index, so that they can push back the segment area.
 *
 */
export default {
  [StrategyCallbacks.Initialize]: (operationData: InitializedOperationData) => {
    const { strategySpecificConfiguration } = operationData;
    Eif (!strategySpecificConfiguration) {
      return;
    }
    const { centerSegmentIndex } = strategySpecificConfiguration;
    if (centerSegmentIndex) {
      operationData.segmentIndex = centerSegmentIndex.segmentIndex;
    }
  },
 
  [StrategyCallbacks.OnInteractionStart]: (
    operationData: InitializedOperationData
  ) => {
    const {
      segmentIndex,
      previewSegmentIndex,
      segmentationVoxelManager: segmentationVoxelManager,
      centerIJK,
      strategySpecificConfiguration,
      imageVoxelManager: imageVoxelManager,
      segmentationImageData,
      preview,
    } = operationData;
    if (!strategySpecificConfiguration?.useCenterSegmentIndex) {
      return;
    }
    // Get rid of the previous data
    delete strategySpecificConfiguration.centerSegmentIndex;
 
    let hasSegmentIndex = false;
    let hasPreviewIndex = false;
    const callback = ({ value }) => {
      hasSegmentIndex ||= value === segmentIndex;
      hasPreviewIndex ||= value === previewSegmentIndex;
    };
 
    pointInShapeCallback(
      segmentationImageData as unknown,
      imageVoxelManager.isInObject,
      callback,
      segmentationVoxelManager.boundsIJK
    );
 
    if (!hasSegmentIndex && !hasPreviewIndex) {
      return;
    }
 
    let existingValue = segmentationVoxelManager.getAtIJKPoint(centerIJK);
    if (existingValue === previewSegmentIndex) {
      if (preview) {
        existingValue = preview.segmentIndex;
      } else {
        return;
      }
    } else if (hasPreviewIndex) {
      // Clear the preview area
      existingValue = null;
    }
    operationData.segmentIndex = existingValue;
    strategySpecificConfiguration.centerSegmentIndex = {
      segmentIndex: existingValue,
    };
  },
};