ordito runs on the GPU, and the libraries most mesh-processing code reaches for do not. This page
compares the two on the same inputs: ordito on CUDA against eleven reference libraries — trimesh,
libigl, Open3D, SciPy, NumPy, potpourri3d (geometry-central), MeshLab (through PyMeshLab), PyVista
(VTK), MeshLib, PyMeshFix and PyTorch3D, the one other library with GPU kernels.
Every comparison times the same quantity on both sides, and the correctness suite checks that the
two answers agree. A time is the median of repeated calls from Python, including the wait for the
GPU to finish, so it is what a caller measures. The inputs are real 3D scans from the Stanford
repository (from 16 thousand to 28 million triangles) and synthetic meshes that each stress one
cost driver: many components, long boundaries, needle triangles, high valence.
How long each library takes relative to ordito, over every function both implement: ordito is 1x,
and a library at 30x takes thirty times as long. Each function counts once: its ratio is first
averaged over the inputs it was measured on, then the functions are averaged. Both averages are
geometric means, the usual way to combine ratios: a 10x win and a 10x loss cancel out.
Time relative to ordito (CUDA), geometric mean over every function both implement; in parentheses, the number of functions. Log scale. Runs stopped at the time limit are left out.Values
Library
Time relative to ordito
Functions compared
ordito faster in
MeshLib
11x
118
103
PyTorch3D (CUDA)
12x
36
34
NumPy
12x
35
29
Open3D
22x
71
67
SciPy
44x
23
23
potpourri3d
65x
20
20
libigl
95x
95
94
MeshLab
96x
79
79
trimesh
102x
119
116
PyVista
109x
64
62
PyMeshFix
548x
4
4
Libraries are compared on different sets of functions, so each bar measures one library against
ordito, not the libraries against each other. The libraries closest to ordito are the ones whose
functions are mostly fast, compiled code on small inputs; the gaps grow with the input.
By module
ordito's speedup per module, against the fastest library measured on each input — the toughest
comparison available for each function. Each module has its own page, with a chart for every
function.
ordito (CUDA)'s speedup over the fastest library measured on each input, geometric mean per module; in parentheses, the number of functions. Log scale.Values
The comparisons with the widest field of libraries. Each chart shows one input, with ordito at 1x
and every other library's time relative to it; each module's page has every function and every
input.
Signed distance to a mesh
Signed distance from a point set to a triangle mesh, the widest field among the spatial queries.
dragon (871 414 faces) · sign_mode=parity · time relative to ordito, log scale · [all proximity benchmarks](proximity.md)Values
Library
Median
Relative to ordito
ordito (CUDA)
5.11 ms
1x
MeshLib
94.85 ms
19x
Open3D
281.78 ms
55x
PyVista
1.024 s
200x
libigl
1.045 s
205x
MeshLab
7.216 s
1413x
Nearest neighbours, k = 7
Seven nearest neighbours of every query point, against CPU trees and PyTorch3D's GPU kernel.
dragon (871 414 faces) · time relative to ordito, log scale · a red cross is a run that left no time · [all neighbors benchmarks](neighbors.md)Values
Library
Median
Relative to ordito
ordito (CUDA)
1.85 ms
1x
PyTorch3D (CUDA)
43.89 ms
24x
Open3D
117.91 ms
64x
SciPy
147.45 ms
80x
libigl
out of memory
Nearest neighbour, k = 1
The same query with a single neighbour. Every library with a tree, ordito included, builds it
over the cloud inside the timed call, and the build is most of the work: about two thirds of
ordito's time.
dragon (871 414 faces) · time relative to ordito, log scale · a red cross is a run that left no time · [all neighbors benchmarks](neighbors.md)Values
Library
Median
Relative to ordito
ordito (CUDA)
625.7 µs
1x
MeshLib
15.65 ms
25x
PyTorch3D (CUDA)
33.85 ms
54x
Open3D
125.54 ms
201x
SciPy
167.32 ms
267x
libigl
out of memory
Quadric decimation
Edge-collapse simplification under the quadric error metric, against five independent
decimators.
saddle (34 848 faces) · target_ratio=0.5 · time relative to ordito, log scale · [all remesh benchmarks](remesh.md)Values
Library
Median
Relative to ordito
ordito (CUDA)
2.99 ms
1x
MeshLib
19.08 ms
6.4x
Open3D
45.93 ms
15x
PyVista
46.34 ms
15x
libigl
51.05 ms
17x
MeshLab
177.33 ms
59x
Minimal oriented bounding box
Every library here searches for the minimum-volume box, not the PCA box, so the bars compare
the same optimisation.
dragon (871 414 faces) · time relative to ordito, log scale · [all bounds benchmarks](bounds.md)Values
Library
Median
Relative to ordito
ordito (CUDA)
1.58 ms
1x
PyVista
18.34 ms
12x
trimesh
159.09 ms
100x
Open3D
2.096 s
1322x
libigl
2.483 s
1567x
Convex hull
dragon (871 414 faces) · time relative to ordito, log scale · [all points benchmarks](points.md)Values
Library
Median
Relative to ordito
ordito (CUDA)
1.86 ms
1x
Open3D
49.37 ms
27x
SciPy
61.31 ms
33x
trimesh
79.55 ms
43x
MeshLab
417.44 ms
224x
Blue-noise sampling
Poisson-disk sampling of a surface: four different algorithms for the same distribution.
dragon (871 414 faces) · radius_scale=1.0 · time relative to ordito, log scale · [all sample benchmarks](sample.md)Values
Library
Median
Relative to ordito
ordito (CUDA)
1.21 ms
1x
MeshLib
12.08 ms
10x
Open3D
57.02 ms
47x
libigl
304.39 ms
252x
MeshLab
488.56 ms
404x
Geodesic distance
Geodesic distance from a source vertex by the heat method, including building the solver.
sphere_med (81 920 faces) · setup=full · time relative to ordito, log scale · [all heat benchmarks](heat.md)Values
Library
Median
Relative to ordito
ordito (CUDA)
6.68 ms
1x
PyVista
23.72 ms
3.5x
potpourri3d
539.58 ms
81x
libigl
597.39 ms
89x
MeshLab
601.38 ms
90x
Repair: merging duplicate vertices
sphere_med (81 920 faces) · epsilon=0.0 · time relative to ordito, log scale · [all repair benchmarks](repair.md)Values
Library
Median
Relative to ordito
ordito (CUDA)
218.1 µs
1x
Open3D
16.42 ms
75x
PyVista
25.66 ms
118x
MeshLib
31.33 ms
144x
MeshLab
221.69 ms
1017x
Repair: consistent winding
Re-orienting every face to agree with its neighbours, a whole-mesh propagation.
sphere_med (81 920 faces) · time relative to ordito, log scale · [all repair benchmarks](repair.md)Values
Library
Median
Relative to ordito
ordito (CUDA)
148.6 µs
1x
MeshLib
6.91 ms
46x
trimesh
17.97 ms
121x
libigl
36.63 ms
247x
MeshLab
51.21 ms
345x
Connected components
dragon (871 414 faces) · time relative to ordito, log scale · [all adjacency benchmarks](adjacency.md)Values
Library
Median
Relative to ordito
ordito (CUDA)
301.0 µs
1x
MeshLib
21.73 ms
72x
PyVista
318.91 ms
1060x
libigl
445.32 ms
1480x
Unique edges
The undirected edge list, the first step of most topology code.
dragon (871 414 faces) · time relative to ordito, log scale · [all edges benchmarks](edges.md)Values
Library
Median
Relative to ordito
ordito (CUDA)
472.6 µs
1x
PyTorch3D (CUDA)
3.52 ms
7.5x
trimesh
243.05 ms
514x
PyVista
268.58 ms
568x
libigl
330.25 ms
699x
Taubin smoothing
dragon (871 414 faces) · time relative to ordito, log scale · [all smoothing benchmarks](smoothing.md)Values
Library
Median
Relative to ordito
ordito (CUDA)
476.5 µs
1x
PyVista
153.29 ms
322x
trimesh
198.54 ms
417x
Open3D
306.02 ms
642x
MeshLab
867.52 ms
1821x
Voxelizing a mesh
dragon (871 414 faces) · divisor=64 · time relative to ordito, log scale · [all voxels benchmarks](voxels.md)Values
Library
Median
Relative to ordito
ordito (CUDA)
636.0 µs
1x
MeshLib
109.34 ms
172x
Open3D
161.89 ms
255x
PyVista
255.97 ms
402x
trimesh
655.79 ms
1031x
Boundary edges, a loss
Listing the edges on a mesh's boundary is a single pass that serial C++ finishes in less time than
a GPU round trip takes. ordito loses this one, as it does most operations whose whole cost is a few
tens of microseconds; the module pages show the rest.
rim_long (131 072 faces) · time relative to ordito, log scale · [all boundary benchmarks](boundary.md)Values
Library
Median
Relative to ordito
MeshLib
55.0 µs
0.31x
ordito (CUDA)
178.5 µs
1x
trimesh
17.86 ms
100x
MeshLab
43.46 ms
243x
libigl
43.80 ms
245x
PyVista
56.55 ms
317x
Reproduce
The suite lives in benchmarks/;
its README describes the inputs and every comparison in detail. It needs Linux, an NVIDIA GPU and
the CUDA toolkit:
The last command redraws every chart on this page and on the module pages from your own run.
Absolute times depend on the hardware; the ratios are what carries over.
A ratio holds only for the library, the input and the hardware it was measured on: besides its
size, a mesh's number of components, boundary length and triangle shapes move it. A few functions
have little parallel work at realistic sizes (a sequential pass over one small boundary loop), and
a fast single-threaded C++ implementation beats them; the module pages show those cases beside
the others.