Metadata-Version: 2.4
Name: mesh-skeleton
Version: 1.0.2
Summary: Extract connected skeletal graphs (centerlines) from 3D meshes
Author-email: Salvatore Esposito <salvatore.esp95@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/iamsalvatore/mesh-skeleton
Project-URL: Repository, https://github.com/iamsalvatore/mesh-skeleton
Project-URL: Issues, https://github.com/iamsalvatore/mesh-skeleton/issues
Keywords: mesh,skeleton,centerline,medial-axis,graph,3d,geometry,voxel,skeletonization,medical-imaging
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Scientific/Engineering :: Image Processing
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
Classifier: Topic :: Scientific/Engineering :: Visualization
Classifier: Topic :: Multimedia :: Graphics :: 3D Modeling
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy
Requires-Dist: scipy
Requires-Dist: trimesh
Requires-Dist: scikit-image
Requires-Dist: matplotlib
Requires-Dist: networkx
Requires-Dist: tqdm
Provides-Extra: gpu
Requires-Dist: torch; extra == "gpu"
Dynamic: license-file

# Mesh Skeleton

Extract connected skeletal graphs from 3D meshes. Unlike point-cloud skeletons, this tool preserves full connectivity as a NetworkX graph — enabling direct path traversal, branch analysis, and navigation.

<p align="center">
  <img src="https://raw.githubusercontent.com/iamsalvatore/mesh-skeleton/main/assets/hero_lung_skeleton.png" alt="Airway tree mesh next to its medial-axis skeleton graph" width="860">
  <br>
  <em>Left: 3D bronchial-tree surface (49k verts / 100k faces). Right: the medial-axis skeleton extracted by <code>mesh-skeleton</code> — 2,625 centerline nodes, 2,664 edges, 97 endpoints (orange), 171 junctions (yellow). Same viewpoint, same scale.</em>
</p>

## Installation

```bash
pip install mesh-skeleton
```

Or from source:

```bash
git clone https://github.com/iamsalvatore/mesh-skeleton.git
cd mesh-skeleton
pip install -e .
```

## Quick Start

### Command Line

```bash
python -m mesh_skeleton input_mesh.obj                          # basic extraction
python -m mesh_skeleton input_mesh.stl -o skeleton.ply -r 256   # custom resolution
python -m mesh_skeleton input_mesh.obj --no_viz                 # skip visualization
```

### Python API

```python
import trimesh
from mesh_skeleton import SkeletonExtractor

mesh = trimesh.load('model.obj')
extractor = SkeletonExtractor(mesh, voxel_resolution=256)
skeleton_coords = extractor.extract_skeleton()

# Access the graph
G = extractor.skeleton_graph        # NetworkX graph
endpoints = extractor.endpoints      # degree-1 nodes
junctions = extractor.junctions      # degree-3+ nodes
main_path = extractor.main_path      # longest path indices

# Custom path between two world-space points
centerline = extractor.get_ordered_centerline(start_point=[0,0,0], end_point=[1,1,1])

# Save PLY + JSON
extractor.save_skeleton(skeleton_coords, 'skeleton.ply')
```

## How It Works

1. **Interior fill** — watertight meshes use ray-cast containment (`mesh.contains`); non-watertight meshes use surface voxelization + morphological closing + exterior flood-fill
2. **Skeletonization** — topological thinning via scikit-image
3. **Graph construction** — 26-connected voxel neighbors linked via KDTree
4. **Connectivity enforcement** — disconnected components bridged with interpolated edges
5. **Path analysis** — endpoints, junctions, main centerline (double-BFS), and non-overlapping branch segments (edge-walking)

## GPU Acceleration

When PyTorch with CUDA is available, voxelization and morphological operations run on GPU automatically. No code changes needed — falls back to CPU transparently.

## Output Files

### skeleton.ply
PLY with vertex positions and edge connectivity.

### skeleton_graph.json
```json
{
  "vertices": [[x, y, z], ...],
  "edges": [[v1, v2], ...],
  "endpoints": [0, 5, ...],
  "junctions": [12, 34, ...],
  "main_path": [0, 1, 2, ...],
  "branch_paths": [[12, 13, 14], ...]
}
```

## CLI Arguments

| Argument | Default | Description |
|----------|---------|-------------|
| `input_mesh` | required | Input mesh file (OBJ, STL, PLY, etc.) |
| `-o, --output` | `skeleton.ply` | Output file path |
| `-r, --resolution` | `256` | Voxel grid resolution (128=fast, 256=balanced, 512=detailed) |
| `--no_viz` | off | Skip matplotlib visualization |

## Resolution Guide

| Resolution | Use case | Notes |
|-----------|----------|-------|
| 128 | Quick preview | Fast, coarse detail |
| 256 | Production | Balanced quality and speed |
| 512 | High detail | Slower, fine structures preserved |

## Troubleshooting

**Empty skeleton** — verify mesh has valid geometry and consistent normals. Try increasing resolution.

**Many disconnected components** — components <10 voxels are pruned; larger ones are bridged automatically within `mesh_scale * 0.1` distance. Check if mesh is watertight.

**Slow processing** — the bottleneck is `skeletonize` (CPU-bound). Reduce resolution for faster results.

## License

MIT — see [LICENSE](LICENSE).
