copper3d / Modules / Utils/segmentation/core/MaskVolume / MaskVolume
Class: MaskVolume
Utils/segmentation/core/MaskVolume.MaskVolume
Table of contents
Constructors
Properties
Methods
- buildRgbToChannelMap
- clear
- clearSlice
- clone
- getBytesPerSlice
- getChannelColor
- getChannels
- getColorMap
- getDimensions
- getIndex
- getMemoryUsage
- getRawData
- getSliceDimensions
- getSliceImageData
- getSliceUint8
- getVersion
- getVoxel
- hasData
- renderBlended
- renderColoredMulti
- renderColoredSingle
- renderGrayscale
- renderLabelSliceInto
- resetChannelColors
- setChannelColor
- setRawData
- setSliceFromImageData
- setSliceLabelsFromImageData
- setSliceUint8
- setVoxel
- validateSliceIndex
Constructors
constructor
• new MaskVolume(width, height, depth, channels?, customColorMap?)
Create a new MaskVolume.
All voxels are initialised to 0.
Parameters
| Name | Type | Default value | Description |
|---|---|---|---|
width | number | undefined | Number of voxels along the X axis (≥ 1). |
height | number | undefined | Number of voxels along the Y axis (≥ 1). |
depth | number | undefined | Number of voxels along the Z axis (≥ 1). |
channels | number | 1 | Number of channels per voxel (default 1). |
customColorMap? | ChannelColorMap | undefined | Optional 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. Uses this instance's colorMap (channels 1-8, skips 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:619
clear
▸ clear(): void
Zero every voxel in the entire volume (all channels).
Returns
void
Example
vol.clear();
vol.getVoxel(256, 256, 50); // 0vol.clear();
vol.getVoxel(256, 256, 50); // 0Defined in
src/Utils/segmentation/core/MaskVolume.ts:860
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
| Name | Type | Default value | Description |
|---|---|---|---|
sliceIndex | number | undefined | Index along the specified axis. |
axis | "x" | "y" | "z" | 'z' | 'x', 'y', or 'z' (default 'z'). |
channel? | number | undefined | Optional channel to clear (default: all). |
Returns
void
Throws
If sliceIndex is out of bounds.
Example
// 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:915
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
A new MaskVolume with identical content.
Example
// 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:834
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:752
getChannelColor
▸ getChannelColor(channel): RGBAColor
Get the current color for a channel.
Falls back to the background color (transparent) if no color is defined.
Parameters
| Name | Type | Description |
|---|---|---|
channel | number | Channel index. |
Returns
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:740
getColorMap
▸ getColorMap(): ChannelColorMap
Get a shallow copy of the entire color map.
Returns
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
{ width, height, depth } — a fresh object (safe to mutate).
Defined in
src/Utils/segmentation/core/MaskVolume.ts:731
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)
+ channelindex = (z × height × width × channels)
+ (y × width × channels)
+ (x × channels)
+ channelParameters
| Name | Type | Default value | Description |
|---|---|---|---|
x | number | undefined | Voxel column (0 … width − 1). |
y | number | undefined | Voxel row (0 … height − 1). |
z | number | undefined | Slice index (0 … depth − 1). |
channel | number | 0 | Channel 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
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:767
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
// 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:788
getSliceDimensions
▸ Private getSliceDimensions(axis): [number, number]
Get the 2D slice dimensions for a given axis.
Parameters
| Name | Type |
|---|---|
axis | "x" | "y" | "z" |
Returns
[number, number]
[width, height] of the slice.
Defined in
src/Utils/segmentation/core/MaskVolume.ts:1087
getSliceImageData
▸ getSliceImageData(sliceIndex, axis?, options?): ImageData
Extract a 2D slice as an ImageData with color mapping.
Slice dimensions depend on the axis:
| Axis | Plane | Width | Height |
|---|---|---|---|
z | Axial | width | height |
y | Coronal | width | depth |
x | Sagittal | depth | height |
Parameters
| Name | Type | Default value | Description |
|---|---|---|---|
sliceIndex | number | undefined | Index along the specified axis. |
axis | "x" | "y" | "z" | 'z' | 'x' (sagittal), 'y' (coronal), or 'z' (axial). |
options | SliceRenderOptions | {} | 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
// 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
| Name | Type | Default value | Description |
|---|---|---|---|
sliceIndex | number | undefined | Index 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.
| Name | Type |
|---|---|
data | Uint8Array |
height | number |
width | number |
Throws
If sliceIndex is out of bounds.
Example
const { data, width, height } = vol.getSliceUint8(50, 'z');
// data.length === width * height * channelsconst { data, width, height } = vol.getSliceUint8(50, 'z');
// data.length === width * height * channelsDefined in
src/Utils/segmentation/core/MaskVolume.ts:987
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
| Name | Type | Default value | Description |
|---|---|---|---|
x | number | undefined | Voxel column (0 … width − 1). |
y | number | undefined | Voxel row (0 … height − 1). |
z | number | undefined | Slice index (0 … depth − 1). |
channel | number | 0 | Channel 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
const vol = new MaskVolume(512, 512, 100);
vol.hasData(); // false (all zeros)
vol.setVoxel(256, 256, 50, 255);
vol.hasData(); // trueconst vol = new MaskVolume(512, 512, 100);
vol.hasData(); // false (all zeros)
vol.setVoxel(256, 256, 50, 255);
vol.hasData(); // trueDefined in
src/Utils/segmentation/core/MaskVolume.ts:885
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
| Name | Type |
|---|---|
pixels | Uint8ClampedArray |
width | number |
height | number |
sliceIndex | number |
axis | "x" | "y" | "z" |
colorMap | ChannelColorMap |
visibleChannels | boolean[] |
opacity | number |
Returns
void
Defined in
src/Utils/segmentation/core/MaskVolume.ts:1312
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
| Name | Type |
|---|---|
pixels | Uint8ClampedArray |
width | number |
height | number |
sliceIndex | number |
axis | "x" | "y" | "z" |
colorMap | ChannelColorMap |
visibleChannels | boolean[] |
opacity | number |
Returns
void
Defined in
src/Utils/segmentation/core/MaskVolume.ts:1238
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
| Name | Type |
|---|---|
pixels | Uint8ClampedArray |
width | number |
height | number |
sliceIndex | number |
axis | "x" | "y" | "z" |
channel | number |
colorMap | ChannelColorMap |
opacity | number |
Returns
void
Defined in
src/Utils/segmentation/core/MaskVolume.ts:1177
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
| Name | Type |
|---|---|
pixels | Uint8ClampedArray |
width | number |
height | number |
sliceIndex | number |
axis | "x" | "y" | "z" |
channel | number |
Returns
void
Defined in
src/Utils/segmentation/core/MaskVolume.ts:1124
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
| Name | Type | Default value | Description |
|---|---|---|---|
sliceIndex | number | undefined | Index along the specified axis. |
axis | "x" | "y" | "z" | 'z' | 'x', 'y', or 'z'. |
target | ImageData | undefined | Pre-allocated ImageData buffer (must match slice dimensions). |
channelVisible? | Record<number, boolean> | undefined | Array where index N indicates if channel N is visible. If undefined, all channels are visible. |
opacity | number | 1.0 | Opacity multiplier 0.0–1.0 (default 1.0). |
Returns
void
Defined in
src/Utils/segmentation/core/MaskVolume.ts:647
resetChannelColors
▸ resetChannelColors(channel?): void
Reset the color map for one or all labels to defaults.
Parameters
| Name | Type | Description |
|---|---|---|
channel? | number | Optional 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 (0-8), not the storage channel index.
Parameters
| Name | Type | Description |
|---|---|---|
channel | number | Label/channel index to update (0-8). |
color | RGBAColor | New RGBA color. |
Returns
void
Throws
If channel is outside valid label range [0, 8].
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
| Name | Type | Description |
|---|---|---|
newData | Uint8Array | Replacement data. |
Returns
void
Throws
If the length does not match.
Example
// 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:808
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
| Name | Type | Default value | Description |
|---|---|---|---|
sliceIndex | number | undefined | Index along the specified axis. |
imageData | ImageData | undefined | Source ImageData (expected dimensions must match the axis). |
axis | "x" | "y" | "z" | 'z' | 'x', 'y', or 'z' (default 'z'). |
channel | number | 0 | Target channel (default 0, ignored when numChannels >= 4). |
Returns
void
Throws
If sliceIndex is out of bounds.
Throws
If imageData dimensions don't match.
Example
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
| Name | Type | Default value | Description |
|---|---|---|---|
sliceIndex | number | undefined | Index along the specified axis. * |
imageData | ImageData | undefined | Canvas ImageData (RGBA) to convert. * |
axis | "x" | "y" | "z" | 'z' | 'x', 'y', or 'z'. * |
activeChannel | number | 1 | Fallback label for pixels whose RGB doesn't match any channel (1-8). * |
channelVisible? | Record<number, boolean> | undefined | Optional 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:499
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
| Name | Type | Default value | Description |
|---|---|---|---|
sliceIndex | number | undefined | Index along the specified axis. |
data | Uint8Array | undefined | Flat 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:1040
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
| Name | Type | Default value | Description |
|---|---|---|---|
x | number | undefined | Voxel column (0 … width − 1). |
y | number | undefined | Voxel row (0 … height − 1). |
z | number | undefined | Slice index (0 … depth − 1). |
value | number | undefined | New voxel value (0 – 255). |
channel | number | 0 | Channel 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
| Name | Type |
|---|---|
sliceIndex | number |
axis | "x" | "y" | "z" |
Returns
void
Throws
If out of bounds.