API Reference
meshmash.pipeline
¶
chunked_hks_pipeline(mesh, query_indices=None, simplify_agg=7, simplify_target_reduction=0.7, overlap_distance=20000, max_vertex_threshold=20000, min_vertex_threshold=200, max_overlap_neighbors=40000, n_components=32, t_min=50000.0, t_max=20000000.0, max_eigenvalue=5e-06, robust=True, mollify_factor=1e-05, truncate_extra=True, drop_first=True, decomposition_dtype=np.float64, compute_hks_kwargs={}, nuc_point=None, distance_threshold=3.0, auxiliary_features=True, n_jobs=-1, verbose=False)
¶
Compute HKS features and aggregate them across overlapping mesh chunks.
.. deprecated:: Prefer condensed_hks_pipeline, which is more memory-efficient because it aggregates features within each chunk before stitching. This function performs aggregation after all chunk features are stitched together, which requires holding the full-mesh feature matrix in memory.
Runs the following pipeline:
- Optional mesh simplification via
fast-simplification. - Spectral bisection of the mesh into overlapping chunks (MeshStitcher).
- Computation of compute_hks per chunk.
- Connectivity-constrained Ward agglomeration of vertices into local domains (agglomerate_split_mesh).
- Area-weighted aggregation of HKS features to each domain (aggregate_features).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Input mesh. Either a |
required | |
query_indices
|
Vertex indices of interest. If provided, only chunks containing
these vertices are processed. |
None
|
|
simplify_agg
|
Decimation aggressiveness (0–10). Higher values are faster but
reduce mesh quality. Low values may prevent reaching
|
7
|
|
simplify_target_reduction
|
Fraction of triangles to remove during simplification. |
0.7
|
|
overlap_distance
|
Geodesic radius used to grow each chunk into its overlap region. Larger values reduce boundary artefacts for long timescales but increase compute time. |
20000
|
|
max_vertex_threshold
|
Maximum vertices per core chunk before overlapping. |
20000
|
|
min_vertex_threshold
|
Minimum component size; smaller components are discarded. |
200
|
|
max_overlap_neighbors
|
Cap on overlap region size (number of nearest neighbours);
overrides |
40000
|
|
n_components
|
Number of HKS timescales. Timescales are log-spaced between
|
32
|
|
t_min
|
Minimum diffusion timescale. |
50000.0
|
|
t_max
|
Maximum diffusion timescale. |
20000000.0
|
|
max_eigenvalue
|
Maximum Laplacian eigenvalue used in the HKS computation. |
5e-06
|
|
robust
|
If |
True
|
|
mollify_factor
|
Mollification factor for the robust Laplacian. |
1e-05
|
|
truncate_extra
|
If |
True
|
|
drop_first
|
If |
True
|
|
decomposition_dtype
|
Floating-point dtype for the eigendecomposition. |
float64
|
|
compute_hks_kwargs
|
dict
|
Extra keyword arguments forwarded to compute_hks. |
{}
|
nuc_point
|
Coordinates of the nucleus/reference point. If provided, a
|
None
|
|
distance_threshold
|
Ward linkage-distance threshold used to cut the agglomeration tree into local domains. |
3.0
|
|
auxiliary_features
|
If |
True
|
|
n_jobs
|
Optional[int]
|
Number of parallel workers for Parallel. |
-1
|
verbose
|
Verbosity level. |
False
|
Returns:
| Type | Description |
|---|---|
Result
|
The mesh after simplification. |
Result
|
The mapping from the original mesh to the simplified mesh. Has length of the number of vertices in the original mesh; each element contains the index that the vertex maps to in the simplified mesh. |
Result
|
The mesh stitcher object. Contains information about the mesh chunks and their overlaps. |
Result
|
The HKS features for each vertex in the simplified mesh. |
Result
|
The aggregated HKS features for each domain in the mesh. |
Result
|
The labels for each vertex in the simplified mesh, indicating which domain it belongs to. |
Result
|
Timing information for each step of the pipeline. |
Notes
This pipeline consists of the following steps:
1. Mesh simplification, using https://github.com/pyvista/fast-simplification.
2. Mesh splitting, using a routine which iteratively does spectral bisection of
the mesh until all chunks are below the `max_vertex_threshold`. These chunks
are then grown to overlap using the `overlap_distance` parameter.
3. Computation of the heat kernel signature of Sun et al (2008). This routine
uses the robust laplacian of Crane et al. (2020) for more stable results. It
also leverages the band-by-band eigensolver method of Vallet and Levy (2008).
4. Agglomeration of the mesh into local domains which are bounded in the
variance of the HKS features. This uses the implementation of Ward's method
in scikit-learn which allows for a connectivity constraint.
5. Aggregation of the computed features to the local domains. This takes the
area-weighted mean of the features for each domain.
compute_condensed_hks(mesh, n_components=32, t_min=50000.0, t_max=20000000.0, max_eigenvalue=1e-05, robust=True, mollify_factor=1e-05, truncate_extra=True, drop_first=True, decomposition_dtype=np.float32, compute_hks_kwargs={}, distance_threshold=3.0)
¶
Compute HKS features and aggregate them on a single (unsplit) mesh.
This is a lightweight helper used internally by condensed_hks_pipeline to process individual submeshes. For large meshes, use the pipeline functions instead.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Input mesh accepted by interpret_mesh. |
required | |
n_components
|
Number of HKS timescales. |
32
|
|
t_min
|
Minimum diffusion timescale. |
50000.0
|
|
t_max
|
Maximum diffusion timescale. |
20000000.0
|
|
max_eigenvalue
|
Maximum Laplacian eigenvalue for the HKS computation. |
1e-05
|
|
robust
|
If |
True
|
|
mollify_factor
|
Mollification factor for the robust Laplacian. |
1e-05
|
|
truncate_extra
|
If |
True
|
|
drop_first
|
If |
True
|
|
decomposition_dtype
|
Floating-point dtype for the eigendecomposition. |
float32
|
|
compute_hks_kwargs
|
dict
|
Extra keyword arguments forwarded to compute_hks. |
{}
|
distance_threshold
|
Ward linkage-distance threshold for agglomeration. |
3.0
|
Returns:
| Name | Type | Description |
|---|---|---|
condensed_features |
DataFrame
|
Per-domain aggregated HKS feature DataFrame indexed by domain
label (including |
labels |
ndarray
|
Per-vertex domain label array of length |
condensed_hks_pipeline(mesh, simplify_agg=7, simplify_target_reduction=0.7, overlap_distance=20000, max_vertex_threshold=20000, min_vertex_threshold=200, max_overlap_neighbors=60000, n_components=32, t_min=50000.0, t_max=20000000.0, max_eigenvalue=1e-05, robust=True, mollify_factor=1e-05, truncate_extra=True, drop_first=True, decomposition_dtype='float32', compute_hks_kwargs={}, nuc_point=None, distance_threshold=3.0, auxiliary_features=True, n_jobs=-1, verbose=False)
¶
Compute HKS features and produce a condensed node-edge graph of a mesh.
This is the primary entry point for the HKS pipeline. It is more memory-efficient than chunked_hks_pipeline because features are aggregated within each submesh chunk before the results are combined, rather than stitching the full per-vertex feature matrix first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Input mesh. Either a |
required | |
simplify_agg
|
Decimation aggressiveness (0–10). Higher values are faster but
reduce mesh quality. Low values may prevent reaching
|
7
|
|
simplify_target_reduction
|
Fraction of triangles to remove during simplification. |
0.7
|
|
overlap_distance
|
Geodesic radius used to grow each chunk into its overlap region. |
20000
|
|
max_vertex_threshold
|
Maximum vertices per core chunk before overlapping. |
20000
|
|
min_vertex_threshold
|
Minimum component size; smaller components are discarded. |
200
|
|
max_overlap_neighbors
|
Cap on overlap region size (number of nearest neighbours);
overrides |
60000
|
|
n_components
|
Number of HKS timescales. Timescales are log-spaced between
|
32
|
|
t_min
|
Minimum diffusion timescale. |
50000.0
|
|
t_max
|
Maximum diffusion timescale. |
20000000.0
|
|
max_eigenvalue
|
Maximum Laplacian eigenvalue used in the HKS computation. |
1e-05
|
|
robust
|
If |
True
|
|
mollify_factor
|
Mollification factor for the robust Laplacian. |
1e-05
|
|
truncate_extra
|
If |
True
|
|
drop_first
|
If |
True
|
|
decomposition_dtype
|
Floating-point dtype for the eigendecomposition. |
'float32'
|
|
compute_hks_kwargs
|
dict
|
Extra keyword arguments forwarded to compute_hks. |
{}
|
nuc_point
|
Coordinates of the nucleus/reference point. If provided, a
|
None
|
|
distance_threshold
|
Ward linkage-distance threshold used to cut the agglomeration tree into local domains. |
3.0
|
|
auxiliary_features
|
If |
True
|
|
n_jobs
|
Optional[int]
|
Number of parallel workers for Parallel. |
-1
|
verbose
|
Verbosity level. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
simple_mesh |
CondensedHKSResult
|
The simplified mesh as a |
mapping |
CondensedHKSResult
|
Array of length |
stitcher |
CondensedHKSResult
|
Fitted MeshStitcher for the simplified mesh. |
simple_labels |
CondensedHKSResult
|
Per-vertex domain label array for the simplified mesh. |
labels |
CondensedHKSResult
|
Per-vertex domain label array for the original mesh. |
condensed_features |
CondensedHKSResult
|
Per-domain aggregated feature DataFrame (log-HKS + optional auxiliary features), indexed by domain label. |
condensed_nodes |
CondensedHKSResult
|
Node table of the condensed mesh graph; see condense_mesh_to_graph. |
condensed_edges |
CondensedHKSResult
|
Edge table of the condensed mesh graph. |
timing_info |
CondensedHKSResult
|
Dictionary with wall-clock times (seconds) for each pipeline step. |
Notes
This pipeline consists of the following steps:
- Mesh simplification via
fast-simplification. - Spectral bisection into overlapping chunks (MeshStitcher).
- Per-chunk: compute_hks, Ward agglomeration, and area-weighted aggregation (compute_condensed_hks). Aggregating before stitching keeps memory use proportional to the chunk size rather than the full mesh.
- Global label reconciliation across chunks (fix_split_labels).
- Assembly of the condensed node-edge graph (condense_mesh_to_graph).
meshmash.morphometry_pipeline
¶
component_morphometry_pipeline(mesh, labels, select_label, post_synapse_mappings=None, vertex_features=None, split_laplacian='graph', split_threshold=None, split_min_size=10, bound_volume_threshold=None, verbose=False)
¶
Measure morphometric properties of labeled mesh components.
For each connected component whose vertices carry select_label,
estimates volume, surface area, sphericity, PCA principal values, and
medoid position. Components may be recursively split by spectral
bisection if their Fiedler eigenvalue exceeds split_threshold.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Input mesh accepted by interpret_mesh. Vertex coordinates are expected to be in nanometres. |
required | |
labels
|
Per-vertex integer label array of length |
required | |
select_label
|
The label value whose components are to be measured. |
required | |
post_synapse_mappings
|
Array of vertex indices (length = number of known post-synapses).
If provided, a |
None
|
|
vertex_features
|
Reserved for future use; currently unused. |
None
|
|
split_laplacian
|
Laplacian variant used for spectral bisection when
|
'graph'
|
|
split_threshold
|
Fiedler eigenvalue threshold for recursive splitting. A component
is split into two sub-components when its Fiedler eigenvalue is
below this value (smaller Fiedler eigenvalue indicates a more
elongated / weakly connected component). |
None
|
|
split_min_size
|
Minimum number of vertices each split sub-component must have for the split to be accepted. |
10
|
|
bound_volume_threshold
|
If set, skip components whose axis-aligned bounding-box volume exceeds this value (in μm³). |
None
|
|
verbose
|
If |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
results |
DataFrame indexed by |
|
corrected_components |
Per-vertex component label array (same length as |
meshmash.decompose
¶
decompose_laplacian(L, M, n_components=100, op_inv=None, sigma=-1e-10, tol=1e-10, ncv=None, prefactor=None)
¶
Solve the generalised eigenvalue problem for a mesh Laplacian.
Computes the n_components smallest-magnitude eigenpairs of
:math:L \phi = \lambda M \phi using ARPACK shift-invert mode.
For small matrices the dense solver eigh is used
instead.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
L
|
sparray
|
Sparse cotangent-weight Laplacian matrix, shape |
required |
M
|
sparray
|
Sparse diagonal mass (area) matrix, shape |
required |
n_components
|
int
|
Number of smallest eigenvalues/eigenvectors to compute. |
100
|
op_inv
|
Optional[LinearOperator]
|
Pre-factored inverse operator to accelerate the ARPACK solve. If
|
None
|
sigma
|
float
|
Shift applied in shift-invert mode. A small negative value ensures the solver targets the smallest non-negative eigenvalues. |
-1e-10
|
tol
|
float
|
Convergence tolerance passed to eigsh. |
1e-10
|
ncv
|
Optional[int]
|
Number of Lanczos vectors. |
None
|
prefactor
|
Optional[str]
|
Pre-factorisation strategy. Currently only |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
eigenvalues |
ndarray
|
Array of eigenvalues sorted in ascending order, shape
|
eigenvectors |
ndarray
|
Array of corresponding eigenvectors, shape |
decompose_mesh(mesh, n_components=100, op_inv=None, sigma=-1e-10, tol=1e-10, robust=True, mollify_factor=1e-05, prefactor=None)
¶
Compute the Laplacian eigendecomposition of a mesh.
Builds the cotangent Laplacian and mass matrix with cotangent_laplacian, then delegates to decompose_laplacian.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh
|
Input mesh accepted by interpret_mesh. |
required |
n_components
|
int
|
Number of smallest eigenpairs to compute. |
100
|
op_inv
|
Optional[LinearOperator]
|
Pre-factored inverse operator; see decompose_laplacian. |
None
|
sigma
|
float
|
Shift for ARPACK shift-invert mode. |
-1e-10
|
tol
|
float
|
Convergence tolerance. |
1e-10
|
robust
|
bool
|
If |
True
|
mollify_factor
|
float
|
Mollification factor for the robust Laplacian. |
1e-05
|
prefactor
|
Optional[str]
|
Pre-factorisation strategy; see decompose_laplacian. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
eigenvalues |
ndarray
|
Sorted eigenvalues, shape |
eigenvectors |
ndarray
|
Corresponding eigenvectors, shape |
decompose_laplacian_by_bands(L, M, max_eigenvalue=1e-09, band_size=50, truncate_extra=True, verbose=False)
¶
Compute eigenpairs of a mesh Laplacian up to a maximum eigenvalue using a band-by-band approach.
Instead of computing all eigenpairs at once (which is slow for large
meshes), this routine incrementally solves bands of band_size
eigenpairs, advancing the ARPACK shift to stay near the frontier of
already-computed eigenvalues. The result is equivalent to calling
decompose_laplacian with a sufficiently large n_components
but uses less memory and is faster in practice.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
L
|
sparray
|
Sparse cotangent-weight Laplacian matrix, shape |
required |
M
|
sparray
|
Sparse diagonal mass (area) matrix, shape |
required |
max_eigenvalue
|
float
|
Stop once the largest computed eigenvalue exceeds this value. |
1e-09
|
band_size
|
int
|
Number of eigenpairs computed per ARPACK call. Does not affect the result, only performance. |
50
|
truncate_extra
|
bool
|
If |
True
|
verbose
|
Union[bool, int]
|
Verbosity level. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
eigenvalues |
ndarray
|
Sorted eigenvalues, shape |
eigenvectors |
ndarray
|
Corresponding eigenvectors, shape |
Notes
The band-shifting heuristic follows Section 4.1 of [1].
References
[1] B. Vallet and B. Levy, "Spectral Geometry Processing with Manifold Harmonics", Computer Graphics Forum, 27(2):251-260, 2008.
get_hks_filter(t_max=None, t_min=None, n_scales=32, dtype=np.float64)
¶
Build a heat-kernel spectral filter for use with spectral_geometry_filter.
Returns a callable that converts an array of Laplacian eigenvalues into a 2-D array of HKS filter coefficients.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
t_max
|
Optional[float]
|
Largest diffusion timescale. |
None
|
t_min
|
Optional[float]
|
Smallest diffusion timescale. |
None
|
n_scales
|
int
|
Number of timescales (= number of output HKS features). Scales
are spaced logarithmically between |
32
|
dtype
|
dtype
|
Floating-point dtype for the output coefficients. |
float64
|
Returns:
| Type | Description |
|---|---|
Callable[[ndarray], ndarray]
|
Callable that accepts a 1-D eigenvalue array of length |
construct_bspline_basis(e_min, e_max, n_components)
¶
Construct a set of B-spline basis functions spanning an eigenvalue range.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
e_min
|
float
|
Left boundary of the eigenvalue domain. |
required |
e_max
|
float
|
Right boundary of the eigenvalue domain. |
required |
n_components
|
int
|
Number of basis functions (= number of output geometry-vector features). |
required |
Returns:
| Type | Description |
|---|---|
list[BSpline]
|
List of |
construct_bspline_filter(e_min, e_max, n_components)
¶
Build a B-spline spectral filter for use with spectral_geometry_filter.
Creates a bank of n_components cubic B-spline basis functions
covering [e_min, e_max] via construct_bspline_basis and
wraps them in a callable that converts eigenvalues to filter
coefficients.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
e_min
|
float
|
Left boundary of the eigenvalue domain. |
required |
e_max
|
float
|
Right boundary of the eigenvalue domain. |
required |
n_components
|
int
|
Number of basis functions (= number of output features). |
required |
Returns:
| Type | Description |
|---|---|
Callable[[ndarray], ndarray]
|
Callable that accepts a 1-D eigenvalue array of length |
spectral_geometry_filter(mesh, filter=None, max_eigenvalue=1e-08, band_size=50, truncate_extra=True, drop_first=True, decomposition_dtype=np.float64, robust=True, mollify_factor=1e-05, point_laplacian=False, n_neighbors=30, verbose=False)
¶
Apply a spectral filter to the geometry of a mesh.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh
|
The input mesh. Must be a tuple of vertices and faces as arrays, or be an object
with a |
required |
filter
|
Optional[Callable[[ndarray], ndarray]]
|
A function that takes 1D array of eigenvalues, and returns a 2D array of filter coefficients, where the first dimension is the number of filters, and the second is the number of eigenvalues. If None, the eigenvectors and eigenvalues themselves will be returned, and no filtering will be applied. |
None
|
max_eigenvalue
|
float
|
The maximum eigenvalue to compute the eigendecomposition up to. |
1e-08
|
band_size
|
int
|
The number of eigenvalues to compute at a time using the band-by-band algorithm from [1]. This number should not affect the results, but may affect the speed. |
50
|
truncate_extra
|
bool
|
If True, truncate the filter to the max_eigenvalue exactly. Due the the band-by-band algorithm, the filter may overshoot the max_eigenvalue by at most one band. |
True
|
drop_first
|
bool
|
If True, drop the first eigenvalue and eigenvector. This should be 0 and the constant eigenvector scaled by vertex areas, so it is often not useful. |
True
|
robust
|
bool
|
If True, use the robust laplacian computation described in [2]. |
True
|
mollify_factor
|
float
|
The factor to use for the mollification when computing the robust laplacian. If robust is False, this parameter is ignored. |
1e-05
|
verbose
|
Union[bool, int]
|
If >0, print out additional information about the computation. Higher values give more information. |
False
|
Returns:
| Type | Description |
|---|---|
Union[ndarray, tuple[ndarray, ndarray]]
|
A 2D array of features, where the first dimension is the number of vertices, and the second is the number of features. |
Notes
Numerical errors are often due to a malformed mesh and therefore a malformed Laplacian. For this reason, it is recommended to use the robust Laplacian computation is used. Alternatively, make sure you are inputting a manifold mesh.
References
[1] Spectral Geometry Processing with Manifold Harmonics, Vallet and Levy, 2008 [2] A Laplacian for Nonmanifold Triangle Meshes, Sharp and Crane, 2020
compute_hks(mesh, max_eigenvalue=1e-08, t_max=None, t_min=None, n_components=32, band_size=50, truncate_extra=False, drop_first=False, robust=True, mollify_factor=1e-05, decomposition_dtype=np.float64, point_laplacian=False, n_neighbors=30, verbose=False)
¶
Compute the Heat Kernel Signature (HKS) for each vertex of a mesh.
The HKS is a multi-scale, intrinsic shape descriptor based on the
diagonal of the heat kernel at a set of diffusion timescales. It
captures local geometry from fine detail (small t) to global
structure (large t).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh
|
Input mesh accepted by interpret_mesh. |
required |
max_eigenvalue
|
float
|
Maximum Laplacian eigenvalue to include in the computation. Larger values capture finer geometric detail at increased cost. |
1e-08
|
t_min
|
Optional[float]
|
Smallest diffusion timescale. |
None
|
t_max
|
Optional[float]
|
Largest diffusion timescale. |
None
|
n_components
|
int
|
Number of diffusion timescales. Scales are spaced logarithmically
between |
32
|
band_size
|
int
|
Number of eigenpairs per ARPACK band; see spectral_geometry_filter. |
50
|
truncate_extra
|
bool
|
Whether to discard eigenpairs that overshoot |
False
|
drop_first
|
bool
|
If |
False
|
robust
|
bool
|
If |
True
|
mollify_factor
|
float
|
Mollification factor for the robust Laplacian. |
1e-05
|
decomposition_dtype
|
Optional[dtype]
|
Floating-point dtype for the eigendecomposition. |
float64
|
point_laplacian
|
bool
|
If |
False
|
n_neighbors
|
int
|
Number of neighbours used when |
30
|
verbose
|
Union[bool, int]
|
Verbosity level passed to spectral_geometry_filter. |
False
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Per-vertex HKS feature array of shape |
Notes
The band-by-band eigensolver from [1] is used for efficiency. The robust Laplacian from [2] is recommended for real-world meshes.
References
[1] J. Sun, M. Ovsjanikov, and L. Guibas, "A Concise and Provably Informative Multi-Scale Signature Based on Heat Diffusion", Computer Graphics Forum, 28(5):1383-1392, 2009. [2] N. Sharp and K. Crane, "A Laplacian for Nonmanifold Triangle Meshes", Computer Graphics Forum, 39(5), 2020.
compute_geometry_vectors(mesh, max_eigenvalue=1e-08, n_components=32, band_size=50, truncate_extra=False, drop_first=False, robust=True, mollify_factor=1e-05, decomposition_dtype=np.float64, verbose=False)
¶
Compute spectral geometry descriptors using a B-spline spectral filter.
Similar in spirit to compute_hks, but instead of heat-kernel exponentials the spectrum is partitioned by a bank of cubic B-spline basis functions. Each basis function acts as a band-pass filter, yielding one feature per vertex per band.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh
|
Input mesh accepted by interpret_mesh. |
required |
max_eigenvalue
|
float
|
Maximum Laplacian eigenvalue to include. Determines the upper boundary of the B-spline domain. |
1e-08
|
n_components
|
int
|
Number of B-spline basis functions (= number of output features per vertex). |
32
|
band_size
|
int
|
Number of eigenpairs per ARPACK band; see spectral_geometry_filter. |
50
|
truncate_extra
|
bool
|
Whether to discard eigenpairs that overshoot |
False
|
drop_first
|
bool
|
If |
False
|
robust
|
bool
|
If |
True
|
mollify_factor
|
float
|
Mollification factor for the robust Laplacian. |
1e-05
|
decomposition_dtype
|
Optional[dtype]
|
Floating-point dtype for the eigendecomposition. |
float64
|
verbose
|
Union[bool, int]
|
Verbosity level passed to spectral_geometry_filter. |
False
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Per-vertex geometry-vector feature array of shape
|
Notes
The B-spline filter bank follows [1].
References
[1] R. Litman and A. M. Bronstein, "Learning spectral descriptors for deformable shape correspondence", IEEE Transactions on Pattern Analysis and Machine Intelligence, 36(1):171-180, 2013.
meshmash.laplacian
¶
area_matrix(mesh)
¶
Compute the diagonal lumped-area matrix for a triangle mesh.
Each diagonal entry is the area associated with that vertex, approximated as one third of the sum of adjacent face areas.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh
|
Input mesh. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
M |
dia_array
|
Sparse diagonal area matrix of shape |
cotangent_laplacian(mesh, robust=False, mollify_factor=1e-05)
¶
Compute the cotangent Laplacian and lumped-area matrix for a triangle mesh.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh
|
Input mesh. |
required |
robust
|
bool
|
If |
False
|
mollify_factor
|
float
|
Mollification parameter passed to
|
1e-05
|
Returns:
| Name | Type | Description |
|---|---|---|
L |
csc_array
|
Sparse cotangent-weight stiffness matrix of shape |
M |
dia_array
|
Sparse diagonal lumped-area matrix of shape |
Notes
The robust Laplacian is described in:
[1] N. Sharp and K. Crane, "A Laplacian for Nonmanifold Triangle Meshes", Computer Graphics Forum (SGP), 39(5):69-80, 2020.
compute_vertex_areas(mesh, robust=False, mollify_factor=1e-05)
¶
Compute per-vertex areas for a triangle mesh.
A thin wrapper around cotangent_laplacian that returns only
the diagonal of the lumped-area matrix M.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh
|
Input mesh. |
required |
robust
|
bool
|
If |
False
|
mollify_factor
|
float
|
Mollification parameter forwarded to
cotangent_laplacian when |
1e-05
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Array of per-vertex areas of length |
meshmash.split
¶
MeshStitcher(mesh, verbose=False, n_jobs=-1)
¶
Split a mesh into overlapping chunks and apply functions across them.
Coordinates the full split-compute-stitch workflow:
- Call split_mesh to partition the mesh into overlapping submeshes.
- Call apply (or apply_on_features / subset_apply) to run a function on each submesh in parallel.
- Results are stitched back to the full mesh using stitch_features.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh
|
Input mesh accepted by interpret_mesh. |
required |
verbose
|
Union[bool, int]
|
Verbosity level. |
False
|
n_jobs
|
Optional[int]
|
Number of parallel workers for Parallel. |
-1
|
split_mesh(max_vertex_threshold=20000, min_vertex_threshold=100, overlap_distance=20000, max_rounds=100000, max_overlap_neighbors=None, verify_connected=True)
¶
Partition the mesh and build overlapping submesh chunks.
Calls fit_mesh_split to produce non-overlapping core
chunks, then expands each chunk by including all vertices
reachable within overlap_distance along mesh edges. The
resulting submeshes, their overlap vertex indices, and the
per-vertex submesh mapping are stored on self for use by
apply, apply_on_features, and
stitch_features.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
max_vertex_threshold
|
int
|
Maximum vertices per non-overlapping core chunk; passed to fit_mesh_split. |
20000
|
min_vertex_threshold
|
int
|
Minimum connected-component size; smaller components are discarded. |
100
|
overlap_distance
|
float
|
Maximum geodesic edge distance used to expand each core chunk into its overlapping neighbourhood. |
20000
|
max_rounds
|
int
|
Maximum bisection rounds; passed to fit_mesh_split. |
100000
|
max_overlap_neighbors
|
Optional[int]
|
If set, limits each chunk's overlap to at most this many
additional vertices (ranked by distance). |
None
|
verify_connected
|
bool
|
If |
True
|
Returns:
| Type | Description |
|---|---|
list[Mesh]
|
List of overlapping submeshes as |
stitch_features(features_by_submesh, fill_value=np.nan)
¶
Combine per-submesh feature arrays into a single full-mesh array.
Each vertex in the overlap region is covered by multiple submeshes.
This method assigns each vertex the value computed by the submesh
that "owns" it (i.e. submesh_mapping[vertex] == submesh_index).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
features_by_submesh
|
list[ndarray]
|
List of 2-D feature arrays, one per submesh, aligned to the
submesh vertex ordering. |
required |
fill_value
|
float
|
Value used to pre-fill the output array before writing submesh
results. Vertices in chunks where the function returned
|
nan
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Full-mesh feature array of shape |
apply(func, *args, fill_value=np.nan, stitch=True, **kwargs)
¶
Apply a function to each submesh and (optionally) stitch results.
func must have signature func(submesh, *args, **kwargs)
and return a 2-D array aligned to the submesh vertices, or
None to indicate failure.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
Callable[..., Any]
|
Callable to apply to each submesh. |
required |
*args
|
Positional arguments forwarded to |
()
|
|
fill_value
|
float
|
Fill value for uncomputed vertices; see stitch_features. |
nan
|
stitch
|
bool
|
If |
True
|
**kwargs
|
Keyword arguments forwarded to |
{}
|
Returns:
| Type | Description |
|---|---|
Union[ndarray, list]
|
Stitched full-mesh feature array of shape |
subset_apply(func, indices, *args, reindex=False, fill_value=np.nan, **kwargs)
¶
Apply a function only to submeshes that contain indices.
Useful when features are only needed for a subset of vertices;
submeshes that do not overlap with indices are skipped.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
Callable[..., Any]
|
Callable with signature |
required |
indices
|
ndarray
|
Vertex indices of interest. Only submeshes that contain at least one of these vertices are processed. |
required |
*args
|
Positional arguments forwarded to |
()
|
|
reindex
|
bool
|
If |
False
|
fill_value
|
float
|
Fill value for vertices whose submesh was not processed. |
nan
|
**kwargs
|
Keyword arguments forwarded to |
{}
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Full-mesh feature array of shape |
apply_on_features(func, X, *args, fill_value=np.nan, **kwargs)
¶
Apply a function that takes both a submesh and a feature slice.
Like apply, but also passes the slice of X corresponding
to each submesh as the second argument to func. The expected
signature is func(submesh, submesh_features, *args, **kwargs).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
Callable[..., Any]
|
Callable with signature
|
required |
X
|
ndarray
|
Full-mesh feature array of shape |
required |
*args
|
Additional positional arguments forwarded to |
()
|
|
fill_value
|
float
|
Fill value for uncomputed vertices. |
nan
|
**kwargs
|
Keyword arguments forwarded to |
{}
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Stitched full-mesh result array of shape |
graph_laplacian_split(adj, dtype=np.float32)
¶
Bisect a mesh using the Fiedler vector of the graph Laplacian.
Computes the second smallest eigenvector (Fiedler vector) of the unnormalised graph Laplacian and partitions vertices by the sign of their Fiedler coefficient.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
adj
|
csr_array
|
Sparse adjacency matrix of the mesh graph, shape |
required |
dtype
|
type
|
Floating-point dtype used for the eigensolver. |
float32
|
Returns:
| Name | Type | Description |
|---|---|---|
indices1 |
ndarray
|
Indices of vertices in the first partition (Fiedler coefficient >= 0). |
indices2 |
ndarray
|
Indices of vertices in the second partition (Fiedler coefficient < 0). |
bisect_adjacency(adj, n_retries=7, check=True)
¶
Bisect a mesh graph into two parts using the graph-Laplacian Fiedler vector.
Calls graph_laplacian_split and retries if the result is
degenerate (one empty partition or disconnected nodes). Uses
recursion up to n_retries times.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
adj
|
csr_array
|
Sparse adjacency matrix of shape |
required |
n_retries
|
int
|
Maximum number of retry attempts when the split fails to produce two non-empty, connected partitions. |
7
|
check
|
bool
|
If |
True
|
Returns:
| Name | Type | Description |
|---|---|---|
sub_adjs |
tuple[csr_array, csr_array]
|
Pair of sub-adjacency matrices |
submesh_indices |
tuple[ndarray, ndarray]
|
Pair of index arrays |
fit_mesh_split(mesh, max_vertex_threshold=20000, min_vertex_threshold=100, max_rounds=100000, verbose=False)
¶
Partition a mesh into non-overlapping chunks using recursive bisection.
Repeatedly bisects each chunk using the Fiedler vector of the graph
Laplacian until every chunk has at most max_vertex_threshold vertices.
Chunks belonging to connected components with fewer than
min_vertex_threshold vertices are dropped (their vertices receive
label -1). The returned labels are ordered so that the largest
chunk has label 0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Union[Mesh, ndarray, csr_array]
|
Input mesh, adjacency matrix, or vertex array accepted by interpret_mesh / mesh_to_adjacency. |
required |
max_vertex_threshold
|
int
|
Stop bisecting a chunk once it contains at most this many vertices. |
20000
|
min_vertex_threshold
|
int
|
Discard connected components with fewer than this many vertices;
their vertices receive label |
100
|
max_rounds
|
int
|
Maximum number of bisection steps before the algorithm terminates regardless of remaining chunk sizes. |
100000
|
verbose
|
Union[bool, int]
|
If truthy, print queue size every 50 rounds. |
False
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Per-vertex integer label array of shape |
bisect_laplacian(L, M)
¶
Bisect a mesh into two parts using the cotangent-Laplacian Fiedler vector.
Computes the second eigenvector of the generalised eigenproblem
L v = λ M v via decompose_laplacian
and partitions vertices by its sign.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
L
|
sparray
|
Cotangent Laplacian matrix of shape |
required |
M
|
sparray
|
Diagonal mass matrix of shape |
required |
Returns:
| Name | Type | Description |
|---|---|---|
sub_laps |
tuple[tuple[sparray, diags_array], tuple[sparray, diags_array]]
|
Pair of |
submesh_indices |
tuple[ndarray, ndarray]
|
Pair of index arrays |
fit_mesh_split_lap(mesh, max_vertex_threshold=20000, min_vertex_threshold=100, max_rounds=100000, robust=True, mollify_factor=1e-05, verbose=False)
¶
Partition a mesh into chunks using recursive cotangent-Laplacian bisection.
Like fit_mesh_split but uses the Fiedler vector of the cotangent Laplacian (instead of the graph Laplacian) for each bisection step, which can produce more geometrically uniform partitions on irregular meshes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Union[Mesh, ndarray, csr_array]
|
Input mesh accepted by interpret_mesh. |
required |
max_vertex_threshold
|
int
|
Stop bisecting a chunk once it contains at most this many vertices. |
20000
|
min_vertex_threshold
|
int
|
Discard connected components with fewer than this many vertices;
their vertices receive label |
100
|
max_rounds
|
int
|
Maximum number of bisection steps before the algorithm terminates. |
100000
|
robust
|
bool
|
If |
True
|
mollify_factor
|
float
|
Mollification factor passed to cotangent_laplacian. |
1e-05
|
verbose
|
Union[bool, int]
|
If truthy, print queue information each round. |
False
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Per-vertex integer label array of shape |
apply_mesh_split(mesh, split_mapping)
¶
Separate a mesh into submeshes according to a per-vertex split mapping.
Only faces whose all three vertices share the same label are retained in that submesh. Faces that span label boundaries are dropped.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh
|
Input mesh accepted by interpret_mesh. |
required |
split_mapping
|
ndarray
|
Per-vertex integer label array of length |
required |
Returns:
| Type | Description |
|---|---|
list[Mesh]
|
List of |
get_submesh_borders(submesh)
¶
Return the vertex indices that lie on boundary edges of a submesh.
Uses :mod:pyvista boundary-edge extraction to find edges shared by
fewer than two faces.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
submesh
|
Mesh
|
A manifold triangular mesh accepted by mesh_to_poly. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Sorted array of vertex indices located on boundary edges. |
fit_overlapping_mesh_split(mesh, overlap_distance=20000, vertex_threshold=20000, max_rounds=1000)
¶
Split a mesh and grow each chunk geodesically to create overlapping regions.
First calls fit_mesh_split to partition the mesh, then expands
each chunk by including all vertices reachable within overlap_distance
along mesh edges (using shortest-path distances).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh
|
Input mesh accepted by interpret_mesh. |
required |
overlap_distance
|
float
|
Maximum geodesic distance from the core chunk within which additional vertices are included in the overlap region. |
20000
|
vertex_threshold
|
int
|
Maximum number of vertices per non-overlapping core chunk passed to fit_mesh_split. |
20000
|
max_rounds
|
int
|
Maximum bisection rounds; see fit_mesh_split. |
1000
|
Returns:
| Type | Description |
|---|---|
list[ndarray]
|
List of vertex index arrays (one per chunk), each containing the core vertices plus their overlap neighbourhood. |
meshmash.graph
¶
compute_edge_widths(mesh, mollify_factor=0.0)
¶
Compute per-edge width estimates from the incircle radii of adjacent faces.
For each face the incircle radius is computed from Heron's formula, then that radius is accumulated onto the three edges of the face. The resulting value at each edge is a geometric proxy for the local "width" of the surface at that boundary.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh
|
Input mesh accepted by mesh_to_poly. |
required |
mollify_factor
|
float
|
Small additive offset applied to each edge length before computing face radii. Prevents division by zero on degenerate faces. |
0.0
|
Returns:
| Type | Description |
|---|---|
csr_array
|
Sparse CSR matrix of shape |
condense_mesh_to_graph(mesh, labels, add_component_features=False)
¶
Condense a vertex-labeled mesh into a node-edge graph representation.
Each unique label becomes a node; adjacent regions (labels that share at least one mesh edge) become connected by an edge. Edge weights reflect the total boundary length between regions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh
|
Input mesh accepted by mesh_to_poly. |
required |
labels
|
ndarray
|
Per-vertex integer label array of length |
required |
add_component_features
|
bool
|
If |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
node_table |
DataFrame
|
DataFrame indexed by label with columns |
edge_table |
DataFrame
|
DataFrame with columns |
meshmash.agglomerate
¶
multicut_ward(X, connectivity=None, distance_thresholds=None)
¶
Compute Ward cluster labels at multiple distance thresholds.
Builds the Ward linkage tree once with
ward_tree, then cuts it at each threshold in
distance_thresholds without rebuilding. This is more efficient
than fitting a separate AgglomerativeClustering
for each threshold.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
ArrayLike
|
Feature matrix of shape |
required |
connectivity
|
Optional[sparray]
|
Optional sparse connectivity matrix of shape |
None
|
distance_thresholds
|
Optional[list[float]]
|
List of linkage-distance thresholds at which to cut the tree. Each threshold yields one column in the output. |
None
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Integer label array of shape |
agglomerate_mesh(mesh, features, distance_thresholds=None)
¶
Apply connectivity-constrained Ward clustering to vertex features on a mesh.
Handles vertices with non-finite feature values by masking them out and
running clustering only on the valid sub-mesh, then filling -1 back
into the invalid positions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Input mesh accepted by interpret_mesh. |
required | |
features
|
Per-vertex feature matrix of shape |
required | |
distance_thresholds
|
Single threshold or list of thresholds passed to
multicut_ward. |
None
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Integer label array of shape |
fix_split_labels(agg_labels, submesh_mapping)
¶
Remap per-submesh local labels to globally unique integers.
When each submesh independently assigns cluster labels 0, 1, 2, …,
the same integer can refer to different clusters in different submeshes.
This function treats each (submesh_id, local_label) pair as a
unique cluster and remaps them to a single contiguous range
0, 1, 2, ….
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agg_labels
|
ndarray
|
Per-vertex label array of shape |
required |
submesh_mapping
|
ndarray
|
Per-vertex integer array of length |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Modified |
fix_split_labels_and_features(agg_labels, submesh_mapping, features_by_submesh)
¶
Remap per-submesh labels to globally unique integers and align feature DataFrames.
Like fix_split_labels, but also re-indexes the per-submesh feature DataFrames so that their row indices match the new global label integers and concatenates them into a single DataFrame.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agg_labels
|
ndarray
|
Per-vertex label array of length |
required |
submesh_mapping
|
ndarray
|
Per-vertex integer array of length |
required |
features_by_submesh
|
list[DataFrame]
|
List of per-submesh feature DataFrames, one per submesh, indexed by local cluster label. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
agg_labels |
ndarray
|
Modified |
condensed_features |
DataFrame
|
Concatenated feature DataFrame indexed by global label, including
a row for the null label |
agglomerate_split_mesh(splitter, features, distance_thresholds)
¶
Apply Ward clustering across submeshes and return globally unique labels.
Applies agglomerate_mesh to each submesh via MeshStitcher.apply_on_features, then calls fix_split_labels to make the cluster labels globally unique across all submeshes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
splitter
|
MeshStitcher
|
A fitted MeshStitcher. |
required |
features
|
ndarray
|
Per-vertex feature matrix of shape |
required |
distance_thresholds
|
Union[list, int, float]
|
Single threshold or list of thresholds passed to multicut_ward. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Integer label array of shape |
aggregate_features(features, labels=None, weights=None, func='mean')
¶
Aggregate per-vertex features to per-label summaries.
Groups vertices by labels and applies func (or an
area-weighted mean when weights is provided) to produce one row
per unique label. The result is reindexed to include every integer
from -1 to labels.max(), inserting NaN for any missing
labels.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
features
|
Union[ndarray, DataFrame]
|
Per-vertex feature matrix of shape |
required |
labels
|
Optional[ndarray]
|
Integer label array of length |
None
|
weights
|
Optional[ndarray]
|
Per-vertex weight array of length |
None
|
func
|
str
|
Aggregation function name recognised by
DataFrameGroupBy.agg (e.g. |
'mean'
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame of shape |
blow_up_features(agg_features_df, labels)
¶
Expand per-label aggregated features back to per-vertex features.
Inverse of aggregate_features. Looks up each vertex's label
in agg_features_df to produce a per-vertex DataFrame.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agg_features_df
|
DataFrame
|
Per-label feature DataFrame indexed by label integer, as returned by aggregate_features. |
required |
labels
|
ndarray
|
Per-vertex label array of length |
required |
Returns:
| Type | Description |
|---|---|
DataFrame
|
Per-vertex feature DataFrame of shape |
meshmash.utils
¶
mesh_to_poly(mesh)
¶
mesh_to_edges(mesh)
¶
Extract all edges from a mesh as vertex index pairs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh
|
Input mesh accepted by mesh_to_poly. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Array of edge vertex index pairs, shape |
mesh_to_adjacency(mesh)
¶
Build a sparse weighted adjacency matrix from a mesh.
Edge weights are Euclidean edge lengths. The returned matrix is upper triangular (each undirected edge appears once).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh
|
Input mesh accepted by mesh_to_poly. |
required |
Returns:
| Type | Description |
|---|---|
csr_array
|
Sparse CSR adjacency matrix of shape |
poly_to_mesh(poly)
¶
fix_mesh(mesh, **kwargs)
¶
Repair a mesh using :mod:pymeshfix.
Attempts to close holes and remove self-intersections so that the result is a manifold surface. Additional keyword arguments are forwarded to MeshFix.repair.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh
|
Input mesh accepted by mesh_to_poly. |
required |
**kwargs
|
Keyword arguments forwarded to MeshFix.repair. |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
vertices |
Mesh
|
Array of repaired vertex positions, shape |
faces |
Mesh
|
Array of repaired triangle face indices, shape |
project_points_to_mesh(points, mesh, distance_threshold=None, return_distances=False)
¶
project_points_to_mesh(
points: ArrayLike,
mesh: Mesh,
distance_threshold: Optional[float] = None,
return_distances: Literal[False] = ...,
) -> np.ndarray
project_points_to_mesh(
points: ArrayLike,
mesh: Mesh,
distance_threshold: Optional[float] = None,
*,
return_distances: Literal[True],
) -> tuple[np.ndarray, np.ndarray]
Find the nearest mesh vertex for each query point.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
points
|
ArrayLike
|
Query point coordinates, shape |
required |
mesh
|
Mesh
|
Target mesh accepted by mesh_to_poly. |
required |
distance_threshold
|
Optional[float]
|
If provided, query points whose nearest vertex is farther than this
distance are assigned an index of |
None
|
return_distances
|
bool
|
If |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
indices |
Union[ndarray, tuple[ndarray, ndarray]]
|
Indices of the nearest vertex in the mesh for each query point,
shape |
distances |
Union[ndarray, tuple[ndarray, ndarray]]
|
Only returned when |
component_size_transform(mesh, indices=None)
¶
Return the connected-component size for each vertex.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh
|
Input mesh accepted by mesh_to_poly. |
required |
indices
|
Optional[ndarray]
|
Subset of vertex indices to return sizes for. If |
None
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Array of component sizes (number of vertices in the same connected
component), one value per entry in |
get_label_components(mesh, labels)
¶
Label connected components of a mesh that share the same vertex label.
Two vertices belong to the same component only if they are connected by an edge and carry the same label value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh
|
Input mesh accepted by mesh_to_poly. |
required |
labels
|
ArrayLike
|
Per-vertex label array of length |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Per-vertex component label array of length |
subset_mesh_by_indices(mesh, indices)
¶
Extract a submesh containing only the specified vertices.
Only faces whose all three vertices are in indices are kept.
Face indices are remapped to the new, compact vertex numbering.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh
|
Input mesh accepted by interpret_mesh. |
required |
indices
|
ndarray
|
Vertex indices to keep, or a boolean mask of length |
required |
Returns:
| Name | Type | Description |
|---|---|---|
vertices |
Mesh
|
Subset of vertex positions, shape |
faces |
Mesh
|
Remapped face index array containing only retained faces. |
rough_subset_mesh_by_indices(mesh, indices)
¶
Extract a submesh keeping faces where any vertex is in indices.
Unlike subset_mesh_by_indices, a face is retained whenever at
least one of its vertices is in indices. This can introduce
additional vertices beyond those in indices.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh
|
Input mesh accepted by interpret_mesh. |
required |
indices
|
ndarray
|
Seed vertex indices. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
submesh |
Mesh
|
|
vertex_indices |
ndarray
|
Final set of vertex indices (in the original mesh) that were
included, which may be a superset of |
largest_mesh_component(mesh)
¶
Return the largest connected component of a mesh.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh
|
Input mesh. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
vertices |
Mesh
|
Vertices of the largest component. |
faces |
Mesh
|
Faces of the largest component, with remapped indices. |
shuffle_label_mapping(x)
¶
Randomly permute integer labels while preserving the set of label values.
Useful for randomising colours when visualising label arrays.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
ArrayLike
|
Array of integer labels. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Array of the same shape as |
compute_distances_to_point(points, center_point)
¶
Compute the Euclidean distance from each point to a reference point.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
points
|
ArrayLike
|
Query point coordinates, shape |
required |
center_point
|
ArrayLike
|
Reference point, shape |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Array of distances, shape |
edges_to_lines(edges)
¶
Convert an edge array to a :mod:pyvista lines connectivity array.
:mod:pyvista encodes lines as a flat array where each cell is
prefixed by its vertex count. This function prepends 2 to each
edge so the result can be passed directly to
PolyData.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
edges
|
ndarray
|
Edge vertex index pairs, shape |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Flat connectivity array of length |
combine_meshes(meshes)
¶
Concatenate a list of meshes into a single mesh.
Vertex arrays are stacked and face index arrays are shifted so that each submesh's faces still point to the correct vertices.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
meshes
|
list[Mesh]
|
List of meshes accepted by interpret_mesh. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
vertices |
Mesh
|
Combined vertex array. |
faces |
Mesh
|
Combined face index array with adjusted indices. |
mesh_connected_components(mesh, size_threshold=100, sort_by_size=False)
¶
Yield each connected component of a mesh as a separate mesh.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh
|
Input mesh. |
required |
size_threshold
|
Optional[int]
|
Minimum number of vertices a component must have to be yielded.
Set to |
100
|
sort_by_size
|
bool
|
If |
False
|
Yields:
| Type | Description |
|---|---|
Mesh
|
|
mesh_n_connected_components(mesh)
¶
Return the number of connected components in a mesh.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh
|
Input mesh. |
required |
Returns:
| Type | Description |
|---|---|
int
|
Number of connected components. |
threshold_mesh_by_component_size(mesh, size_threshold=100)
¶
Remove connected components smaller than a vertex-count threshold.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh
|
Input mesh. |
required |
size_threshold
|
int
|
Minimum number of vertices a component must have to be retained. |
100
|
Returns:
| Name | Type | Description |
|---|---|---|
mesh |
Mesh
|
Filtered |
indices |
ndarray
|
Indices of the retained vertices in the original mesh, shape
|
expand_labels(condensed_labels, mapping)
¶
Expand per-vertex labels from a reduced mesh back to the original mesh.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
condensed_labels
|
ndarray
|
Per-vertex label array for the simplified/reduced mesh, shape
|
required |
mapping
|
ndarray
|
Array of length |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Per-vertex label array for the original mesh, shape
|
graph_to_adjacency(graph)
¶
Convert a (vertices, edges) graph tuple to an unweighted adjacency matrix.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
graph
|
tuple[ndarray, ndarray]
|
Tuple of |
required |
Returns:
| Type | Description |
|---|---|
csr_array
|
Sparse CSR adjacency matrix of shape |
scale_mesh(mesh, scale)
¶
Return a new mesh with all vertex positions scaled by scale.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh
|
Input mesh accepted by interpret_mesh. |
required |
scale
|
float
|
Scalar factor to multiply all vertex coordinates by. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
vertices |
Mesh
|
Scaled vertex positions. |
faces |
Mesh
|
Unchanged face index array. |
meshmash.io
¶
interpret_path(path, **kwargs)
¶
Parse a path into a cloudfiles.CloudFiles handle and filename.
Supports local paths as well as cloud storage URIs such as gs://
and file://.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Union[str, Path]
|
Path to a file or directory. If the path has no file extension, it
is treated as a directory and the returned filename is |
required |
**kwargs
|
Additional keyword arguments forwarded to
|
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
cf |
CloudFiles
|
|
file_name |
Optional[str]
|
The base filename, or |
save_condensed_features(path, features, labels, feature_dtype=np.float32, label_dtype=np.int32, check_header=True)
¶
Save per-label features and per-vertex labels to a compressed .npz file.
A header.txt file containing tab-separated column names is written
alongside the data file (or validated against an existing one when
check_header=True).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Union[str, Path]
|
Destination file path (local or |
required |
features
|
DataFrame
|
DataFrame of per-label features. Rows should be indexed
|
required |
labels
|
ndarray
|
Per-vertex label array mapping each vertex to a row index in
|
required |
feature_dtype
|
type
|
Numeric dtype used to store the feature values. |
float32
|
label_dtype
|
type
|
Numeric dtype used to store the label array. |
int32
|
check_header
|
bool
|
If |
True
|
read_condensed_features(path)
¶
Load per-label features and per-vertex labels from a file written by save_condensed_features.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Union[str, Path]
|
Path to the |
required |
Returns:
| Name | Type | Description |
|---|---|---|
features |
DataFrame
|
DataFrame of per-label features indexed |
labels |
ndarray
|
Per-vertex label array. |
save_condensed_edges(path, edges, check_header=True)
¶
Save a condensed edge table to a compressed .npz file.
The source and target columns are stored as int32; all
remaining columns are stored as float32.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Union[str, Path]
|
Destination file path (local or |
required |
edges
|
DataFrame
|
DataFrame with at least |
required |
check_header
|
bool
|
If |
True
|
read_condensed_edges(path)
¶
save_condensed_graph(path, nodes, edges, nodes_dtype=np.float32, edges_dtype=np.int32, check_header=True)
¶
Save both the condensed node and edge tables to a single .npz file.
Column names for each table are written to separate header files
(nodes_header.txt and edges_header.txt) in the same directory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Union[str, Path]
|
Destination file path (local or |
required |
nodes
|
DataFrame
|
DataFrame of per-label node features indexed |
required |
edges
|
DataFrame
|
DataFrame of inter-label edge features. |
required |
nodes_dtype
|
type
|
Numeric dtype used for the node feature values. |
float32
|
edges_dtype
|
type
|
Numeric dtype used for the edge values. |
int32
|
check_header
|
bool
|
If |
True
|
read_condensed_graph(path)
¶
Load node and edge tables from a file written by save_condensed_graph.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Union[str, Path]
|
Path to the |
required |
Returns:
| Name | Type | Description |
|---|---|---|
nodes |
DataFrame
|
DataFrame of per-label node features. |
edges |
DataFrame
|
DataFrame of inter-label edge features. |
save_id_to_mesh_map(path, id_to_mesh_map)
¶
read_id_to_mesh_map(path)
¶
Load a mapping array from a file written by save_id_to_mesh_map.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Union[str, Path]
|
Path to the |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Integer array of shape |
save_array(path, array)
¶
meshmash.datasets
¶
Sample datasets for meshmash.
Use pip install meshmash[datasets] to enable downloading.
fetch_sample_mesh(name='microns_dendrite_sample')
¶
Download (once) and return a sample mesh as (vertices, faces).
The file is cached in the OS-appropriate user cache directory
(e.g. ~/.cache/meshmash on Linux/macOS) and reused on subsequent calls.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Dataset name, without file extension. Available meshes:
|
'microns_dendrite_sample'
|
Returns:
| Name | Type | Description |
|---|---|---|
vertices |
(ndarray, shape(V, 3))
|
Vertex positions. |
faces |
(ndarray, shape(F, 3))
|
Triangle face indices. |
Examples:
>>> from meshmash import fetch_sample_mesh
>>> vertices, faces = fetch_sample_mesh()
>>> vertices.shape
(N, 3)
meshmash.types
¶
interpret_mesh(mesh)
¶
Normalize a mesh input to a (vertices, faces) tuple.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Either a |
required |
Returns:
| Name | Type | Description |
|---|---|---|
vertices |
ndarray
|
Array of vertex positions, shape |
faces |
ndarray
|
Array of triangle face indices, shape |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
meshmash.wrap
¶
wrap_mesh(input_mesh, alpha=250.0, offset=5.0, alpha_fraction=None, offset_fraction=None)
¶
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
alpha
|
float
|
Ball size in physical (mesh) units. If provided, overrides alpha_fraction. |
250.0
|
offset
|
float
|
Offset distance in physical (mesh) units. If provided, overrides offset_fraction. |
5.0
|
alpha_fraction
|
float
|
Ball size as a fraction of the largest bounding-box diagonal (used when alpha is None). |
None
|
offset_fraction
|
float
|
Offset distance as a fraction of the largest bounding-box diagonal (used when offset is None). |
None
|