fill_surface: Fill a volume cube based on water-tight surface

View source: R/imaging-fill-surface.R

fill_surfaceR Documentation

Fill a volume cube based on water-tight surface

Description

Create a cube volume (256 'voxels' on each margin), fill in the 'voxels' that are inside of the surface.

Usage

fill_surface(
  surface,
  inflate = 0,
  close_radius = NULL,
  resolution = 256L,
  IJK2RAS = NULL,
  preview = FALSE,
  preview_frame = 128
)

Arguments

surface

a surface mesh; accepted classes include 'mesh3d' (from rgl), 'fs.surface' (from freesurferformats), 'ieegio_surface' (from ieegio), or a bare list containing a vb vertex matrix; see ensure_mesh3d for details and for how 'ieegio_surface' inputs are coerced

inflate

amount of 'voxels' to inflate on the final result; must be a non-negative integer. A zero inflate value means the resulting volume is tightly close to the surface

close_radius

radius (in 'voxels' along the finest 'IJK' axis; see IJK2RAS) of the morphological closing (dilate-then-erode) operation used to connect the embedded surface into a water-tight shell and to remove small topological handles/tunnels (for example a hole drilled through an otherwise solid structure) before the surface is filled; default is NULL, which derives a radius from the surface geometry (capped at 15 'voxels'). Handles/tunnels wider than roughly twice this radius (in physical, ⁠RAS⁠ space) will not be closed, so when the input surface is known to contain larger topological defects, set this to a larger number explicitly. Larger radii cost more time and memory (the closing operates on a dense resolution^3 volume) and - because the operation is performed in a fixed-size volume - must leave enough margin that the dilated shell does not reach the volume boundary; radii that are too large for the working cube will be capped with a warning

resolution

number of 'voxels' along each margin of the working cube volume that the surface is embedded into; default is 256. Larger values increase the spatial precision of the fill and the closing operation (at the cost of memory and computation time, which scale with resolution^3); the value must leave enough room for the surface (transformed into 'IJK' space via IJK2RAS) plus the closing margin to fit inside the cube

IJK2RAS

volume 'IJK' (zero-indexed coordinate index) to 'tkrRAS' transform, default is automatically determined leave it ‘NULL' if you don’t know how to set it. When the linear part of IJK2RAS encodes voxel sizes that differ across axes (pixdim, i.e. the three 'IJK' axes do not advance by the same physical distance per 'voxel'), the dilate/erode operations underlying close_radius and inflate automatically use a different number of 'voxels' along each axis so that the resulting structuring element stays isotropic in physical (⁠RAS⁠) space

preview

whether to preview the results; default is false

preview_frame

integer from 1 to 256 the depth frame used to generate preview.

Details

This function creates a volume (256 on each margin) and fill in the volume from a surface mesh. The surface vertex points will be embedded into the volume first. These points may not be connected together, hence for each 'voxel', a cube patch will be applied to grow the volume. Then, the volume will be bucket-filled from a corner, forming a negated mask of "outside-of-surface" area. The inverted bucket-filled volume is then shrunk so the mask boundary tightly fits the surface

Value

A list containing the filled volume and parameters used to generate the volume

Coercing Surface Inputs

The surface objects are converted to 'mesh3d' object before applying further calculations.

When surface is a surface ieegio object, the returned mesh3d$vb contains vertices that have been left-multiplied by surface$geometry$transforms[[1]] (the first transform stored in the geometry, typically the ScannerAnat or voxel-to-world transform).

Breaking change: Earlier versions (before 0.2.6) of ravetools returned the raw surface$geometry$vertices without applying any transform, so downstream code often multiplied by surface$geometry$transforms[[1]] (or an equivalent) manually before working in world space. Such code will now double apply the transform and produce incorrect coordinates. If you previously applied a transform from surface$geometry$transforms by hand after calling a ravetools mesh function on an 'ieegio_surface', remove that manual step.

Surfaces with an empty or missing geometry$transforms list (for example, surfaces produced by ieegio's volume_to_surface, which stores an identity transform) are unaffected.

If geometry$transforms contains multiple transforms targeting different coordinate spaces, only the first one is used. Callers that need a specific target space should select and apply that transform themselves before calling ravetools mesh functions.

Author(s)

Zhengjia Wang

See Also

ensure_mesh3d

Examples




# takes > 5s to run example

# Generate a sphere
surface <- vcg_sphere()
surface$vb[1:3, ] <- surface$vb[1:3, ] * 50

fill_surface(surface, preview = TRUE)




ravetools documentation built on Aug. 31, 2026, 5:07 p.m.