Overview
Mesh splitting is a fundamental operation for processing large meshes that exceed memory or computational limits. MeshMash uses spectral bisection based on the graph Laplacian to recursively divide meshes into balanced submeshes while preserving connectivity. TheMeshStitcher class provides a powerful workflow for splitting meshes with optional overlaps, applying operations in parallel, and stitching results back together.
Basic Splitting
The splitting algorithm uses the second eigenvector of the graph Laplacian (Fiedler vector) to partition vertices into two groups. This process repeats recursively until all submeshes are below the threshold.
Overlapping Splits
For operations that require local context (like smoothing or diffusion), create overlapping submeshes:overlap_distance parameter extends each submesh to include neighboring vertices within the specified geodesic distance from the border. This ensures operations don’t create artifacts at submesh boundaries.
Applying Functions to Submeshes
Once split, apply any function to all submeshes in parallel:stitcher.apply(func, *args, fill_value=np.nan, stitch=True, **kwargs) -> np.ndarray
Working with Features on Submeshes
If you have features defined on the original mesh and want to apply a function that uses both the submesh geometry and features:stitcher.apply_on_features(func, X, *args, fill_value=np.nan, **kwargs) -> np.ndarray
The stitcher automatically maps features from the full mesh to each submesh, handles overlaps, and stitches results back to the original vertex ordering.
Understanding the Mapping
The stitcher maintains important mappings:stitcher.submesh_mapping: Array of shape(n_vertices,)mapping each vertex to its submesh ID (or -1 if excluded)stitcher.submesh_overlap_indices: List wheresubmesh_overlap_indices[i]contains vertex indices from the original mesh included in submeshistitcher.submeshes: List of submesh tuples with overlaps
Advanced: Cotangent Laplacian Splitting
For more geometrically-aware splitting, use the cotangent Laplacian instead of the graph Laplacian:mesh:Union[Mesh, np.ndarray, csr_array]- Input mesh or adjacency matrixmax_vertex_threshold:int- Maximum vertices per submeshmin_vertex_threshold:int- Minimum vertices to consider splittingrobust:bool- Use robust cotangent Laplacian (recommended for non-manifold meshes)mollify_factor:float- Numerical mollification factor
np.ndarray - Shape (n_vertices,) with submesh labels
Performance Considerations
- Vertex threshold: Smaller submeshes mean more parallelism but more overhead. 10,000-50,000 vertices per submesh is typically optimal.
- Overlap distance: Larger overlaps ensure better local context but increase memory usage and computation.
- Parallel jobs: Set
n_jobs=-1to use all cores, or specify a number to limit parallelism.