Benchmark
Which repair to run first when a mesh is broken in several ways at once
Which repair should be run first when a mesh has several defects at once?
Result
Order decides the outcome, and most orders are wrong. Four repairs that every tool offers, welding, hole filling, degenerate face removal and decimation, applied to one sphere carrying all four defects at once, close the mesh in 4 of the 24 possible sequences. The other 20 leave it open. Three of the four operations turn out to have exactly one workable order between them, weld then decimate then fill, and the fourth, dropping faces with no area, can go anywhere without changing anything: four valid sequences is precisely the four places the free operation can be inserted. Getting it wrong is not a near miss. Filling before welding creates 720 non-manifold edges that the source mesh did not have, because the unwelded seams read as holes and get stitched over. Decimating first leaves the mesh in 119 pieces and 1.22 per cent off the correct volume, against 0.11 per cent for the orders that work. The same four sequences close the mesh for every damage layout tested, so the order belongs to the operations rather than to the model.
What each operation does
| Operation | What it does |
|---|---|
| weld | merge corners that sit at the same coordinates |
| fill | close the boundary loops with new triangles |
| degen | drop faces that enclose no area |
| simplify | decimate to roughly half the triangle count |
These are the four every repair tool exposes, under various names. Some tools chain several of them behind a single button, which is one reason the order is usually invisible to the person clicking it.
All 24 orders, against a sphere that started closed
| Order | Faces | Open edges | Non-manifold edges | Shells | Closed | Volume error (%) |
|---|---|---|---|---|---|---|
| weld then fill then degen then simplify | 2,547 | 23 | 0 | 1 | No | 0.187 |
| weld then fill then simplify then degen | 2,547 | 23 | 0 | 1 | No | 0.187 |
| weld then degen then fill then simplify | 2,547 | 23 | 0 | 1 | No | 0.187 |
| weld then degen then simplify then fill | 2,558 | 0 | 0 | 1 | Yes | 0.110 |
| weld then simplify then fill then degen | 2,558 | 0 | 0 | 1 | Yes | 0.110 |
| weld then simplify then degen then fill | 2,558 | 0 | 0 | 1 | Yes | 0.110 |
| fill then weld then degen then simplify | 2,945 | 19 | 720 | 1 | No | 0.308 |
| fill then weld then simplify then degen | 2,945 | 19 | 714 | 1 | No | 0.307 |
| fill then degen then weld then simplify | 2,945 | 19 | 720 | 1 | No | 0.308 |
| fill then degen then simplify then weld | 2,946 | 25 | 20 | 203 | No | 0.235 |
| fill then simplify then weld then degen | 2,944 | 25 | 20 | 203 | No | 0.235 |
| fill then simplify then degen then weld | 2,944 | 25 | 20 | 203 | No | 0.235 |
| degen then weld then fill then simplify | 2,547 | 23 | 0 | 1 | No | 0.187 |
| degen then weld then simplify then fill | 2,558 | 0 | 0 | 1 | Yes | 0.110 |
| degen then fill then weld then simplify | 2,945 | 19 | 720 | 1 | No | 0.308 |
| degen then fill then simplify then weld | 2,946 | 25 | 20 | 203 | No | 0.235 |
| degen then simplify then weld then fill | 2,955 | 50 | 32 | 119 | No | 1.216 |
| degen then simplify then fill then weld | 2,955 | 50 | 32 | 119 | No | 1.216 |
| simplify then weld then fill then degen | 2,953 | 50 | 32 | 119 | No | 1.217 |
| simplify then weld then degen then fill | 2,953 | 50 | 32 | 119 | No | 1.217 |
| simplify then fill then weld then degen | 2,953 | 50 | 32 | 119 | No | 1.217 |
| simplify then fill then degen then weld | 2,953 | 50 | 32 | 119 | No | 1.217 |
| simplify then degen then weld then fill | 2,953 | 50 | 32 | 119 | No | 1.217 |
| simplify then degen then fill then weld | 2,953 | 50 | 32 | 119 | No | 1.217 |
The volume column is only meaningful on the rows that closed, since an open mesh does not enclose a volume in the first place; it is shown throughout because the size of the number tracks how far the result drifted. The three failure modes are distinct. Anything filled before welding gains hundreds of non-manifold edges it did not start with. Anything decimated first ends in roughly 119 pieces. Anything welded and filled but then decimated reopens, at 23 edges.
Which precedences the closing orders share
| Constraint | Orders that satisfy it | Of those, closed | Share closed | Required |
|---|---|---|---|---|
| weld before fill | 12 | 4 | 33.33% | Yes |
| weld before degen | 12 | 3 | 25% | No |
| weld before simplify | 12 | 4 | 33.33% | Yes |
| fill before weld | 12 | 0 | 0% | No |
| fill before degen | 12 | 1 | 8.33% | No |
| fill before simplify | 12 | 0 | 0% | No |
| degen before weld | 12 | 1 | 8.33% | No |
| degen before fill | 12 | 3 | 25% | No |
| degen before simplify | 12 | 2 | 16.67% | No |
| simplify before weld | 12 | 0 | 0% | No |
| simplify before fill | 12 | 4 | 33.33% | Yes |
| simplify before degen | 12 | 2 | 16.67% | No |
Read down the Required column. It is derived from the results rather than asserted in advance: a constraint counts as required when every order that closed the mesh satisfies it. Three do, and the three together fix one sequence. Every constraint involving the degenerate face removal is marked no, which is the measurement saying that step is free to go anywhere.
The same run against four different damage layouts
| Layout | Orders that closed it | Orders tried | Closing orders recorded |
|---|---|---|---|
| 11 | 4 | 24 | 4 |
| 23 | 4 | 24 | 4 |
| 47 | 4 | 24 | 4 |
| 99 | 4 | 24 | 4 |
Same quantity of damage, different places. Four out of twenty four every time, and the source data records that the four are the identical four in each run. If the answer had moved between layouts it would be a fact about this sphere rather than about the operations.
The one order, and why it is that one
Weld, then decimate, then fill, with degenerate face removal wherever you like. Each constraint has a reason that survives outside this test. Welding has to precede filling because a hole filler works on boundary loops, and on an unwelded surface every triangle edge is a boundary: the filler cannot tell the six real holes from the 400 seams that only look like holes. Welding has to precede decimation because a decimator collapses edges, and it can only collapse edges it can see, so an unwelded mesh gets decimated as hundreds of separate scraps. Decimation has to precede filling because decimation reopens what was filled, which is the 23 open edges left by every order that filled and then decimated. Nothing constrains degenerate face removal because a face with no area contributes no edge that any of the other three operations act on.
The expensive mistake is filling too early
Of the three ways to get it wrong, filling before welding is the one that makes the mesh worse rather than merely leaving it unfixed. It closes the 400 seams as though they were holes and produces 720 non-manifold edges, a defect the damaged mesh did not have: the source had two. Non-manifold edges are harder to fix than holes and several tools will not touch them automatically, so the repair has converted a tractable problem into an awkward one. This matters because filling first is the intuitive move. The holes are the defect you can see.
A closed mesh is not the same as a correct one
Three rows in the table report a single shell with no open edges after decimating first, and they are 1.22 per cent off the correct volume against 0.11 per cent for the orders that work, an eleven fold difference. Watertightness is a yes or no reading and it is the one every tool puts on screen, so it is easy to treat as the finish line. It is not: two results can both be closed and one of them can be a worse copy of the object. The volume column is the one that separates them, and it is only trustworthy once the shell is closed, which is the awkward part.
Why a repair button can leave you worse off
A mesh arriving from a generator or a conversion usually carries several of these defects at once, which is the case this measures. If a tool exposes the operations separately, the order is the user's to get right and 20 of the 24 available choices do not close the mesh. If a tool chains them behind one button, the order is already decided and there is no way to see what it decided. Either way the useful habit is to check for unwelded corners before anything else happens, since that one precedence is upstream of the other two.
How this was measured
An icosphere of 2562 vertices and 5120 faces, scaled to 100 mm across and closed by construction, so the correct answer is known exactly and anything else in the result was introduced by the repairs rather than found by them. It is then damaged four ways at once: six hole patches, each removing a face together with its immediate neighbours so the boundary is a loop rather than a single gap; 400 faces given private copies of their corners, so the surface is split without looking split; two faces built with a repeated corner and therefore no area; and a triangle count higher than the job needs. The damaged mesh reads as 3762 vertices, 2360 boundary edges and 401 separate shells. Every one of the 24 orders is run against that same mesh, and the whole run repeats across four random damage layouts to check that the answer is a property of the operations and not of where the holes happened to land.
- Software and versions
- trimesh 5.1.0, numpy 2.5.2
- Date measured
- 2026-09-14
- Script
scripts/measure-repair-order.py- Raw data
- repair-order-2026-09-14.json
This data is published under CC BY 4.0. Reuse the numbers freely, with a link back so a reader can check the method.
What this does not show
Stated so the result is not read wider than it goes.
- What any named repair tool does. The four operations here are the ones every tool exposes, but Meshmixer, Netfabb, MeshLab and Blender each implement them differently and some chain several of them behind a single button, which is exactly why the order is usually invisible to the person clicking it.
- Whether an automatic hole fill produces the shape the designer wanted. Closing a boundary loop and closing it correctly are different questions, and only the first one is measured here. A large hole spanning a concave region can be closed into a surface nobody intended.
- Meshes whose defects interact with the shape, such as a hole that spans a thin wall or self intersections. The defects here are placed at random on a convex surface, which is the easy case; the ordering result is a lower bound on how much the choice matters.