All files / packages/tools/src/utilities/segmentation createLabelmapVolumeForViewport.ts

76.47% Statements 13/17
60% Branches 6/10
100% Functions 1/1
76.47% Lines 13/17

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                                                                          7x 7x 7x   7x       7x 7x       7x   7x   7x         7x             7x 7x         7x    
import cloneDeep from 'lodash.clonedeep';
import {
  getEnabledElementByIds,
  volumeLoader,
  VolumeViewport,
  utilities as csUtils,
} from '@cornerstonejs/core';
import type { Types } from '@cornerstonejs/core';
 
/**
 * Create a new 3D segmentation volume from the default imageData presented in
 * the first actor of the viewport. It looks at the metadata of the imageData
 * to determine the volume dimensions and spacing if particular options are not provided.
 *
 * @param viewportId - The Id of the viewport from which to derive the volume from.
 * @param renderingEngineId - The Id of the rendering engine the viewport belongs to.
 * @param [segmentationId] - The Id to name the generated segmentation. Autogenerated if not given.
 * @param [options] - LabelmapOptions
 * @returns A promise that resolves to the Id of the new labelmap volume.
 */
export default async function createLabelmapVolumeForViewport(input: {
  viewportId: string;
  renderingEngineId: string;
  segmentationId?: string;
  options?: {
    volumeId: string;
    scalarData: Float32Array | Uint8Array | Uint16Array | Int16Array;
    targetBuffer: {
      type: 'Float32Array' | 'Uint8Array' | 'Uint16Array' | 'Int8Array';
    };
    metadata: Types.Metadata;
    dimensions: Types.Point3;
    spacing: Types.Point3;
    origin: Types.Point3;
    direction: Types.Mat3;
  };
}): Promise<string> {
  const { viewportId, renderingEngineId, options } = input;
  let { segmentationId } = input;
  const enabledElement = getEnabledElementByIds(viewportId, renderingEngineId);
 
  Iif (!enabledElement) {
    throw new Error('element disabled');
  }
 
  const { viewport } = enabledElement;
  Iif (!(viewport instanceof VolumeViewport)) {
    throw new Error('Segmentation only supports VolumeViewport');
  }
 
  const { uid } = viewport.getDefaultActor();
 
  Eif (segmentationId === undefined) {
    // Name the segmentation volume with the viewport Id
    segmentationId = `${uid}-based-segmentation-${
      options?.volumeId ?? csUtils.uuidv4().slice(0, 8)
    }`;
  }
 
  Iif (options) {
    // create a new labelmap with its own properties
    // This allows creation of a higher resolution labelmap vs reference volume
    const properties = cloneDeep(options);
    await volumeLoader.createLocalVolume(properties, segmentationId);
  } else {
    // create a labelmap from a reference volume
    const { uid: volumeId } = viewport.getDefaultActor();
    await volumeLoader.createAndCacheDerivedSegmentationVolume(volumeId, {
      volumeId: segmentationId,
    });
  }
 
  return segmentationId;
}