Skip to main content

pyFM - Python Functional Maps Library

animated

PyPI version Python versions License: MIT Tests Documentation

This package contains a comprehensive Python implementation for shape correspondence using functional maps, featuring code from multiple papers.

Full API documentation is available online.

Core Features

  • Complete TriMesh class with geometric measures (geodesics, normals, LBO projections, differential operators)
  • Fast Laplace-Beltrami Operator implementation
  • Shape descriptors (HKS, WKS) with flexible parameter control
  • Efficient correspondence refinement (ICP, ZoomOut)
  • Fast functional-to-pointwise map conversion
  • Functional Map Network utilities

Installation

pip install pyfmaps

# with the optional PyVista-based plotting helpers used in the gallery
pip install 'pyfmaps[viz]'

Key Dependencies

Requires Python 3.10+ and: numpy, scipy, tqdm, scikit-learn, potpourri3d (geodesic distances via the heat and fast-marching methods), and robust_laplacian (Delaunay/tufted Laplacian). All are installed automatically.

Quickstart

from pyFM.mesh import TriMesh
from pyFM.functional import FunctionalMapping

# Load a source and a target mesh
mesh1 = TriMesh.load("cat.off", area_normalize=True, center=True)
mesh2 = TriMesh.load("lion.off", area_normalize=True, center=True)

# Compute the LBO spectrum + descriptors, then fit a functional map.
# Keep w_orient above 0: descriptors alone cannot tell left from right,
# and w_orient=0 (the default) usually returns a symmetry-flipped map.
model = FunctionalMapping(mesh1, mesh2)
model.preprocess(descr_type="WKS", subsample_step=2, verbose=True)
model.fit(K=30, w_descr=1e0, w_lap=1e-1, w_dcomm=1e0, w_orient=1e0, verbose=True)

# Convert the functional map to a point-to-point map (mesh2 -> mesh1)
p2p_21 = model.get_p2p()

# Refine the map -- this is where most of the accuracy comes from
FM_zo = model.zoomout_refine(nit=16, step=5)
p2p_21_zo = model.get_p2p(FM_zo)

See the example gallery for complete, runnable workflows with interactive 3D figures.

Design Philosophy

This codebase prioritizes readability and adaptability over rigid modularity. The implementation seeks to make it easy to:

  • Read and understand the underlying algorithms
  • Copy and modify code snippets for your research
  • Experiment with and extend existing methods
  • Avoid rewriting core functionality from scratch

Under the hood, core algorithms are implemented as standalone functions operating on basic numpy arrays. This dual-layer design means you can use the high-level interface for standard workflows, but still easily extract and modify the core functions for your research, as they work with simple numpy arrays.

While this approach differs from highly modular packages like scikit-learn, it better serves researchers who need to modify and build upon existing shape correspondence methods.

This design choice comes with some trade-offs:

  • Less abstraction means potentially more code to achieve certain tasks
  • Users need some familiarity with shape correspondence concepts
  • Implementation favors explicit algorithms over general-purpose interfaces

I selected this approach from my personal experience with research codebases and may not suit everyone's needs. More generic and abstracted implementations of geometric processing can be expected to appear soonish in the scikit-shapes or geomstats libraries.

Notation Convention

  • Functional maps (FM_12): mesh1 → mesh2
  • Pointwise maps (p2p_21): mesh2 → mesh1

Documentation & Examples

Implemented Papers

This library implements methods from several key papers in shape correspondence, including:

Torch Version

Most functions in this package can easily be translated to torch. However, for clarity of the code, a separate version will be released.

For now, the torch implementations can be found in different githubs (see my GitHub profile).

Coming Soon

Contact and Citation

You can contact me for any questions or requests at robin.magnet@inria.fr

This package has not (yet) been presented as a paper in itself, although all my works heavily rely on this.

If you use this package or copy and paste parts of it for you experiments, please cite this github or one of the following paper. Note these papers never directly refer to pyfmaps as so I am fine with you only citing the github for now.

@inproceedings{magnetDWKSLocalDescriptor2021,
  title = {{{DWKS}} : {{A Local Descriptor}} of {{Deformations Between Meshes}} and {{Point Clouds}}},
  shorttitle = {{{DWKS}}},
  booktitle = {2021 {{IEEE}}/{{CVF International Conference}} on {{Computer Vision}} ({{ICCV}})},
  author = {Magnet, Robin and Ovsjanikov, Maks},
  publisher = {IEEE},
}


@inproceedings{magnetSmoothNonRigidShape2022,
  title = {Smooth {{Non-Rigid Shape Matching}} via {{Effective Dirichlet Energy Optimization}}},
  booktitle = {2022 {{International Conference}} on {{3D Vision}} ({{3DV}})},
  author = {Magnet, Robin and Ren, Jing and {Sorkine-Hornung}, Olga and Ovsjanikov, Maks},
  year = {2022},
  publisher = {{IEEE}},

}

@article{magnetScalableEfficientFunctional2023,
  title = {Scalable and {{Efficient Functional Map Computations}} on {{Dense Meshes}}},
  author = {Magnet, Robin and Ovsjanikov, Maks},
  year = {2023},
  journal = {Computer Graphics Forum},
}

Metadata

Release files for pyfmaps 1.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyfmaps 1.3.1
File Size Uploaded
pyfmaps-1.3.1.tar.gz 3.4 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for pyfmaps 1.3.1
File Interpreter ABI Platform
pyfmaps-1.3.1-py3-none-any.whl Python 3 none any Details

Total release size: 3.9 MB

Release files / pyfmaps-1.3.1.tar.gz

Download URL pyfmaps-1.3.1.tar.gz
Size 3.4 MB
Tags Source
SHA-256 checksum
How to use checksums
88582566f7784b077a1920a4cd8d736ba6407731fac706861a6210799a9bc687
BLAKE2b-256 checksum
How to use checksums
d3ae890c56fc42c7283c8dce4174204322e7b630dfc3187f538677ff83536900
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.

Transparency log

Release files / pyfmaps-1.3.1-py3-none-any.whl

Download URL pyfmaps-1.3.1-py3-none-any.whl
Size 512.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a85ba66ed70d4d41818bd539c4eed4dda7764c27f906ad79200d99ad1a69ee65
BLAKE2b-256 checksum
How to use checksums
2d1d86c183dd53c4cccdddf8c11ae7bcc81f5b8ca42b0ab0fd6985575731aa90
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.3.1 This release

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page