Unlike its namesake, this Python 3 library does not (yet) seek to conquer Eternia but to turn meshes into skeletons.
Heads-up: skeletor 1.0.0 introduced some breaking changes and major reorganizations.
Please see the changelog
for details.
pip3 install skeletorFor the dev version:
pip3 install git+https://github.com/navis-org/skeletor@masterAutomatically installed with pip:
- networkx
- numpy
- pandas
- scipy
- scikit-learn
- trimesh
- tqdm
- python-igraph
- ncollpyde
Optional because not strictly required for the core functions but highly recommended:
- pyglet is required by trimesh to preview meshes/skeletons in 3D: pip3 install pyglet
- fastremap for sizeable speed-ups with some methods: pip3 install fastremap
Please see the documentation for details.
The change log can be found here.
For the impatient a quick example:
>>> import skeletor as sk
>>> mesh = sk.example_mesh()
>>> # To load and use your own mesh instead of the example mesh:
>>> # import trimesh as tm
>>> # mesh = tm.Trimesh(vertices, faces)  # or...
>>> # mesh = tm.load_mesh('mesh.obj')
>>> fixed = sk.pre.fix_mesh(mesh, remove_disconnected=5, inplace=False)
>>> skel = sk.skeletonize.by_wavefront(fixed, waves=1, step_size=1)
>>> skel
<Skeleton(vertices=(1258, 3), edges=(1194, 2), method=wavefront)>All skeletonization methods return a Skeleton object. These are just
convenient objects to represent and inspect the results.
>>> # location of vertices (nodes)
>>> skel.vertices
array([[16744, 36720, 26407],
       ...,
       [22076, 23217, 24472]])
>>> # child -> parent edges
>>> skel.edges
array([[  64,   31],
       ...,
       [1257, 1252]])
>>> # Mapping for mesh to skeleton vertex indices
>>> skel.mesh_map
array([ 157,  158, 1062, ...,  525,  474,  547])
>>> # SWC table
>>> skel.swc.head()
   node_id  parent_id             x             y             z    radius
0        0         -1  16744.005859  36720.058594  26407.902344  0.000000
1        1         -1   5602.751953  22266.756510  15799.991211  7.542587
2        2         -1  16442.666667  14999.978516  10887.916016  5.333333
>>> # Save SWC file
>>> skel.save_swc('skeleton.swc')If you installed pyglet (see above) you can also use trimesh's plotting
capabilities to inspect the results:
>>> skel.show(mesh=True)Benchmarks
were run on a 2018 MacBook Pro (2.2 GHz Core i7, 32Gb memory) with optional
fastremap dependency installed. Note some of these functions (e.g.
contraction and TEASAR/vertex cluster skeletonization) can vary a lot in
speed based on parameterization.
Pull requests are always welcome!
Mesh contraction and the edge collapse approach are based on this paper:
[1] Au OK, Tai CL, Chu HK, Cohen-Or D, Lee TY. Skeleton extraction by mesh contraction. ACM Transactions on Graphics (TOG). 2008 Aug 1;27(3):44.
The abstract and the paper can be found here.
Also see this YouTube video.
Some of the code in skeletor was modified from the Py_BL_MeshSkeletonization addon for Blender 3D created by #0K Srinivasan Ramachandran and published under GPL3.
The mesh TEASAR approach was adapted from the implementation in meshparty by Sven Dorkenwald, Casey Schneider-Mizell and Forrest Collman.

