mesh Module

The mesh module provides low-level functions for mesh processing, contour generation, and mesh creation from 3D images.

Contour Generation

contour(image, iterations=25, smoothing=1, masking_factor=0.75, crop=True, resolution=None, clahe_window=None, clahe_clip_limit=None, gaussian_sigma=None, gaussian_iterations=5, fill_slices=True, chan_vese_lambda1=1, chan_vese_lambda2=1, register_stack=True, target_resolution=None, fill_inland_threshold=None, return_resolution=False, verbose=True)[source]

Generate binary contour from 3D image using morphological active contours.

Performs image preprocessing (CLAHE, Gaussian filtering), stack registration, and morphological Chan-Vese segmentation to extract object contour.

Parameters:
  • image (str | ndarray[tuple[Any, ...], dtype[Any]]) – Input 3D image array or file path

  • iterations (int, default: 25) – Number of morphological Chan-Vese iterations

  • smoothing (int, default: 1) – Smoothing iterations per cycle

  • masking_factor (float | ndarray[tuple[Any, ...], dtype[bool]], default: 0.75) – Initial mask threshold (fraction of Otsu threshold)

  • crop (bool, default: True) – Automatically crop image to content

  • resolution (Sequence[float] | None, default: None) – Spatial resolution in XYZ (micrometers). Auto-detected if None

  • clahe_window (Sequence[int] | None, default: None) – CLAHE window size. Auto-calculated if None

  • clahe_clip_limit (int | None, default: None) – CLAHE clip limit. Auto-calculated if None

  • gaussian_sigma (list[float] | None, default: None) – Gaussian filter sigma. Auto-calculated if None

  • gaussian_iterations (int, default: 5) – Number of Gaussian smoothing iterations

  • fill_slices (bool, default: True) – Fill holes in XY slices

  • chan_vese_lambda1 (float, default: 1) – Morphological Chan-Vese lambda1 parameter

  • chan_vese_lambda2 (float, default: 1) – Morphological Chan-Vese lambda2 parameter

  • register_stack (bool, default: True) – Apply stack registration for slice alignment

  • target_resolution (list[float] | None, default: None) – Target resolution for resampling

  • fill_inland_threshold (float | None, default: None) – Distance threshold for filling inland regions

  • return_resolution (bool, default: False) – Return resolution along with contour

  • verbose (bool, default: True) – Print processing progress

Return type:

ndarray[tuple[Any, ...], dtype[bool]] | tuple[ndarray[tuple[Any, ...], dtype[bool]], Sequence[float]]

Returns:

Binary contour array, and optionally resolution tuple

Mesh Creation

create_mesh(contour, resolution=None, step_size=1)[source]

Generate mesh from binary 3D contour using marching cubes.

Parameters:
  • contour (ndarray[tuple[Any, ...], dtype[Any]]) – Binary 3D array (bool, int, or float) defining the contour

  • resolution (list[float] | None, default: None) – Spatial resolution in XYZ dimensions

  • step_size (int, default: 1) – Step size for marching cubes algorithm

Return type:

PhenoMesh

Returns:

PhenoMesh mesh

create_cellular_mesh(seg_img, resolution=None, verbose=True)[source]

Generate mesh from segmented 3D image with one mesh per cell.

Parameters:
  • seg_img (ndarray[tuple[Any, ...], dtype[integer[Any]]]) – 3D segmentation image with integer labels for each cell

  • resolution (list[float] | None, default: None) – Spatial resolution in XYZ dimensions

  • verbose (bool, default: True) – Print progress information

Return type:

PhenoMesh

Returns:

PhenoMesh combining all cell meshes

Mesh Smoothing

smooth_boundary(mesh, iterations=20, sigma=0.1, inplace=False)[source]

Smooth the boundary of a mesh using Laplacian smoothing.

Parameters:
  • mesh (PolyData) – Mesh to smooth.

  • iterations (int, default: 20) – Number of smoothing iterations. Default is 20.

  • sigma (float, default: 0.1) – Smoothing sigma. Default is 0.1.

  • inplace (bool, default: False) – Update mesh in-place. Default is False.

Return type:

PolyData | None

Returns:

Smoothed mesh, or None if inplace=True.

Mesh Remeshing

remesh(mesh, n_clusters, subdivisions=3)[source]

Regularise the mesh faces using the ACVD algorithm.

Parameters:
  • mesh (PolyData) – The mesh to regularise.

  • n_clusters (int) – The number of clusters (i.e. output number of faces) to use.

  • subdivisions (int, default: 3) – The number of subdivisions to use when clustering.

Return type:

PolyData

Returns:

The regularised mesh.

remesh_decimate(mesh, iterations, upsample_factor=2, downsample_factor=0.5, verbose=True)[source]

Iterative remeshing/decimation.

Parameters:
  • mesh (PolyData) – Mesh to operate on.

  • iterations (int) – Number of iterations.

  • upsample_factor (float, default: 2) – Factor with which to upsample.

  • downsample_factor (float, default: 0.5) – Factor with which to downsample.

  • verbose (bool, default: True) – Flag for whether to print operation steps.

Return type:

PolyData

Returns:

Processed mesh.

Mesh Repair

repair(mesh)[source]

Repair a mesh using MeshFix.

Return type:

PolyData

Parameters:

mesh (PolyData)

repair_small_holes(mesh, max_boundary_edges=100, refine=True)[source]

Repair small holes in a mesh based on the number of edges.

Parameters:
  • mesh (PolyData) – Mesh to repair.

  • max_boundary_edges (int | None, default: 100) – Number of edges to use for the repair. Default is 100.

  • refine (bool, default: True) – Refine the mesh. Default is True.

Return type:

PolyData

Returns:

Repaired mesh.

make_manifold(mesh, hole_edges=300)[source]

Make a mesh manifold by removing non-manifold edges.

Return type:

PolyData

Parameters:
  • mesh (PolyData)

  • hole_edges (int)

Mesh Filtering

filter_by_curvature(mesh, curvature_threshold, curvatures=None)[source]

Remove mesh vertices outside curvature threshold range.

Parameters:
  • mesh (PolyData) – PyVista PolyData mesh

  • curvature_threshold (tuple[float, float] | float) – Tuple (min, max) defining valid curvature range, or single value for symmetric range

  • curvatures (ndarray[tuple[Any, ...], dtype[floating[Any]]] | None, default: None) – Optional curvature array. If None, computes mean curvature

Return type:

PolyData

Returns:

Filtered PyVista PolyData mesh

remove_by_normals(mesh, threshold_angle=0, flip=False, angle='polar')[source]

Remove points based on the point normal angle.

Parameters:
  • mesh (PolyData) – Mesh on which to operate.

  • threshold_angle (float, default: 0) – Threshold for the polar angle (theta). Values smaller than this will be removed. Default = 0.

  • flip (bool, default: False) – Flag to flip normal orientation. Default = False.

  • angle (str, default: 'polar') – Type of angle to use (‘polar’ or ‘azimuth’).

Return type:

PolyData

Returns:

Mesh with the resulting vertices removed.

remove_bridges(mesh, verbose=True)[source]

Remove triangles where all vertices are part of the mesh boundary.

Parameters:
  • mesh (PolyData) – Mesh to operate on.

  • verbose (bool, default: True) – Flag to print processing steps.

Return type:

PolyData

Returns:

Mesh after bridge removal.

remove_tongues(mesh, radius, threshold=6, hole_edges=100, verbose=True)[source]

Remove “tongues” in mesh.

All boundary points within a given radius are considered. The ones where the fraction of the distance along the boundary, as divided by the euclidean distance, is greater than the given threshold.

Parameters:
  • mesh (PolyData) – Mesh to operate on.

  • radius (float) – Radius for boundary point neighbourhood.

  • threshold (float, default: 6) – Threshold for fraction between boundary distance and euclidean distance.

  • hole_edges (int, default: 100) – Size of holes to fill after tongue removal.

  • verbose (bool, default: True) – Print processing steps.

Return type:

PolyData

Returns:

Resulting mesh.

remove_inland_under(mesh, contour, threshold, resolution=None, invert=False)[source]

Remove the part of the mesh that is under the contour.

Parameters:
  • mesh (PolyData) – Mesh to remove the inland part from.

  • contour (ndarray[tuple[Any, ...], dtype[bool]]) – Contour to use for the removal.

  • threshold (int) – Threshold distance from the contour XY periphery.

  • resolution (list[float] | None, default: None) – Resolution of the image. Default is [1, 1, 1].

  • invert (bool, default: False) – Invert the mesh normals. Default is False.

Return type:

PolyData

Returns:

Mesh with the inland part removed.

Mesh Processing

process(mesh, hole_repair_threshold=100, downscaling=0.01, upscaling=2, threshold_angle=60, top_cut='center', tongues_radius=None, tongues_ratio=4, smooth_iterations=200, smooth_relaxation=0.01, curvature_threshold=0.4, inland_threshold=None, contour=None)[source]

Convenience function for postprocessing a mesh.

Parameters:
  • mesh (PolyData) – Mesh to process.

  • hole_repair_threshold (int, default: 100) – Threshold for the hole repair algorithm.

  • downscaling (float, default: 0.01) – Downscaling factor for the mesh.

  • upscaling (float, default: 2) – Upscaling factor for the mesh.

  • threshold_angle (float, default: 60) – Threshold for the polar angle (theta).

  • top_cut (str | tuple[float, float, float], default: 'center') – Top cut location.

  • tongues_radius (float | None, default: None) – Radius of the tongues.

  • tongues_ratio (float, default: 4) – Ratio of the tongues.

  • smooth_iterations (int, default: 200) – Number of smoothing iterations.

  • smooth_relaxation (float, default: 0.01) – Smoothing relaxation factor.

  • curvature_threshold (float, default: 0.4) – Threshold for the curvature.

  • inland_threshold (float | None, default: None) – Threshold for the inland removal.

  • contour (ndarray[tuple[Any, ...], dtype[bool]] | None, default: None) – Contour to use for the inland removal.

Return type:

PolyData

Returns:

Processed mesh.

ecft(mesh, hole_edges=300, inplace=False)

Perform ExtractLargest, Clean, FillHoles, and TriFilter operations.

Parameters:
  • mesh (PolyData) – Mesh to operate on.

  • hole_edges (int, default: 300) – Size of holes to fill.

  • inplace (bool, default: False) – Flag for performing operation in-place.

Return type:

PolyData

Returns:

Mesh after operation.

erode(mesh, iterations=1)[source]

Erode the mesh by removing boundary points iteratively.

Return type:

PolyData

Parameters:
  • mesh (PolyData)

  • iterations (int)

drop_skirt(mesh, max_distance, flip=False)[source]

Downprojects the boundary to the lowest point in the z-direction.

Parameters:
  • mesh (PolyData) – Mesh to operate on.

  • max_distance (float) – Distance in z-direction from the lowest point in the mesh to consider.

  • flip (bool, default: False) – If True, flip the direction.

Return type:

PolyData

Returns:

Mesh with boundary downprojected.

Mesh Analysis

fit_paraboloid_mesh(mesh, return_coord=False)[source]

Fit a paraboloid to a mesh.

Parameters:
  • mesh (PolyData) – Mesh to fit paraboloid to.

  • return_coord (bool, default: False) – If True, return apex coordinates as well.

Return type:

ndarray[tuple[Any, ...], dtype[floating[Any]]] | tuple[ndarray[tuple[Any, ...], dtype[floating[Any]]], ndarray[tuple[Any, ...], dtype[floating[Any]]]]

Returns:

Parameters for the paraboloid, and optionally the apex coordinates.

correct_normal_orientation(mesh, relative='x', inplace=False)[source]

Correct the orientation of the normals of a mesh.

Return type:

PolyData | None

Parameters:
  • mesh (PolyData)

  • relative (str)

  • inplace (bool)

correct_bad_mesh(mesh, verbose=True)[source]

Correct a bad (non-manifold) mesh.

Parameters:
  • mesh (PolyData) – Input mesh.

  • verbose (bool, default: True) – Flag to print out operation procedure.

Return type:

PolyData

Returns:

Corrected mesh.

define_meristem(mesh, method='central_mass', return_coord=False)[source]

Determine which domain corresponds to the meristem.

Parameters:
  • mesh (PolyData) – Mesh to operate on.

  • method (str, default: 'central_mass') – Method for defining the meristem to use.

  • return_coord (bool, default: False) – If True, return coordinates as well.

Return type:

int | tuple[int, ndarray[tuple[Any, ...], dtype[floating[Any]]]]

Returns:

Domain index of the meristem, and optionally the center coordinates.

Vertex Operations

get_vertex_neighbors(mesh, index, include_self=True)[source]

Get the indices of the vertices connected to a given vertex.

Parameters:
  • mesh (PolyData) – Mesh to operate on.

  • index (int) – Index of the vertex.

  • include_self (bool, default: True) – Whether to include the vertex itself in the list of neighbors.

Return type:

ndarray[tuple[Any, ...], dtype[int64]]

Returns:

Array of indices of the connected vertices.

get_vertex_neighbors_all(mesh, include_self=True)[source]

Get all vertex neighbors.

Parameters:
  • mesh (PolyData) – Mesh to operate on.

  • include_self (bool, default: True) – Whether to include the vertex itself in the list of neighbors.

Return type:

list[ndarray[tuple[Any, ...], dtype[int64]]]

Returns:

List of arrays of indices of the connected vertices.

get_vertex_cycles(mesh)[source]

Find cycles (holes/boundaries) in a mesh.

Parameters:

mesh (PolyData) – Mesh to operate on.

Return type:

list[list[int]]

Returns:

List of cycles, each cycle is a list of vertex indices.

Edge Operations

get_boundary_edges(mesh)[source]

Get boundary edges.

Return type:

PolyData

Parameters:

mesh (PolyData)

get_boundary_points(mesh)[source]

Get vertex indices of points in the boundary.

Return type:

ndarray[tuple[Any, ...], dtype[int64]]

Parameters:

mesh (PolyData)

get_feature_edges(mesh, angle=30)[source]

Get feature edges defined by given angle.

Return type:

PolyData

Parameters:
  • mesh (PolyData)

  • angle (float)

get_manifold_edges(mesh)[source]

Get manifold edges.

Return type:

PolyData

Parameters:

mesh (PolyData)

get_non_manifold_edges(mesh)[source]

Get non-manifold edges.

Return type:

PolyData

Parameters:

mesh (PolyData)

Labeling

label_from_image(mesh, segm_img, resolution=None, background=0, mode='point', inplace=False)[source]

Label mesh vertices or faces using nearest voxel in segmented image.

Parameters:
  • mesh (PolyData) – PyVista PolyData mesh to label

  • segm_img (ndarray[tuple[Any, ...], dtype[integer[Any]]]) – 3D segmented image with integer labels

  • resolution (list[float] | None, default: None) – Spatial resolution of segmented image

  • background (int, default: 0) – Background label value to ignore

  • mode (str, default: 'point') – Labeling mode (‘point’ for vertices, ‘face’ for cell centers)

  • inplace (bool, default: False) – Modify mesh in place

Return type:

ndarray[tuple[Any, ...], dtype[integer[Any]]] | None

Returns:

Label array or None if inplace=True

project_to_surface(mesh, int_img, distance_threshold, mask=None, resolution=None, fct=<function sum>, background=0)[source]

Project image intensity values onto mesh surface.

Aggregates intensity values within distance threshold of each vertex.

Parameters:
  • mesh (PolyData) – PyVista PolyData mesh

  • int_img (ndarray[tuple[Any, ...], dtype[Any]]) – 3D intensity image array

  • distance_threshold (float) – Maximum distance from surface for projection

  • mask (ndarray[tuple[Any, ...], dtype[bool]] | None, default: None) – Optional mask array for image

  • resolution (list[float] | None, default: None) – Spatial resolution of intensity image

  • fct (Callable[..., Any], default: <function sum at 0x7fdc25a994b0>) – Aggregation function (currently only np.sum supported)

  • background (float, default: 0) – Background value to ignore in image

Return type:

ndarray[tuple[Any, ...], dtype[floating[Any]]]

Returns:

Array of projected values, one per mesh vertex