spectralbrain.core.meshes#

Triangle mesh representation and mesh-specific geometric analysis.

Provides BrainMesh, the primary mesh container, which implements GeometricObject and owns the Laplacian construction + eigendecomposition pipeline.

Also provides standalone functions for mesh-specific geometry that cannot be computed on unstructured point clouds: cotangent Laplacian, angle-defect Gaussian curvature, heat-method geodesics, Euler characteristic, etc.

Dependencies#

  • robust_laplacian — optional, for the Sharp–Crane tufted Laplacian (recommended on non-manifold meshes).

Classes

BrainMesh(vertices, faces[, metadata])

Triangle surface mesh for brain structures.

class spectralbrain.core.meshes.BrainMesh(vertices, faces, metadata=None)[source]#

Bases: object

Triangle surface mesh for brain structures.

Implements the GeometricObject protocol and provides the Laplacian construction → eigendecomposition → descriptor pipeline.

Parameters:
  • vertices (ndarray, shape (N, 3)) – Vertex coordinates in mm.

  • faces (ndarray, shape (F, 3)) – Triangle indices, 0-indexed.

  • metadata (dict, optional) – Provenance (subject, hemisphere, structure, …).

Examples

>>> verts, faces = sb.io.load_freesurfer_surface("lh.white")
>>> mesh = BrainMesh(verts, faces, metadata={"structure": "cortex"})
>>> decomp = mesh.decompose(k=100)
boundary_vertices()[source]#

Indices of boundary (non-manifold edge) vertices.

Returns:

ndarray of int – Vertex indices on the mesh boundary.

Return type:

ndarray

casorati_curvature()[source]#

Casorati curvature — identical to curvedness.

K_C = √((κ₁² + κ₂²) / 2)

Preferred over mean/Gaussian curvature for complexity quantification (Matsuyama et al. 2023).

Returns:

ndarray, shape (N,)

Return type:

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

compute_laplacian(method='cotangent', *, robust_mollify_factor=1e-05)[source]#

Construct the Laplacian and mass matrix.

Parameters:
  • method (str) – "cotangent" — FEM cotangent-weighted Laplacian with Voronoi-area mass matrix (Meyer–Desbrun–Schröder–Barr). "robust" — Sharp & Crane tufted Laplacian via robust_laplacian (handles non-manifold edges).

  • robust_mollify_factor (float) – Mollification parameter for the robust method.

Returns:

  • L (SparseMatrix, shape (N, N)) – Stiffness (Laplacian) matrix — symmetric positive semi-definite.

  • M (MassMatrix, shape (N, N)) – Diagonal mass matrix.

Return type:

tuple[spmatrix, spmatrix]

compute_normals()[source]#

Compute area-weighted per-vertex normals from face topology.

Returns:

normals (ndarray, shape (N, 3)) – Unit normals.

Return type:

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

curvedness()[source]#

Koenderink Curvedness C ≥ 0.

C = √((κ₁² + κ₂²) / 2)

Returns:

ndarray, shape (N,)

Return type:

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

decompose(k=100, *, laplacian_method='cotangent', backend=None, **eigsh_kwargs)[source]#

Compute the spectral decomposition.

Parameters:
  • k (int) – Number of eigenpairs to compute.

  • laplacian_method (str) – Passed to compute_laplacian().

  • backend (Backend, optional) – Compute backend. Defaults to NumpyBackend.

  • **eigsh_kwargs – Extra arguments to backend.eigsh().

Returns:

SpectralDecomposition

Return type:

SpectralDecomposition

edge_lengths()[source]#

All edge lengths.

Returns:

ndarray, shape (E,)

Return type:

ndarray

euler_characteristic()[source]#

Euler characteristic χ = V − E + F.

Returns:

int

Return type:

int

gaussian_curvature()[source]#

Gaussian curvature via angle defect (Descartes–Euler).

K(v) = (2π − Σ θ_j) / A(v)

where θ_j are the face angles at vertex v and A(v) is the Voronoi area.

Returns:

ndarray, shape (N,) – Gaussian curvature in 1/mm².

Return type:

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

genus()[source]#

Genus g from χ = 2 − 2g (closed surfaces).

Returns:

int

Return type:

int

geodesic_distance(source_indices, *, method='heat', t_factor=1.0)[source]#

Geodesic distance from source vertices to all others.

Parameters:
  • source_indices (ndarray) – Indices of source vertices.

  • method (str) – "heat" — Crane et al. heat method (smooth, O(N)). "dijkstra" — graph shortest path on edge graph (exact on graph, O(N log N)).

  • t_factor (float) – For the heat method: time-step multiplier relative to the squared mean edge length.

Returns:

distances (ndarray, shape (N,)) – Geodesic distance from the closest source vertex.

Return type:

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

is_closed()[source]#

True if the mesh has no boundary.

Return type:

bool

laplacian_smooth(n_iterations=10, step_size=0.5)[source]#

Laplacian smoothing (uniform weights).

Parameters:
  • n_iterations (int)

  • step_size (float) – Damping factor (0–1).

Returns:

BrainMesh – New mesh with smoothed vertices.

Return type:

BrainMesh

mean_curvature()[source]#

Mean curvature via the Laplacian (Hn = ΔX / 2).

Requires the cotangent Laplacian and mass matrix.

Returns:

ndarray, shape (N,) – Mean curvature (signed) in 1/mm.

Return type:

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

principal_curvatures()[source]#

Principal curvatures κ₁ ≥ κ₂ from H and K.

κ₁ = H + √(H² − K), κ₂ = H − √(H² − K)

Returns:

  • kappa1 (ndarray, shape (N,))

  • kappa2 (ndarray, shape (N,))

Return type:

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

quality_report()[source]#

Mesh quality summary.

Returns:

dict – Keys: n_vertices, n_faces, n_edges, euler, genus, is_closed, area, edge_length_{min,mean,max,std}, valence_{min,mean,max}, n_boundary_vertices.

Return type:

dict[str, Any]

shape_index()[source]#

Koenderink Shape Index S ∈ [−1, +1].

S = (2/π) · arctan((κ₂ + κ₁) / (κ₂ − κ₁))

Returns:

ndarray, shape (N,)

Return type:

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

surface_area()[source]#

Total surface area in mm².

Return type:

float

taubin_smooth(n_iterations=10, lambda_=0.5, mu=-0.53)[source]#

Taubin smoothing (shrinkage-free).

Alternates positive and negative smoothing steps to avoid the volume shrinkage of pure Laplacian smoothing.

Parameters:
  • n_iterations (int) – Number of (λ, μ) cycles.

  • lambda (float) – Positive smoothing factor.

  • mu (float) – Negative (inflation) factor. Must satisfy mu < -lambda_ for shrinkage-free behaviour.

  • lambda_ (float)

Returns:

BrainMesh

Return type:

BrainMesh

vertex_areas(method='barycentric')[source]#

Per-vertex area (Voronoi or barycentric lumped).

Parameters:

method (str) – "barycentric" — A(v) = Σ_{t∈star(v)} area(t) / 3. "voronoi" — mixed Voronoi–barycentric (Meyer et al.).

Returns:

ndarray, shape (N,)

Return type:

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

vertex_valence()[source]#

Number of edges incident to each vertex.

Returns:

ndarray, shape (N,), int

Return type:

ndarray

willmore_density()[source]#

Local Willmore energy density H²(v).

The integral ∫ H² dA is the Willmore energy — conformally invariant, measures deviation from a sphere.

Returns:

ndarray, shape (N,)

Return type:

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

willmore_energy()[source]#

Total Willmore energy ∫ H² dA.

Returns:

float

Return type:

float

property coordinates: ndarray[tuple[Any, ...], dtype[floating]]#

Return the vertex coordinates array.

property n_faces: int#

Return the number of triangular faces.

property n_points: int#

Return the number of vertices (alias for n_vertices).

property n_vertices: int#

Return the number of vertices in the mesh.