Skip to content

Fix chamfered crisp edges: anchor the QEM quadric solve at the edge midpoint#78

Merged
kmatzen merged 1 commit into
mainfrom
fix-crease-chamfer
Jul 26, 2026
Merged

Fix chamfered crisp edges: anchor the QEM quadric solve at the edge midpoint#78
kmatzen merged 1 commit into
mainfrom
fix-crease-chamfer

Conversation

@kmatzen

@kmatzen kmatzen commented Jul 26, 2026

Copy link
Copy Markdown
Owner

Problem

After #77, exported meshes show defects along crisp edges: corners visibly chamfered / cut off, even though every vertex sits exactly on the surface and the mesh is watertight.

Root cause is in simplifyMesh's collapse-target solve. Along a straight crease the combined quadric is rank 2 — every point on the crease line has identical (zero) cost — so the raw determinant inverse in optimalQ was ill-conditioned there and let collapse targets slide arbitrarily far along the crease line. Vertices ended up out of order along the edge, and the triangulation chamfered across the corner. The surface-snap pass can't repair it because nothing is off the surface.

Measured on an axis-aligned box at res 128 (max distance from the true crease lines to the mesh, point-to-triangle):

stage before after
raw dual contour 0.0000 0.0000
+ error-bounded simplify 1.6398 0.0000
+ surface snap 1.6398 0.0000

The rotated box mostly escaped (0.005) because float noise conditions the system — which is why the existing rotated-corner test didn't catch it.

Fix

Replace the determinant solve with the same truncated-eigen pseudo-inverse the contouring QEF already uses, extracted from qef.ts as solveSymmetric3Anchored, anchored at the edge midpoint: rank-deficient directions keep the midpoint coordinate instead of being dragged by noise, which also preserves vertex ordering along a crease. A guard falls back to endpoint/midpoint candidates if the solved point ever lands far outside the edge's own neighborhood.

Cost: crease-adjacent regions decimate less aggressively (box at res 128: 434 → 1828 triangles). Flat-face decimation is unaffected.

Tests

  • New regression test: dual contour → error-bounded simplify on a box, asserting max point-to-triangle distance from all 12 true crease lines stays under half a voxel (was ~1.6 before the fix).
  • 258/258 tests pass, tsc --noEmit clean.

🤖 Generated with Claude Code

…e chamfering

The optimal-point solve in QEM collapse used a raw determinant inverse
with an absolute singularity threshold. Along a straight crease the
quadric is rank 2 - every point on the crease line has identical cost -
so the solve was ill-conditioned and collapse targets slid arbitrarily
far along the edge line. Vertices ended up out of order along the
crease and the triangulation chamfered across corners: every vertex
still exactly on the surface, mesh watertight, but crisp edges visibly
cut off (measured 1.64 units of crease deviation on an axis-aligned box
at res 128; zero after this change).

Replace it with the same truncated-eigen pseudo-inverse the contouring
QEF uses (extracted as solveSymmetric3Anchored), anchored at the edge
midpoint so rank-deficient directions keep the midpoint coordinate,
plus a fallback to endpoint/midpoint candidates if the solved point
lands far outside the edge neighborhood. Costs slightly higher triangle
counts near creases (box at res 128: 434 -> 1828 tris) in exchange for
exact edges.

Adds a regression test measuring true crease-line coverage (max
point-to-triangle distance) through dual contour + error-bounded
simplify on a box.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

🚀 Preview deployed: https://fix-crease-chamfer.sinter.pages.dev

(updates on every push to this PR)

@kmatzen
kmatzen marked this pull request as ready for review July 26, 2026 02:41
@kmatzen
kmatzen merged commit c12996d into main Jul 26, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant