How to compute the distance between meshes with unknown correspondences with functional maps?#

We show an aligment-based strategy to compute “distances” between meshes with unknown correspondences. Alignment is performed using functional maps.

Meshes are assumed to have the same number of vertices.

NB: this is not really a distance (e.g. not symmetric)

[1]:
import pyvista as pv
from geomstats.geometry.stratified.quotient import Aligner, QuotientMetric

from polpo.mesh.geometry import (
    DiscreteSurfaces,
    FmAlignerAlgorithm,
    L2SurfacesMetric,
    PullbackMetric,
    SurfacesSpace,
    vertices_to_array,
    vertices_to_geomfum,
)
from polpo.preprocessing.load.pregnancy.random import get_two_random_meshes
[KeOps] Warning : CUDA was detected, but driver API could not be initialized. Switching to CPU only.
[2]:
STATIC_VIZ = True
VIZ = 0

if STATIC_VIZ:
    pv.set_jupyter_backend("static")
[3]:
# decimation breaks correspondnces
meshes = get_two_random_meshes(
    target_reduction=0.6,
    as_pv_surface=True,
)

mesh_a, mesh_b = meshes
[4]:
if VIZ > 1:
    pl = pv.Plotter(border=False)

    for mesh in meshes:
        pl.add_mesh(mesh.as_pv(), show_edges=True, opacity=0.6)

    pl.show()
[5]:
image_space = DiscreteSurfaces(mesh_a.faces, equip=False).equip_with_metric(
    L2SurfacesMetric
)

# TODO: improve geomstats
total_space = SurfacesSpace().equip_with_metric(
    PullbackMetric, forward_map=vertices_to_array, image_space=image_space
)
aligner_algo = FmAlignerAlgorithm()
total_space.aligner = Aligner(
    total_space,
    align_algo=aligner_algo,
)

quotient = SurfacesSpace().equip_with_metric(
    QuotientMetric,
    total_space=total_space,
)

space = SurfacesSpace().equip_with_metric(
    PullbackMetric,
    forward_map=vertices_to_geomfum,
    image_space=quotient,
)

registered_space = SurfacesSpace().equip_with_metric(
    PullbackMetric,
    forward_map=vertices_to_array,
    image_space=image_space,
)
[6]:
(
    registered_space.metric.squared_dist(mesh_a, mesh_b),
    # NB: values differ if no convergence
    # source seems to be laplacian basis?
    space.metric.squared_dist(mesh_a, mesh_b),
)
WARNING: Maximum number of iterations reached: 5
[6]:
(np.float32(87.58698), np.float32(25.653923))