Wrapper around the Fast-Quadric-Mesh-Simplification library.
Project description
This is a python wrapping of the Fast-Quadric-Mesh-Simplification Library. Having arrived at the same problem as the original author, but needing a Python library, this project seeks to extend the work of the original library while adding integration to Python and the PyVista project.
For the full documentation visit: https://pyvista.github.io/fast-simplification/
Basic Usage
The basic interface is quite straightforward and can work directly with arrays of points and triangles:
points = [[ 0.5, -0.5, 0.0],
[ 0.0, -0.5, 0.0],
[-0.5, -0.5, 0.0],
[ 0.5, 0.0, 0.0],
[ 0.0, 0.0, 0.0],
[-0.5, 0.0, 0.0],
[ 0.5, 0.5, 0.0],
[ 0.0, 0.5, 0.0],
[-0.5, 0.5, 0.0]]
faces = [[0, 1, 3],
[4, 3, 1],
[1, 2, 4],
[5, 4, 2],
[3, 4, 6],
[7, 6, 4],
[4, 5, 7],
[8, 7, 5]]
points_out, faces_out = fast_simplification.simplify(points, faces, 0.5)
Advanced Usage
This library supports direct integration with VTK through PyVista to provide a simplistic interface to the library. As this library provides a 4-5x improvement to the VTK decimation algorithms.
>>> from pyvista import examples
>>> mesh = examples.download_nefertiti()
>>> out = fast_simplification.simplify_mesh(mesh, target_reduction=0.9)
Compare with built-in VTK/PyVista methods:
>>> fas_sim = fast_simplification.simplify_mesh(mesh, target_reduction=0.9)
>>> dec_std = mesh.decimate(0.9) # vtkQuadricDecimation
>>> dec_pro = mesh.decimate_pro(0.9) # vtkDecimatePro
>>> pv.set_plot_theme('document')
>>> pl = pv.Plotter(shape=(2, 2), window_size=(1000, 1000))
>>> pl.add_text('Original', 'upper_right', color='w')
>>> pl.add_mesh(mesh, show_edges=True)
>>> pl.camera_position = cpos
>>> pl.subplot(0, 1)
>>> pl.add_text(
... 'Fast-Quadric-Mesh-Simplification\n~2.2 seconds', 'upper_right', color='w'
... )
>>> pl.add_mesh(fas_sim, show_edges=True)
>>> pl.camera_position = cpos
>>> pl.subplot(1, 0)
>>> pl.add_mesh(dec_std, show_edges=True)
>>> pl.add_text(
... 'vtkQuadricDecimation\n~9.5 seconds', 'upper_right', color='w'
... )
>>> pl.camera_position = cpos
>>> pl.subplot(1, 1)
>>> pl.add_mesh(dec_pro, show_edges=True)
>>> pl.add_text(
... 'vtkDecimatePro\n11.4~ seconds', 'upper_right', color='w'
... )
>>> pl.camera_position = cpos
>>> pl.show()
Comparison to other libraries
The pyfqmr library wraps the same header file as this library and has similar capabilities. In this library, the decision was made to write the Cython layer on top of an additional C++ layer rather than directly interfacing with wrapper from Cython. This results in a mild performance improvement.
Reusing the example above:
Set up a timing function.
>>> import pyfqmr
>>> vertices = mesh.points
>>> faces = mesh.faces.reshape(-1, 4)[:, 1:]
>>> def time_pyfqmr():
... mesh_simplifier = pyfqmr.Simplify()
... mesh_simplifier.setMesh(vertices, faces)
... mesh_simplifier.simplify_mesh(
... target_count=out.n_faces, aggressiveness=7, verbose=0
... )
... vertices_out, faces_out, normals_out = mesh_simplifier.getMesh()
... return vertices_out, faces_out, normals_out
Now, time it and compare with the non-VTK API of this library:
>>> timeit time_pyfqmr()
2.75 s ± 5.35 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
>>> timeit vout, fout = fast_simplification.simplify(vertices, faces, 0.9)
2.05 s ± 3.18 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Additionally, the fast-simplification library has direct plugins to the pyvista library, making it easy to read and write meshes:
>>> import pyvista
>>> import fast_simplification
>>> mesh = pyvista.read('my_mesh.stl')
>>> simple = fast_simplification.simplify_mesh(mesh)
>>> simple.save('my_simple_mesh.stl')
Since both libraries are based on the same core C++ code, feel free to use whichever gives you the best performance and interoperability.
Replay decimation functionality
This library also provides an interface to keep track of the successive collapses that occur during the decimation process and to replay the decimation process. This can be useful for different applications, such as:
applying the same decimation to a collection of meshes that share the same topology
computing a correspondence map between the vertices of the original mesh and the vertices of the decimated mesh, to transfer field data from one to the other for example
replaying the decimation process with a smaller target reduction than the original one, faster than decimating the original mesh with the smaller target reduction
To use this functionality, you need to set the return_collapses parameter to True when calling simplify. This will return the successive collapses of the decimation process in addition to points and faces.
>>> import fast_simplification
>>> import pyvista
>>> mesh = pyvista.Sphere()
>>> points, faces = mesh.points, mesh.faces.reshape(-1, 4)[:, 1:]
>>> points_out, faces_out, collapses = fast_simplification.simplify(points, faces, 0.9, return_collapses=True)
Now you can call replay_simplification to replay the decimation process and obtain the mapping between the vertices of the original mesh and the vertices of the decimated mesh.
>>> points_out, faces_out, indice_mapping = fast_simplification.replay_simplification(points, faces, collapses)
>>> i = 3
>>> print(f'Vertex {i} of the original mesh is mapped to {indice_mapping[i]} of the decimated mesh')
You can also use the replay_simplification function to replay the decimation process with a smaller target reduction than the original one. This is faster than decimating the original mesh with the smaller target reduction. To do so, you need to pass a subset of the collapses to the replay_simplification function. For example, to replay the decimation process with a target reduction of 50% the initial rate, you can run:
>>> import numpy as np
>>> collapses_half = collapses[:int(0.5 * len(collapses))]
>>> points_out, faces_out, indice_mapping = fast_simplification.replay_simplification(points, faces, collapses_half)
If you have a collection of meshes that share the same topology, you can apply the same decimation to all of them by calling replay_simplification with the same collapses for each mesh. This ensure that the decimated meshes will share the same topology.
>>> import numpy as np
>>> # Assume that you have a collection of meshes stored in a list meshes
>>> _, _, collapses = fast_simplification.simplify(meshes[0].points, meshes[0].faces,
... 0.9, return_collapses=True)
>>> decimated_meshes = []
>>> for mesh in meshes:
... points_out, faces_out, _ = fast_simplification.replay_simplification(mesh.points, mesh.faces, collapses)
... decimated_meshes.append(pyvista.PolyData(points_out, faces_out))
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Hashes for fast_simplification-0.1.4.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1a6d6ac9c7eca7a3799af28192cdfa97c7e8a8e3f4d9988c478df58ab329374e |
|
MD5 | 448ab4d1f01f72846e7f13269224b4d6 |
|
BLAKE2b-256 | a76c44f26b4185e334a0976e47e14e70dea44124fb46647497765e7cdb80e5d2 |
Hashes for fast_simplification-0.1.4-cp312-cp312-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3eff3eb5b9ab20dff333e1ee433602fa26d07b2e9c45745adf4458265c61ecac |
|
MD5 | 6f845edc96a2e64a17fb69d14da2baa5 |
|
BLAKE2b-256 | 7d21901f42dfc9667295adc7d8588556badc9a3fb4d5a28061a366a316f70588 |
Hashes for fast_simplification-0.1.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | c0f4b22fb0d20f15937078137e2ee3d3617a61b4a5d8122437cbbfb20f54bac3 |
|
MD5 | d3d63c264fd3f04bce51762389b340c5 |
|
BLAKE2b-256 | 69e541416bdbc33fcf8ca2a2f43663249b74755d8c1045407fbcef0f122abcc9 |
Hashes for fast_simplification-0.1.4-cp312-cp312-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | ce79a513e029569573605356f77775894201c846bea4fa90e2ce9c645ed2c536 |
|
MD5 | 0351e8d5074f65f47a707aec55bb58ec |
|
BLAKE2b-256 | 1a3cce60eba64926133df77ab9765f7293f27cc0a60ee9bf344189ed5013a18a |
Hashes for fast_simplification-0.1.4-cp312-cp312-macosx_10_9_universal2.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 7350f07ac83d8ead453565904af4c23b4b72d765e6ae58170f79bfb8a21b0b03 |
|
MD5 | 2d6e6b9839b5662f1cba8ec70441c89e |
|
BLAKE2b-256 | 72c77cfb3b9a6bd1cadef167a94b82e245b092723940899316ff1749bb958d32 |
Hashes for fast_simplification-0.1.4-cp311-cp311-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | abeb783a3b4dc262ffbfc8d434337d4f51616a622e07aee1a5727294260ab366 |
|
MD5 | 5247607e4b31f7411ec2672d1618dbad |
|
BLAKE2b-256 | 2fe71b9a432643ba48a6b89414975aedf27cca6f6edbc75008a58e66f4c40411 |
Hashes for fast_simplification-0.1.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b6f3d9467935bedc58015d1610a36f66d284346c830de69c9e7ca11fe4e4bfcd |
|
MD5 | b2272d9a8a41fd0001c2c060024cd717 |
|
BLAKE2b-256 | 62dda880ab47cd0602bdf6682f9af5721765e6a61afe2d09868e97d62da5dc68 |
Hashes for fast_simplification-0.1.4-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 352eba2d34c68894f408d3a43982a8eb3878ef6e074c12a0b738fe08ae1f9e8d |
|
MD5 | 47a854f6fe50c588fe8bccee5decab57 |
|
BLAKE2b-256 | a95e8920a1a576a24e6414bbb5d90f604043bff321e4702a99ba107aa2c2b604 |
Hashes for fast_simplification-0.1.4-cp311-cp311-macosx_10_9_universal2.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b2dd5d22a821d39f398ff73ce5d7f1c6184256beac1170bb95e9014f97f971b8 |
|
MD5 | b63ae622565d303d0d897e409ad907ba |
|
BLAKE2b-256 | bf032d593e028efea887a65d74f47d998f02879512fff542ed742bc759ddfe01 |
Hashes for fast_simplification-0.1.4-cp310-cp310-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 38167f03ee9fb5b6f3114ffa581104d85d5b565b7dd17d65f123781d6683059e |
|
MD5 | d27a7feeac44f1b0cbb252bf3698c5ec |
|
BLAKE2b-256 | 4b12b8fc783e97aac76dfc3fde7d1dfce69e13b9c27bd91e09220ac8bdea139a |
Hashes for fast_simplification-0.1.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 97d6fba42d8a25db65455fbd600bea09005c20062e86bfe8c3cb3b9936d967ba |
|
MD5 | e6d28e6e793926fd747e5cd01e564eba |
|
BLAKE2b-256 | b251355990f8e15ec09771c8d84732f5d7417fdbdcb65ecf7e8a605d0e2a2ae2 |
Hashes for fast_simplification-0.1.4-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 05ec21b9c72ec1ace0cc87540931def7e73fb73b131abb536b4d6b9b49d54acc |
|
MD5 | 3915bec4a05dd841dd2597b659c8de46 |
|
BLAKE2b-256 | bcaf182cc150f8cd77fce8f390ae37b266fae6af0f7b113c4285f119e9f78095 |
Hashes for fast_simplification-0.1.4-cp310-cp310-macosx_10_9_universal2.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 8433008b66367ec7d6209554906d0ca53bb0efb24df55fd4dc29d0db2f6a58e1 |
|
MD5 | 01c777cb6f27d993aa3fe1c0efcb2bc7 |
|
BLAKE2b-256 | 6025a5e2e904690b2838f1a427d5e3b505e3fa0e53ad3f0b87f944bf1092aa51 |
Hashes for fast_simplification-0.1.4-cp39-cp39-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b585bf78387b16c2cf3ba0f4a1b6f21ed1545400a9b69d4c92f0f154fe75c667 |
|
MD5 | 99b60a388615757ba7c9fce6ff1ec5aa |
|
BLAKE2b-256 | c8fcd0b3cc4a60d143a0b1c90ce8023480431ed8b39f103ed842a4f85c59f55b |
Hashes for fast_simplification-0.1.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3c1b9e5edfa023bb25186761bbe094e158aab38733a5223b6f8f85f31cc3f201 |
|
MD5 | 8700442aacbf626bd900a68af768f155 |
|
BLAKE2b-256 | fb2cba21a64b2173990cd3e86447da9cfe741a77ad3d8463dbab31303cfe669d |
Hashes for fast_simplification-0.1.4-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 76aa1dc483efc3f2aa6c2d3f38a5ff0d757fec59e28a6e4b486209974820c66a |
|
MD5 | 367e4410f8df2760f2dfd5d3918083d2 |
|
BLAKE2b-256 | 40be402d808528d3c07353e979c3cd69221ae085630cb7d5ce8ac218761bc8a6 |
Hashes for fast_simplification-0.1.4-cp39-cp39-macosx_10_9_universal2.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | feb11d73d0f40cce9935f442b582cfff2ee74409ed0c81ad6cc0a521fc798eaa |
|
MD5 | f13ca172b809d8542b51581d1933be88 |
|
BLAKE2b-256 | d9021a9d56e69871bf51f6fd4136f881175139e08b5b376e836575dffdafee7b |
Hashes for fast_simplification-0.1.4-cp38-cp38-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 346e532d13e7d6d19af39889924200fcbbf717abae4cc3f653f443147dc8e136 |
|
MD5 | 8a2f7f8bfed58f2d6ecef7df655e683b |
|
BLAKE2b-256 | 8154ef83dc16b5be74e8b9236ce55631450c9a8bbe4e9b67f303927166ef212c |
Hashes for fast_simplification-0.1.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 921b089db1f18ce5802b837f2ee296c58e43cb5a034f6079eacad700d4daf783 |
|
MD5 | 70089a5cd24c9d5fa1dd0d3ad226b93c |
|
BLAKE2b-256 | 43f71c528c31ac5a2dc41077aae9916c63f99f2e7d1cf9ee8d06919b89d1cc58 |
Hashes for fast_simplification-0.1.4-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6220cf5d1bc7d45762d5a74426b51d48f0ac09a6c85c28b6d717ebd04293a548 |
|
MD5 | 1cf8098f983683fc23782a8ba711daf8 |
|
BLAKE2b-256 | 985de323ab22c90b6876167b2d2ba9b64f73747895d7a4709de7c621a72253db |
Hashes for fast_simplification-0.1.4-cp38-cp38-macosx_10_9_universal2.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | d4b208772b144f68220a31e88f2b7fae91e15414e5fde7007cec425a66c0c9e8 |
|
MD5 | 50c82476831fb7f6aa200919aaa9cdfb |
|
BLAKE2b-256 | 469ad8fb6f76365659c58b329c331c5ab4caab94b3fd33585a51c02560b83a61 |