Skip to content

copper3d / Modules / Utils/segmentation/core/MaskVolume / MaskVolume

Class: MaskVolume ​

Utils/segmentation/core/MaskVolume.MaskVolume

Table of contents ​

Constructors ​

Properties ​

Methods ​

Constructors ​

constructor ​

• new MaskVolume(width, height, depth, channels?, customColorMap?)

Create a new MaskVolume.

All voxels are initialised to 0.

Parameters ​

NameTypeDefault valueDescription
widthnumberundefinedNumber of voxels along the X axis (≥ 1).
heightnumberundefinedNumber of voxels along the Y axis (≥ 1).
depthnumberundefinedNumber of voxels along the Z axis (≥ 1).
channelsnumber1Number of channels per voxel (default 1).
customColorMap?ChannelColorMapundefinedOptional color map to override defaults.

Throws

If any dimension or the channel count is < 1.

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:90

Properties ​

bytesPerSlice ​

• Private Readonly bytesPerSlice: number

Number of bytes in one complete z-slice. Equal to width × height × channels.

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:58


colorMap ​

• Private colorMap: ChannelColorMap

Per-channel color map used for colored rendering modes.

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:61


data ​

• Private data: Uint8Array

Contiguous backing buffer — layout [z][y][x][channel].

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:46


dims ​

• Private Readonly dims: Dimensions

Volume size in voxels.

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:49


numChannels ​

• Private Readonly numChannels: number

Number of value channels per voxel (≥ 1).

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:52


version ​

• Private version: number = 0

Monotonic data-mutation counter.

Incremented by every method that mutates voxel data (not color). Consumers (e.g. the contour cache in RenderingUtils) key cached derivations on this value so an edit automatically invalidates them — it is impossible to forget an invalidation point because every write bumps the version. Color-map changes do not bump it (colors are applied at fill time, never cached).

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:73

Methods ​

buildRgbToChannelMap ​

▸ Private buildRgbToChannelMap(): Map<number, number>

Build a Map from RGB packed integer to channel label for reverse lookup. Covers every label this instance has a colour for, skipping 0 (transparent).

Instance method ensures custom per-layer colors are correctly reverse-mapped.

Returns ​

Map<number, number>

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:646


clear ​

▸ clear(): void

Zero every voxel in the entire volume (all channels).

Returns ​

void

Example

ts
vol.clear();
vol.getVoxel(256, 256, 50); // 0
vol.clear();
vol.getVoxel(256, 256, 50); // 0

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:895


clearChannel ​

▸ clearChannel(channel): void

Zero every voxel carrying one label, leaving every other label in place.

The third member of the clear family: clear() takes the whole volume and clearSlice() takes one slice, both regardless of label. Deleting a single annotation needs neither — its mask is one label inside a volume it shares with every other annotation on that layer, so anything coarser takes the neighbours with it.

Label-based volumes only, which is what numChannels === 1 means here: the voxel value IS the label. A multi-plane volume stores channels as separate planes and would need a different sweep.

The version is bumped only when a voxel actually changed. Every derived cache keyed on it — the contour cache above all — is invalidated by a bump, so bumping for a clear that found nothing would redraw the layer for no reason.

Parameters ​

NameTypeDescription
channelnumberLabel to erase, 1-255. Zero is "empty", not a channel.

Returns ​

void

Throws

If channel is outside [1, 255].

Example

ts
vol.clearChannel(3); // finding 3's voxels go; 1, 2 and 4 stay
vol.clearChannel(3); // finding 3's voxels go; 1, 2 and 4 stay

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:925


clearSlice ​

▸ clearSlice(sliceIndex, axis?, channel?): void

Zero every voxel in a single slice along the given axis.

If channel is provided, only that channel is cleared; otherwise all channels in the slice are cleared.

Parameters ​

NameTypeDefault valueDescription
sliceIndexnumberundefinedIndex along the specified axis.
axis"x" | "y" | "z"'z''x', 'y', or 'z' (default 'z').
channel?numberundefinedOptional channel to clear (default: all).

Returns ​

void

Throws

If sliceIndex is out of bounds.

Example

ts
// Erase a single axial slice
vol.clearSlice(50, 'z');

// Erase only channel 1 of slice 50
vol.clearSlice(50, 'z', 1);
// Erase a single axial slice
vol.clearSlice(50, 'z');

// Erase only channel 1 of slice 50
vol.clearSlice(50, 'z', 1);

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:996


clone ​

▸ clone(): MaskVolume

Create an independent deep copy of this volume.

The clone has the same dimensions, channels, data, and color map but shares no references with the original.

Returns ​

MaskVolume

A new MaskVolume with identical content.

Example

ts
// Undo support: snapshot before an operation
const snapshot = vol.clone();
performEdit(vol);
// Rollback: vol.setRawData(snapshot.getRawData());
// Undo support: snapshot before an operation
const snapshot = vol.clone();
performEdit(vol);
// Rollback: vol.setRawData(snapshot.getRawData());

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:869


getBytesPerSlice ​

▸ getBytesPerSlice(): number

Return the number of bytes in one complete z-slice.

Equal to width × height × channels. Useful for direct buffer index arithmetic in performance-critical code paths.

Returns ​

number

Bytes per z-slice.

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:787


getChannelColor ​

▸ getChannelColor(channel): RGBAColor

Get the current color for a channel.

Falls back to the background color (transparent) if no color is defined.

Parameters ​

NameTypeDescription
channelnumberChannel index.

Returns ​

RGBAColor

A copy of the RGBA color.

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:246


getChannels ​

▸ getChannels(): number

Return the number of channels per voxel.

Returns ​

number

Channel count (≥ 1).

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:775


getColorMap ​

▸ getColorMap(): ChannelColorMap

Get a shallow copy of the entire color map.

Returns ​

ChannelColorMap

A copy of the color map (safe to mutate).

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:274


getDimensions ​

▸ getDimensions(): Dimensions

Return a copy of the volume dimensions.

Returns ​

Dimensions

{ width, height, depth } — a fresh object (safe to mutate).

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:766


getIndex ​

▸ Private getIndex(x, y, z, channel?): number

Map 3D coordinates + channel to a flat 1D index.

Memory layout (slice-major):

index = (z × height × width × channels)
      + (y × width × channels)
      + (x × channels)
      + channel
index = (z × height × width × channels)
      + (y × width × channels)
      + (x × channels)
      + channel

Parameters ​

NameTypeDefault valueDescription
xnumberundefinedVoxel column (0 … width − 1).
ynumberundefinedVoxel row (0 … height − 1).
znumberundefinedSlice index (0 … depth − 1).
channelnumber0Channel index (0 … channels − 1).

Returns ​

number

Flat 1D index into this.data.

Throws

If any coordinate or channel is out of bounds.

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:150


getMemoryUsage ​

▸ getMemoryUsage(): number

Return total memory used by the backing buffer, in bytes.

Returns ​

number

width × height × depth × channels bytes.

Example

ts
const vol = new MaskVolume(512, 512, 100);
vol.getMemoryUsage(); // 26_214_400 (~25 MB)
const vol = new MaskVolume(512, 512, 100);
vol.getMemoryUsage(); // 26_214_400 (~25 MB)

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:802


getRawData ​

▸ getRawData(): Uint8Array

Return a reference to the raw backing buffer.

Use this for direct read access (e.g. serialisation, GPU upload). Mutating the returned array mutates the volume.

Returns ​

Uint8Array

The underlying Uint8Array.

Example

ts
// Serialise for network transfer
const bytes = vol.getRawData();
socket.send(bytes.buffer);
// Serialise for network transfer
const bytes = vol.getRawData();
socket.send(bytes.buffer);

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:823


getSliceDimensions ​

▸ Private getSliceDimensions(axis): [number, number]

Get the 2D slice dimensions for a given axis.

Parameters ​

NameType
axis"x" | "y" | "z"

Returns ​

[number, number]

[width, height] of the slice.

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:1168


getSliceImageData ​

▸ getSliceImageData(sliceIndex, axis?, options?): ImageData

Extract a 2D slice as an ImageData with color mapping.

Slice dimensions depend on the axis:

AxisPlaneWidthHeight
zAxialwidthheight
yCoronalwidthdepth
xSagittalheightdepth

Parameters ​

NameTypeDefault valueDescription
sliceIndexnumberundefinedIndex along the specified axis.
axis"x" | "y" | "z"'z''x' (sagittal), 'y' (coronal), or 'z' (axial).
optionsSliceRenderOptions{}Rendering options (mode, channel, colors, etc.).

Returns ​

ImageData

ImageData ready for ctx.putImageData().

Throws

If sliceIndex is out of bounds for the given axis.

Example

ts
// Grayscale (default, backward compatible)
const gs = vol.getSliceImageData(50, 'z');

// Colored single-channel
const cs = vol.getSliceImageData(50, 'z', {
  mode: RenderMode.COLORED_SINGLE,
  channel: 0,
});

// Multi-channel priority
const mc = vol.getSliceImageData(50, 'z', {
  mode: RenderMode.COLORED_MULTI,
  visibleChannels: [false, true, true, true],
});
// Grayscale (default, backward compatible)
const gs = vol.getSliceImageData(50, 'z');

// Colored single-channel
const cs = vol.getSliceImageData(50, 'z', {
  mode: RenderMode.COLORED_SINGLE,
  channel: 0,
});

// Multi-channel priority
const mc = vol.getSliceImageData(50, 'z', {
  mode: RenderMode.COLORED_MULTI,
  visibleChannels: [false, true, true, true],
});

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:322


getSliceUint8 ​

▸ getSliceUint8(sliceIndex, axis?): Object

Extract a 2D slice as a flat Uint8Array (one byte per voxel per channel).

For a 1-channel volume the result is sliceWidth × sliceHeight bytes, each byte being the label value at that pixel. This is suitable for sending to a backend that expects raw label data (e.g. NIfTI slice replacement).

Parameters ​

NameTypeDefault valueDescription
sliceIndexnumberundefinedIndex along the specified axis.
axis"x" | "y" | "z"'z''x', 'y', or 'z' (default 'z').

Returns ​

Object

A copy of the slice data plus its dimensions.

NameType
dataUint8Array
heightnumber
widthnumber

Throws

If sliceIndex is out of bounds.

Example

ts
const { data, width, height } = vol.getSliceUint8(50, 'z');
// data.length === width * height * channels
const { data, width, height } = vol.getSliceUint8(50, 'z');
// data.length === width * height * channels

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:1068


getVersion ​

▸ getVersion(): number

Return the current data-mutation version.

Increments on every voxel write. Use as a cache key so derived data (e.g. extracted contours) is invalidated whenever the volume changes.

Returns ​

number

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:212


getVoxel ​

▸ getVoxel(x, y, z, channel?): number

Read a single voxel value.

Parameters ​

NameTypeDefault valueDescription
xnumberundefinedVoxel column (0 … width − 1).
ynumberundefinedVoxel row (0 … height − 1).
znumberundefinedSlice index (0 … depth − 1).
channelnumber0Channel index (default 0).

Returns ​

number

The stored value (0 – 255).

Throws

If any coordinate is out of bounds.

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:184


hasData ​

▸ hasData(): boolean

Check if the volume contains any non-zero voxel data.

Returns true if at least one voxel has a non-zero value, false if all voxels are zero (empty mask).

This is useful for determining if a layer has actual mask annotations before saving or exporting.

Returns ​

boolean

True if any voxel is non-zero, false if all zeros.

Example

ts
const vol = new MaskVolume(512, 512, 100);
vol.hasData(); // false (all zeros)

vol.setVoxel(256, 256, 50, 255);
vol.hasData(); // true
const vol = new MaskVolume(512, 512, 100);
vol.hasData(); // false (all zeros)

vol.setVoxel(256, 256, 50, 255);
vol.hasData(); // true

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:966


renderBlended ​

▸ Private renderBlended(pixels, width, height, sliceIndex, axis, colorMap, visibleChannels, opacity): void

Render all visible channels with additive blending.

Each channel contributes its color weighted by intensity × opacity. RGB values are clamped to 255.

Parameters ​

NameType
pixelsUint8ClampedArray
widthnumber
heightnumber
sliceIndexnumber
axis"x" | "y" | "z"
colorMapChannelColorMap
visibleChannelsboolean[]
opacitynumber

Returns ​

void

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:1393


renderColoredMulti ​

▸ Private renderColoredMulti(pixels, width, height, sliceIndex, axis, colorMap, visibleChannels, opacity): void

Render all visible channels with distinct colors.

The highest-index non-zero visible channel wins (priority-based).

Parameters ​

NameType
pixelsUint8ClampedArray
widthnumber
heightnumber
sliceIndexnumber
axis"x" | "y" | "z"
colorMapChannelColorMap
visibleChannelsboolean[]
opacitynumber

Returns ​

void

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:1319


renderColoredSingle ​

▸ Private renderColoredSingle(pixels, width, height, sliceIndex, axis, channel, colorMap, opacity): void

Render a single channel with its predefined color.

Alpha is modulated by the voxel intensity and the opacity multiplier.

Parameters ​

NameType
pixelsUint8ClampedArray
widthnumber
heightnumber
sliceIndexnumber
axis"x" | "y" | "z"
channelnumber
colorMapChannelColorMap
opacitynumber

Returns ​

void

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:1258


renderGrayscale ​

▸ Private renderGrayscale(pixels, width, height, sliceIndex, axis, channel): void

Render a single channel as grayscale (original behaviour).

Non-zero voxels are fully opaque (A = 255), zero voxels are transparent (A = 0).

Parameters ​

NameType
pixelsUint8ClampedArray
widthnumber
heightnumber
sliceIndexnumber
axis"x" | "y" | "z"
channelnumber

Returns ​

void

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:1205


renderLabelSliceInto ​

▸ renderLabelSliceInto(sliceIndex, axis?, target, channelVisible?, opacity?): void

Render a 1-channel label slice into a pre-allocated RGBA ImageData buffer.

Each voxel stores a label value (0-8). Label 0 = transparent. Labels 1-8 are mapped to colors via MASK_CHANNEL_COLORS, filtered by the channelVisible array.

Parameters ​

NameTypeDefault valueDescription
sliceIndexnumberundefinedIndex along the specified axis.
axis"x" | "y" | "z"'z''x', 'y', or 'z'.
targetImageDataundefinedPre-allocated ImageData buffer (must match slice dimensions).
channelVisible?Record<number, boolean>undefinedArray where index N indicates if channel N is visible. If undefined, all channels are visible.
opacitynumber1.0Opacity multiplier 0.0–1.0 (default 1.0).

Returns ​

void

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:679


resetChannelColors ​

▸ resetChannelColors(channel?): void

Reset the color map for one or all labels to defaults.

Parameters ​

NameTypeDescription
channel?numberOptional specific label to reset. If omitted, resets all.

Returns ​

void

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:256


setChannelColor ​

▸ setChannelColor(channel, color): void

Update the color for a specific label/channel in the color map.

For label-based volumes (1-channel), the channel parameter refers to the label value, not the storage channel index.

Parameters ​

NameTypeDescription
channelnumberLabel/channel index to update (0-MAX_ENGINE_CHANNEL).
colorRGBAColorNew RGBA color.

Returns ​

void

Throws

If channel is outside the storable label range.

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:229


setRawData ​

▸ setRawData(newData): void

Replace the entire backing buffer.

The provided array must have exactly the same length as the current buffer (width × height × depth × channels).

Parameters ​

NameTypeDescription
newDataUint8ArrayReplacement data.

Returns ​

void

Throws

If the length does not match.

Example

ts
// Restore from a saved snapshot
const saved = new Uint8Array(savedBuffer);
vol.setRawData(saved);
// Restore from a saved snapshot
const saved = new Uint8Array(savedBuffer);
vol.setRawData(saved);

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:843


setSliceFromImageData ​

▸ setSliceFromImageData(sliceIndex, imageData, axis?, channel?): void

Write a 2D ImageData back into the volume for the given axis/slice.

When the volume has 4 channels, all RGBA components are stored (ch0=R, ch1=G, ch2=B, ch3=A) for lossless round-trip. Otherwise, the R channel of each pixel is used as grayscale.

Parameters ​

NameTypeDefault valueDescription
sliceIndexnumberundefinedIndex along the specified axis.
imageDataImageDataundefinedSource ImageData (expected dimensions must match the axis).
axis"x" | "y" | "z"'z''x', 'y', or 'z' (default 'z').
channelnumber0Target channel (default 0, ignored when numChannels >= 4).

Returns ​

void

Throws

If sliceIndex is out of bounds.

Throws

If imageData dimensions don't match.

Example

ts
const imgData = ctx.getImageData(0, 0, 512, 512);
vol.setSliceFromImageData(50, imgData, 'z');
const imgData = ctx.getImageData(0, 0, 512, 512);
vol.setSliceFromImageData(50, imgData, 'z');

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:386


setSliceLabelsFromImageData ​

▸ setSliceLabelsFromImageData(sliceIndex, imageData, axis?, activeChannel?, channelVisible?): void

/**

  • Store label data from canvas RGBA ImageData into a 1-channel volume.
  • For each pixel: matches the RGB color against MASK_CHANNEL_COLORS to
  • determine which channel label to store. If no match is found, falls
  • back to activeChannel. Transparent pixels (alpha === 0) are stored as 0.
  • This is the write counterpart to renderLabelSliceInto.

Parameters ​

NameTypeDefault valueDescription
sliceIndexnumberundefinedIndex along the specified axis. *
imageDataImageDataundefinedCanvas ImageData (RGBA) to convert. *
axis"x" | "y" | "z"'z''x', 'y', or 'z'. *
activeChannelnumber1Fallback label for pixels whose RGB matches no channel exactly, * and one of the candidates the nearest-colour search considers. *
channelVisible?Record<number, boolean>undefinedOptional map of visible channels (true=visible, false=hidden). * If provided, data for hidden channels will be preserved * when the canvas pixel is transparent.

Returns ​

void

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:500


setSliceUint8 ​

▸ setSliceUint8(sliceIndex, data, axis?): void

Write a 2D slice from a flat Uint8Array back into the volume.

This is the inverse of getSliceUint8. The data array must have exactly sliceWidth × sliceHeight × channels bytes.

Parameters ​

NameTypeDefault valueDescription
sliceIndexnumberundefinedIndex along the specified axis.
dataUint8ArrayundefinedFlat source array (same layout as returned by getSliceUint8).
axis"x" | "y" | "z"'z''x', 'y', or 'z' (default 'z').

Returns ​

void

Throws

If sliceIndex is out of bounds.

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:1121


setVoxel ​

▸ setVoxel(x, y, z, value, channel?): void

Write a single voxel value.

Values are clamped to the Uint8 range [0, 255] by the typed array.

Parameters ​

NameTypeDefault valueDescription
xnumberundefinedVoxel column (0 … width − 1).
ynumberundefinedVoxel row (0 … height − 1).
znumberundefinedSlice index (0 … depth − 1).
valuenumberundefinedNew voxel value (0 – 255).
channelnumber0Channel index (default 0).

Returns ​

void

Throws

If any coordinate is out of bounds.

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:201


validateSliceIndex ​

▸ Private validateSliceIndex(sliceIndex, axis): void

Validate that a slice index is within bounds for the given axis.

Parameters ​

NameType
sliceIndexnumber
axis"x" | "y" | "z"

Returns ​

void

Throws

If out of bounds.

Defined in ​

src/Utils/segmentation/core/MaskVolume.ts:1184