You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Replace VTK's clean filter with our own point merging #79
Clustering.create_mesh calls VTK's clean filter by default. All we need from it is merging coincident points, but it also rebuilds the cell array, and that undoes the compact representation we hand it.
Measured on 200,000 triangles with an int32, fixed-width cell array:
connectivity
fixed-size storage
offsets
cell array
before clean()
int32
yes
1 KiB
2345 KiB
after clean()
int64
no
1563 KiB
6251 KiB
So the filter inflates the cell array 2.7x: it widens the connectivity to int64 and materialises an offsets array we had eliminated. On the default clean=True path that means the compact form only ever exists on the intermediate mesh, never on what we return to the caller.
We already have a much better merger in the org. pyvista-stl dedups vertices with a 96-bit hash table (src/hash96.h, Bob Jenkins lookup3, MIT), using a lock-free concurrent open-addressing table on the parallel path with a sequential fallback and mmap-backed allocation (src/stlfile.cpp, roughly lines 316-460). It solves the identical problem, exact coincident-vertex merging over a triangle soup, and it does it while reading the file rather than as a separate pass.
It should transplant cleanly. pyvista-stl and pyacvd already share array_support.h and the same nanobind stack, as does fast-simplification.
Worth doing because:
we keep int32 and fixed-width storage through to the returned mesh
exact hashing is a better fit than a spatial locator, since the points we merge are bitwise-identical duplicates produced by our own subdivision rather than nearby-but-distinct points
it drops a VTK filter from the hot path, and it parallelises
Two things to decide when picking this up. Whether the merge tolerance stays exact or needs to match clean's tolerance behaviour for anyone relying on it, and whether create_mesh(clean=True) keeps that name once it is no longer VTK's clean.
Context: this came out of the in-progress work to make faces int32 and use fixed-width cell storage, which is the representation clean currently discards. I'll link that PR here once it's up.
The int32 fixed-width work is up as #80. That PR's intermediate arrays halve, but create_mesh(clean=True) still re-widens the returned mesh, which is what this issue would fix.
Activity
akaszynski commentedon Aug 15, 2026
The int32 fixed-width work is up as #80. That PR's intermediate arrays halve, but
create_mesh(clean=True)still re-widens the returned mesh, which is what this issue would fix.