---
title: secondmouseau/swiftmeshheal
framework: Swift Package Catalog
role: article
path: packages/secondmouseau/swiftmeshheal
---

# secondmouseau/swiftmeshheal

On-device, **dependency-free** triangle-mesh healing in pure Swift — turn broken / non-watertight STL

## Why

Mesh-repair tools that "just work" (Netfabb, Polygonica, fTetWild, CGAL alpha-wrapping) are either paid, GPL, server-side, or too heavy / too slow to embed in a shipping app — and the robust volumetric ones **weld intended openings shut** (a railcar's windows) and remesh away the original triangulation. SwiftMeshHeal is a feature-preserving *local* healer: it fills defect holes, leaves intended openings open, never moves existing geometry, and runs in milliseconds per body.

## What it does

```swift import SwiftMeshHeal

var mesh = MeshHeal(positions: positions, indices: indices)   // welded, indexed triangles let healed = mesh.tier1Healed().mesh                          // closed, manifold (where solidifiable) ```

`tier1Healed()`: 1. removes internal-membrane faces (generalized winding number) and duplicate / degenerate faces, 2. resolves non-manifold edges (iterated), 3. fills every boundary loop with **Liepa (2003) minimum-dihedral** triangulation — handling non-planar    holes, forbidding diagonals that collide with existing edges, and fanning from a fresh vertex for    slits/cracks, 4. passes degenerate zero-thickness sheets through unchanged (not solidifiable).

### Preserving intended openings

A part's missing back is a *defect* (fill it); a shell's window is an *opening* (keep it). Pass a predicate to protect genuine through-openings:

```swift let skip = mesh.throughOpeningSkip()          // real area + ray clears space both sides = an opening let healed = mesh.tier1Healed(skipLoop: skip).mesh ```

`throughOpeningSkip()` reads vertex positions, and healing grows the mesh as it fills, so for multi-hole shells prefer the factory form — it re-derives the predicate against the mesh as it evolves:

```swift let healed = mesh.tier1Healed(skipLoopFor: { $0.throughOpeningSkip() }).mesh ```

## API surface

- `MeshHeal(positions:indices:)`, `isWatertight`, `enclosedVolume`, `surfaceArea`, `pcaExtents`, `bounds` - `boundaryLoops()`, `nonManifoldEdgeCount`, `resolveNonManifoldEdges()`, `removingDuplicateFaces()` - `repairedManifold()`, `generalizedWindingNumber(_:)`, `firstRayHit(origin:direction:)` - `liepaFill(loop:bndNormals:existingEdges:)`, `filledHoles(skipLoop:)`, `tier1Healed(skipLoop:)`, `tier1Healed(skipLoopFor:)` - `throughOpeningSkip(minArea:clearDist:)`, `isDegenerateSheet`

## Validation

On a 278k-triangle, 3946-body STL (a 1:80 railcar), `tier1Healed` closes **99.8%** of solidifiable bodies to watertight, ~ms/body, non-destructively (0 mm distortion of existing geometry), while preserving the shell's through-openings.

## License

MIT.

## Package Metadata

Repository: secondmouseau/swiftmeshheal

Default branch: main

README: README.md
