PhenoMesh

The PhenoMesh class extends PyVista’s PolyData with phenotyping-specific operations for 3D plant analysis.

PhenoMesh Class

class PhenoMesh[source]

Bases: PolyData

Extension of PyVista PolyData with phenotyping-specific operations.

PhenoMesh inherits from pv.PolyData, so it can be used anywhere a PolyData is expected. It adds convenience methods for 3D plant phenotyping workflows including smoothing, repair, curvature analysis, and domain segmentation.

Parameters:
  • var_inp (PolyData | str | Path | ndarray[tuple[Any, ...], dtype[floating[Any]]] | None, default: None) – Input data - can be a PolyData, file path, or vertex array

  • *args (Any) – Additional positional arguments passed to pv.PolyData

  • contour (ndarray[tuple[Any, ...], dtype[bool]] | None, default: None) – Optional binary contour array the mesh was generated from

  • resolution (list[float] | None, default: None) – Optional spatial resolution [z, y, x]

  • **kwargs (Any) – Additional keyword arguments passed to pv.PolyData

Example

>>> mesh = PhenoMesh(pv.Sphere())
>>> smoothed = mesh.smooth(iterations=100)
>>> isinstance(mesh, pv.PolyData)  # True - PhenoMesh is a PolyData
True
__init__(var_inp=None, *args, contour=None, resolution=None, **kwargs)[source]

Initialize PhenoMesh with optional PolyData, file, or vertex array.

Parameters:
Return type:

None

property contour: ndarray[tuple[Any, ...], dtype[bool]] | None

Binary contour array the mesh was generated from.

property resolution: list[float] | None

Spatial resolution [z, y, x].

classmethod from_polydata(polydata, contour=None, resolution=None)[source]

Create PhenoMesh from PyVista PolyData.

Parameters:
  • polydata (PolyData) – PyVista PolyData mesh

  • contour (ndarray[tuple[Any, ...], dtype[bool]] | None, default: None) – Optional binary contour array

  • resolution (list[float] | None, default: None) – Optional spatial resolution

Return type:

PhenoMesh

Returns:

New PhenoMesh instance

to_polydata()[source]

Return a plain PolyData copy (without PhenoMesh attributes).

Return type:

PolyData

Returns:

A new pv.PolyData copy of this mesh

copy(deep=True)[source]

Create a copy of this PhenoMesh.

Parameters:

deep (bool, default: True) – If True, create a deep copy

Return type:

PhenoMesh

Returns:

New PhenoMesh with copied data

property n_faces: int

Number of faces in the mesh (alias for n_cells).

smooth(iterations=100, relaxation_factor=0.01, feature_smoothing=False, boundary_smoothing=True, edge_angle=15.0, feature_angle=45.0)[source]

Smooth the mesh using Laplacian smoothing.

Parameters:
  • iterations (int, default: 100) – Number of smoothing iterations

  • relaxation_factor (float, default: 0.01) – Relaxation factor for smoothing (0-1)

  • feature_smoothing (bool, default: False) – Smooth along features

  • boundary_smoothing (bool, default: True) – Smooth boundary edges

  • edge_angle (float, default: 15.0) – Angle for edge detection

  • feature_angle (float, default: 45.0) – Angle for feature detection

Return type:

PhenoMesh

Returns:

New PhenoMesh with smoothed surface

smooth_taubin(iterations=100, pass_band=0.1, edge_angle=15.0, feature_angle=45.0, feature_smoothing=False, boundary_smoothing=True, non_manifold_smoothing=True, normalize_coordinates=True)[source]

Smooth the mesh using Taubin smoothing (low-pass filter).

Taubin smoothing is less prone to shrinkage than Laplacian smoothing.

Parameters:
  • iterations (int, default: 100) – Number of smoothing iterations

  • pass_band (float, default: 0.1) – Pass band for the filter (0-2)

  • edge_angle (float, default: 15.0) – Angle for edge detection

  • feature_angle (float, default: 45.0) – Angle for feature detection

  • feature_smoothing (bool, default: False) – Smooth along features

  • boundary_smoothing (bool, default: True) – Smooth boundary edges

  • non_manifold_smoothing (bool, default: True) – Smooth non-manifold edges

  • normalize_coordinates (bool, default: True) – Normalize coordinates before smoothing

Return type:

PhenoMesh

Returns:

New PhenoMesh with smoothed surface

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

Smooth the boundary of the mesh using Laplacian smoothing.

Parameters:
  • iterations (int, default: 20) – Number of smoothing iterations

  • sigma (float, default: 0.1) – Smoothing sigma

Return type:

PhenoMesh

Returns:

Smoothed PhenoMesh

decimate(target_reduction=0.5, volume_preservation=True)[source]

Reduce mesh complexity by decimating faces.

Parameters:
  • target_reduction (float, default: 0.5) – Fraction of faces to remove (0-1)

  • volume_preservation (bool, default: True) – Preserve mesh volume during decimation

Return type:

PhenoMesh

Returns:

New PhenoMesh with reduced complexity

subdivide(n_subdivisions=1, subfilter='linear')[source]

Subdivide mesh faces to increase resolution.

Parameters:
  • n_subdivisions (int, default: 1) – Number of subdivision iterations

  • subfilter (str, default: 'linear') – Subdivision filter (‘linear’, ‘butterfly’, ‘loop’)

Return type:

PhenoMesh

Returns:

New PhenoMesh with subdivided faces

remesh(n_clusters, subdivisions=3)[source]

Regularise the mesh faces using the ACVD algorithm.

Parameters:
  • n_clusters (int) – The number of clusters (i.e. output number of faces)

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

Return type:

PhenoMesh

Returns:

Regularised PhenoMesh

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

Iterative remeshing/decimation.

Parameters:
  • 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) – Print operation steps

Return type:

PhenoMesh

Returns:

Processed PhenoMesh

triangulate()[source]

Convert all faces to triangles.

Return type:

PhenoMesh

Returns:

New PhenoMesh with triangulated faces

clean(point_merging=True, tolerance=None, lines_to_points=True, polys_to_lines=True, strips_to_polys=True, absolute=True)[source]

Clean mesh by removing degenerate cells and merging duplicate points.

Parameters:
  • point_merging (bool, default: True) – Merge coincident points

  • tolerance (float | None, default: None) – Tolerance for point merging

  • lines_to_points (bool, default: True) – Convert degenerate lines to points

  • polys_to_lines (bool, default: True) – Convert degenerate polygons to lines

  • strips_to_polys (bool, default: True) – Convert strips to polygons

  • absolute (bool, default: True) – Use absolute tolerance

Return type:

PhenoMesh

Returns:

Cleaned PhenoMesh

extract_largest()[source]

Extract the largest connected component.

Return type:

PhenoMesh

Returns:

New PhenoMesh containing only the largest connected region

fill_holes(hole_size=1000.0)[source]

Fill holes in the mesh.

Parameters:

hole_size (float, default: 1000.0) – Maximum hole size to fill

Return type:

PhenoMesh

Returns:

New PhenoMesh with holes filled

repair()[source]

Repair the mesh using MeshFix.

Return type:

PhenoMesh

Returns:

Repaired PhenoMesh

repair_small_holes(max_hole_edges=100, refine=True)[source]

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

Parameters:
  • max_hole_edges (int | None, default: 100) – Maximum number of edges for holes to repair

  • refine (bool, default: True) – Refine the mesh after repair

Return type:

PhenoMesh

Returns:

Repaired PhenoMesh

make_manifold(hole_edges=300)[source]

Make the mesh manifold by removing non-manifold edges.

Parameters:

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

Return type:

PhenoMesh

Returns:

Manifold PhenoMesh

correct_bad_mesh(verbose=True)[source]

Correct a bad (non-manifold) mesh.

Parameters:

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

Return type:

PhenoMesh

Returns:

Corrected PhenoMesh

extract_clean_fill_triangulate(hole_edges=300)[source]

Perform ExtractLargest, Clean, FillHoles, and TriFilter operations.

Parameters:

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

Return type:

PhenoMesh

Returns:

Processed PhenoMesh

ecft(hole_edges=300)

Perform ExtractLargest, Clean, FillHoles, and TriFilter operations.

Parameters:

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

Return type:

PhenoMesh

Returns:

Processed PhenoMesh

compute_normals(cell_normals=True, point_normals=True, flip_normals=False, consistent_normals=True, auto_orient_normals=False, non_manifold_traversal=True, feature_angle=30.0)[source]

Compute surface normals.

Parameters:
  • cell_normals (bool, default: True) – Compute cell normals

  • point_normals (bool, default: True) – Compute point normals

  • flip_normals (bool, default: False) – Flip all normals

  • consistent_normals (bool, default: True) – Make normals consistent

  • auto_orient_normals (bool, default: False) – Orient normals outward

  • non_manifold_traversal (bool, default: True) – Allow traversal across non-manifold edges

  • feature_angle (float, default: 30.0) – Feature angle for splitting

Return type:

PhenoMesh

Returns:

New PhenoMesh with computed normals

flip_normals()[source]

Flip all surface normals.

Return type:

PhenoMesh

Returns:

New PhenoMesh with flipped normals

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

Correct the orientation of the normals.

Parameters:
  • relative (str, default: 'x') – Axis to use for orientation (‘x’, ‘y’, ‘z’)

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

Return type:

PhenoMesh | None

Returns:

PhenoMesh with corrected normals, or None if inplace

compute_curvature(curvature_type='mean')[source]

Compute surface curvature.

Parameters:

curvature_type (Literal['mean', 'gaussian', 'minimum', 'maximum'], default: 'mean') – Curvature type (‘mean’, ‘gaussian’, ‘minimum’, ‘maximum’)

Return type:

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

Returns:

Array of curvature values per vertex

filter_by_curvature(curvature_threshold, curvatures=None)[source]

Remove mesh vertices outside curvature threshold range.

Parameters:
Return type:

PhenoMesh

Returns:

Filtered PhenoMesh

remove_points(mask, keep_scalars=True)[source]

Remove points from the mesh.

Parameters:
  • mask (ndarray[tuple[Any, ...], dtype[bool]]) – Boolean mask indicating points to remove (True = remove)

  • keep_scalars (bool, default: True) – Preserve scalar data

Return type:

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

Returns:

Tuple of (new PhenoMesh with points removed, indices of removed points)

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

Remove points based on the point normal angle.

Parameters:
  • threshold_angle (float, default: 0) – Threshold for the polar angle

  • flip (bool, default: False) – Flip normal orientation

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

Return type:

PhenoMesh

Returns:

PhenoMesh with vertices removed

erode(iterations=1)[source]

Erode the mesh by removing boundary points iteratively.

Parameters:

iterations (int, default: 1) – Number of erosion iterations

Return type:

PhenoMesh

Returns:

Eroded PhenoMesh

remove_bridges(verbose=True)[source]

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

Parameters:

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

Return type:

PhenoMesh

Returns:

PhenoMesh after bridge removal

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

Remove “tongues” in mesh.

Parameters:
  • radius (float) – Radius for boundary point neighbourhood

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

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

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

Return type:

PhenoMesh

Returns:

PhenoMesh with tongues removed

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

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

Parameters:
  • 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

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

Return type:

PhenoMesh

Returns:

PhenoMesh with the inland part removed

clip(normal='x', origin=None, invert=True)[source]

Clip mesh with a plane.

Parameters:
  • normal (str | Sequence[float], default: 'x') – Plane normal direction (‘x’, ‘y’, ‘z’, ‘-x’, ‘-y’, ‘-z’) or 3-element normal vector

  • origin (Sequence[float] | None, default: None) – Point on the clipping plane

  • invert (bool, default: True) – Invert clipping direction

Return type:

PhenoMesh

Returns:

Clipped PhenoMesh

rotate_x(angle, inplace=False)[source]

Rotate mesh around X axis.

Parameters:
  • angle (float) – Rotation angle in degrees

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

Return type:

Self

Returns:

Rotated PhenoMesh (or self if inplace)

rotate_y(angle, inplace=False)[source]

Rotate mesh around Y axis.

Parameters:
  • angle (float) – Rotation angle in degrees

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

Return type:

Self

Returns:

Rotated PhenoMesh (or self if inplace)

rotate_z(angle, inplace=False)[source]

Rotate mesh around Z axis.

Parameters:
  • angle (float) – Rotation angle in degrees

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

Return type:

Self

Returns:

Rotated PhenoMesh (or self if inplace)

drop_skirt(max_distance, flip=False)[source]

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

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

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

Return type:

PhenoMesh

Returns:

PhenoMesh with boundary downprojected

compute_center_of_mass()[source]

Compute center of mass.

Return type:

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

Returns:

3-element array of center of mass coordinates

compute_geodesic_distance(start_vertex, end_vertex)[source]

Compute geodesic distance between two vertices.

Parameters:
  • start_vertex (int) – Index of start vertex

  • end_vertex (int) – Index of end vertex

Return type:

float

Returns:

Geodesic distance along the mesh surface

find_closest_point(point)[source]

Find the index of the closest point.

Parameters:

point (Sequence[float]) – Query point coordinates

Return type:

int

Returns:

Index of the closest point

ray_trace(origin, end_point)[source]

Perform ray tracing on the mesh.

Parameters:
Return type:

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

Returns:

Tuple of (intersection points, cell indices)

get_boundary_points()[source]

Get vertex indices of points in the boundary.

Return type:

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

Returns:

Array of boundary vertex indices

get_boundary_edges()[source]

Get boundary edges.

Return type:

PhenoMesh

Returns:

PhenoMesh containing boundary edges

get_non_manifold_edges()[source]

Get non-manifold edges.

Return type:

PhenoMesh

Returns:

PhenoMesh containing non-manifold edges

get_manifold_edges()[source]

Get manifold edges.

Return type:

PhenoMesh

Returns:

PhenoMesh containing manifold edges

get_feature_edges(angle=30)[source]

Get feature edges defined by given angle.

Parameters:

angle (float, default: 30) – Feature angle threshold

Return type:

PhenoMesh

Returns:

PhenoMesh containing feature edges

get_vertex_neighbors(index, include_self=True)[source]

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

Parameters:
  • index (int) – Index of the vertex

  • include_self (bool, default: True) – Include the vertex itself in the list

Return type:

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

Returns:

Array of connected vertex indices

get_all_vertex_neighbors(include_self=True)[source]

Get all vertex neighbors.

Parameters:

include_self (bool, default: True) – Include each vertex in its own neighbor list

Return type:

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

Returns:

List of arrays of connected vertex indices

get_vertex_cycles()[source]

Find cycles (holes/boundaries) in the mesh.

Return type:

list[list[int]]

Returns:

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

label_from_image(segmented_image, resolution=None, background=0, mode='point')[source]

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

Parameters:
  • segmented_image (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)

Return type:

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

Returns:

Label array

project_to_surface(intensity_image, distance_threshold, mask=None, resolution=None, aggregation_function=<function sum>, background=0)[source]

Project image intensity values onto mesh surface.

Parameters:
  • intensity_image (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

  • aggregation_function (Callable[..., Any], default: <function sum at 0x7fdc25a994b0>) – Aggregation function

  • 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

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

Determine which domain corresponds to the meristem.

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

  • return_coordinates (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

fit_paraboloid(return_coord=False)[source]

Fit a paraboloid to the mesh.

Parameters:

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

process(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 the mesh.

Parameters:
  • 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

  • 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:

PhenoMesh

Returns:

Processed PhenoMesh

__add__(dataset)[source]

Concatenate meshes.

Return type:

PhenoMesh

Parameters:

dataset (PolyData)

__repr__()[source]

Return string representation.

Return type:

str

__str__()[source]

Return string representation.

Return type:

str

smoothen(iterations=100, relaxation_factor=0.01, feature_smoothing=False, boundary_smoothing=True, edge_angle=15.0, feature_angle=45.0)

Smooth the mesh using Laplacian smoothing.

Parameters:
  • iterations (int, default: 100) – Number of smoothing iterations

  • relaxation_factor (float, default: 0.01) – Relaxation factor for smoothing (0-1)

  • feature_smoothing (bool, default: False) – Smooth along features

  • boundary_smoothing (bool, default: True) – Smooth boundary edges

  • edge_angle (float, default: 15.0) – Angle for edge detection

  • feature_angle (float, default: 45.0) – Angle for feature detection

Return type:

PhenoMesh

Returns:

New PhenoMesh with smoothed surface

filter_curvature(curvature_threshold, curvatures=None)

Remove mesh vertices outside curvature threshold range.

Parameters:
Return type:

PhenoMesh

Returns:

Filtered PhenoMesh

remove_normals(threshold_angle=0, flip=False, angle_type='polar')

Remove points based on the point normal angle.

Parameters:
  • threshold_angle (float, default: 0) – Threshold for the polar angle

  • flip (bool, default: False) – Flip normal orientation

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

Return type:

PhenoMesh

Returns:

PhenoMesh with vertices removed

repair_small(max_hole_edges=100, refine=True)

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

Parameters:
  • max_hole_edges (int | None, default: 100) – Maximum number of edges for holes to repair

  • refine (bool, default: True) – Refine the mesh after repair

Return type:

PhenoMesh

Returns:

Repaired PhenoMesh

label_mesh(segmented_image, resolution=None, background=0, mode='point')

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

Parameters:
  • segmented_image (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)

Return type:

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

Returns:

Label array

project2surface(intensity_image, distance_threshold, mask=None, resolution=None, aggregation_function=<function sum>, background=0)

Project image intensity values onto mesh surface.

Parameters:
  • intensity_image (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

  • aggregation_function (Callable[..., Any], default: <function sum at 0x7fdc25a994b0>) – Aggregation function

  • 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

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)

Convenience function for postprocessing the mesh.

Parameters:
  • 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

  • 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:

PhenoMesh

Returns:

Processed PhenoMesh

boundary_points()

Get vertex indices of points in the boundary.

Return type:

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

Returns:

Array of boundary vertex indices

boundary_edges()

Get boundary edges.

Return type:

PhenoMesh

Returns:

PhenoMesh containing boundary edges

non_manifold_edges()

Get non-manifold edges.

Return type:

PhenoMesh

Returns:

PhenoMesh containing non-manifold edges

manifold_edges()

Get manifold edges.

Return type:

PhenoMesh

Returns:

PhenoMesh containing manifold edges

feature_edges(angle=30)

Get feature edges defined by given angle.

Parameters:

angle (float, default: 30) – Feature angle threshold

Return type:

PhenoMesh

Returns:

PhenoMesh containing feature edges

vertex_neighbors(index, include_self=True)

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

Parameters:
  • index (int) – Index of the vertex

  • include_self (bool, default: True) – Include the vertex itself in the list

Return type:

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

Returns:

Array of connected vertex indices

vertex_neighbors_all(include_self=True)

Get all vertex neighbors.

Parameters:

include_self (bool, default: True) – Include each vertex in its own neighbor list

Return type:

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

Returns:

List of arrays of connected vertex indices

vertex_cycles()

Find cycles (holes/boundaries) in the mesh.

Return type:

list[list[int]]

Returns:

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

find_point(point)

Find the index of the closest point.

Parameters:

point (Sequence[float]) – Query point coordinates

Return type:

int

Returns:

Index of the closest point

Usage Examples

Creating a PhenoMesh

from phenotastic import PhenoMesh
import pyvista as pv

# From a PyVista mesh
mesh = PhenoMesh(pv.Sphere())

# From a file
mesh = PhenoMesh(pv.read("mesh.vtk"))

# With custom attributes
mesh = PhenoMesh(
    pv.Sphere(),
    contour=binary_contour_array,
    resolution=[1.0, 1.0, 1.0]
)

Mesh Processing

# Smoothing
mesh = mesh.smooth(iterations=100)
mesh = mesh.smooth_taubin(iterations=50, pass_band=0.1)

# Remeshing
mesh = mesh.remesh(n_clusters=10000)

# Repair
mesh = mesh.repair()
mesh = mesh.repair_small(nbe=100)

Curvature Analysis

# Compute curvature
curvature = mesh.compute_curvature(curvature_type="mean")

# Filter by curvature
filtered = mesh.filter_curvature(curvature_threshold=(-0.5, 0.5))

Interoperability

# PhenoMesh is a PolyData
isinstance(mesh, pv.PolyData)  # True

# Use anywhere PolyData is expected
plotter = pv.Plotter()
plotter.add_mesh(mesh)

# Convert to plain PolyData
polydata = mesh.to_polydata()

# Create from PolyData
mesh = PhenoMesh.from_polydata(polydata)