Multiscaling with triangle meshes

We use the skshapes.Multiscale class to create a multiscale decomposition of a triangle mesh. This is useful to accelerate some processing steps, such as multigrid simulations or level-of-detail rendering.

First, we load the Stanford bunny as a triangle mesh.

import pyvista as pv

import skshapes as sks

bunny = sks.PolyData(pv.examples.download_bunny())

Then, we create the multiscale representation with different sampling ratios.

multiscale_bunny = sks.Multiscale(shape=bunny, ratios=[0.1, 0.01, 0.001])

Under the hood, we rely on quadric decimation (Garland and Heckbert 1997) to reduces the number of vertices, iteratively collapsing the edge with the smallest approximation error. This algorithm is implemented by the fast-simplification package.

pl = pv.Plotter(shape=(2, 2))

for i, ratio in enumerate([1, 0.1, 0.01, 0.001]):
    # Use the '.at()' method to access the shape at different scales
    sampled_bunny = multiscale_bunny.at(ratio=ratio)

    pl.subplot(i // 2, i % 2)
    sks.doc.display(
        plotter=pl,
        shape=sampled_bunny,
        show_edges=True,
        title=f".at(ratio={ratio}), {sampled_bunny.n_points:,} points",
    )

pl.show()
plot multiscaling

Please note that calling the at() method with an arbitrary ratio returns the most compact (i.e. the coarsest) representation stored in the Multiscale object that is at least as detailed as the specified ratio.

pl = pv.Plotter(shape=(2, 2))

for i, ratio in enumerate([0.5, 0.1, 0.05, 0.01]):
    # Use the '.at()' method to access the shape at different scales
    sampled_bunny = multiscale_bunny.at(ratio=ratio)

    pl.subplot(i // 2, i % 2)
    sks.doc.display(
        plotter=pl,
        shape=sampled_bunny,
        show_edges=True,
        title=f".at(ratio={ratio}), {sampled_bunny.n_points:,} points",
    )

pl.show()
plot multiscaling

Alternatively, we can use the n_points parameter to specify the desired number of points per resolution level.

multiscale_bunny = sks.Multiscale(shape=bunny, n_points=[3000, 1000, 300, 100])

pl = pv.Plotter(shape=(2, 2))

for i, n_points in enumerate([3000, 1000, 300, 100]):
    # Use the '.at()' method with the n_points parameter instead of ratio
    sampled_bunny = multiscale_bunny.at(n_points=n_points)

    pl.subplot(i // 2, i % 2)
    sks.doc.display(
        plotter=pl,
        shape=sampled_bunny,
        show_edges=True,
        title=f".at(n_points={n_points}), {sampled_bunny.n_points:,} points",
    )

pl.show()
plot multiscaling

Total running time of the script: (0 minutes 5.995 seconds)

Gallery generated by Sphinx-Gallery