← report · parts, clean 10k (renders of A and B) · middle slices
Fitted contours on point clouds: A vs B
2026-10-28 · clean 10k clouds (pointclouds/*_clean_10000.ply) · prototypes in scripts/ringfit.py, package untouched ·
slices: scripts/compare_slices.py, tables: report/ringfit_table_clean_10000.txt.
Verdict. Neither is a win yet. A works and is safe, but it only cleans the geometry of rings whose topology the
slicer already decided, so it cannot reduce the parts: its counts and errors stay within a few percent of the package. B is the only
one that attacks the cause (the topology of thin walls), but as built it is not usable: it loses whole layers and draws wild contours,
with 3–10× the package's error. B is the more promising direction, A the more mature component; the useful product is probably B's
topology with A's fitting, once B gets a proper 2D curve reconstruction instead of the angle ordering used here.
What the two do
Both replace the slicer's traced polylines with contours fitted to the points: for every layer, the points within a spacing of the plane
are moved onto it along the surface (a point is used only when that move is under ¾ spacing, so slanted and near-horizontal surfaces count
only near the plane), each contour is x(t), y(t) with Neff = min(16, (n/3 − 1)/2) harmonics for its n points (regularised
by the point count, plus a light ridge on the high harmonics), and each point's t comes from its projection on the current fit (4 rounds).
The fitted contours then go through the package's tracking, cuts and atom selection unchanged.
- A, slicer topology: the slicer's rings decide how many contours a layer has, which are holes, and which points belong to each
(nearest ring, on its face by the oriented normal); only the shape is refitted.
- B, point sheets: no slicer field. Points within 3 spacings whose normals do not face opposite ways are joined into sheets (a
thin wall's two faces stay apart); a sheet that closes around its centre (angular gap under 120°) becomes a contour, parametrised first
by the angle around its centre; solid or hole from whether its normals point away from or towards the centre.
Results, clean 10k
tracks / parts / mean distance over the diagonal (×10⁻³). Mesh parts for reference. Red: error ≥ 2× the package's.
| object | mesh parts | package | A ringfit | B graph |
| battery | 4 | 3 / 6 / 3.46 | 3 / 5 / 3.55 | 10 / 17 / 26.3 |
| dress | 17 | 10 / 17 / 3.19 | 14 / 22 / 3.43 | 10 / 21 / 10.4 |
| elephant | 27 | 25 / 32 / 4.29 | 26 / 31 / 4.15 | 7 / 17 / 21.1 |
| bowl (ObjectFolder) | 5 | 12 / 14 / 2.69 | 12 / 14 / 3.20 | 7 / 13 / 26.3 |
| bowl (GSO) | 6 | 18 / 20 / 2.75 | 18 / 20 / 3.16 | 15 / 20 / 28.2 |
| mug | 8 | 9 / 13 / 3.00 | 8 / 12 / 3.00 | 8 / 17 / 14.0 |
| dino | 25 | 18 / 27 / 2.47 | 19 / 28 / 2.65 | 19 / 28 / 11.1 |
| shoe | 22 | 17 / 30 / 7.74 | 15 / 30 / 7.88 | 23 / 36 / 14.3 |
| loaf pan | 7 | 56 / 74 / 16.6 | 52 / 68 / 16.3 | 33 / 36 / 27.9 |
| horse | 18 | 9 / 16 / 2.33 | 9 / 19 / 2.39 | 16 / 26 / 9.6 |
B's lower part counts on the loaf pan (36) and the elephant (17) are not progress: they come from layers it lost, not from better
tracking — the errors show it.
What the slices show
Each comparison page shows, per layer, the slicer's rings, A and B over GT (black) and the slab's points (grey):
GSO bowl · loaf pan ·
battery · dino ·
shoe.
A: clean shapes, the slicer's topology
- It removes the hooks. Where the slicer's ring is right but ragged, A's ring is smooth and lies on GT: GSO bowl layer 114, loaf pan
13, 29 and 44, battery 85 and 100 (the latch step is kept). This is what the ring fit was for: N follows the points, not 512 resamples of a
traced line.
- It inherits every topology error. Where the slicer opens the loaf pan's wall into a C (layer 60), A fits one ring to both faces: a
twisted C. Where the slicer fragments the bowl's rim (118) or the battery's top (122), A fits each fragment. Tracks are the slicer's, so the
parts barely move.
- It adds a few artefacts. A spike at the bowl's 116 and the loaf pan's 99: points assigned to the wrong ring (the nearest-ring
assignment fails where the slicer's rings are themselves wrong). Corners are slightly rounded (battery), as N ≤ 16 always does. Net: error
+0–15 %, mostly from these spikes.
B: the right idea, a fragile implementation
- When the sheet is closed and roughly convex, it is excellent. GSO bowl layers 20–100 (both faces of the wall, as two clean
contours), battery 20, 60, 115: as good as A, with no slicer at all.
- Failure 1, lost layers. A sheet broken by a gap wider than the link, or with a few wrongly oriented normals, does not close and is
dropped: the loaf pan's 13 and 44 and the bowl's rim (114–118) have no contour at all. A layer with no contour is a hole in the object,
hence the large errors.
- Failure 2, wild contours. The angle around the centre is a poor first parameter when the sheet is not star-shaped around its
centre, is elongated, or has stray points: battery 85 (the step) and 100, loaf pan 29, 60 and 99 show loops far outside the object.
- Failure 3, thin crescents. The rim's section is a thin crescent: an outer arc and an inner arc that close only together. B's
sheets are the two arcs, neither closes, both are dropped.
- Failure 4, false holes. On non-convex sections the mean of n·(p − c) can come out negative and a solid becomes a hole (dino, mug,
shoe: 9–18 holes against 0–8).
Which is more promising
B, but not as it stands. Everything A can do is bounded by the slicer's topology, and the topology is the problem: at 10k the excess
parts are tracks (GSO bowl 18 against 3, loaf pan 56 against 2), which no fitting of shapes removes. B is the only one of the two that can
fix them, and on the layers where its sheets close it already does. Its four failures are all in the parts I simplified, not in the idea:
- the order of a sheet's points: replace the angle around the centre by a real curve reconstruction of the slab's points with normals
(e.g. the nearest-neighbour crust, or a shortest cycle through the sheet's k-NN graph), which handles non-convex, elongated and stepped
sections;
- open sheets: pair the two faces of a thin wall (opposite normals, a wall's width apart) into one ring (the crescent), and close a sheet
across a gap under a few spacings instead of dropping it;
- solid or hole from the orientation of the reconstructed curve (signed area against the normals), not from the centre;
- a fallback per layer to A (the slicer's topology) where B's contours do not explain the points, so B can never lose a layer.
The honest risk: at 10k some walls are thinner than the spacing (47 % of the loaf pan's surface). There even a perfect reconstruction
relies on the normals alone to separate the faces, and where the slicer's normals are wrong, B is wrong too. A's fitting step is worth keeping
either way: it is the right last stage for whichever topology wins.