Skip to content

Restore the double query filter in FastInSphereTesterSoS - #6595

Merged
meshinspector-agent[bot] merged 4 commits into
alpha-shape-triangle-shadowfrom
agent/mlib-insphere-double-filter
Aug 16, 2026
Merged

Restore the double query filter in FastInSphereTesterSoS#6595
meshinspector-agent[bot] merged 4 commits into
alpha-shape-triangle-shadowfrom
agent/mlib-insphere-double-filter

Conversation

@meshinspector-agent

Copy link
Copy Markdown
Contributor

Stacks on #6594 — its two commits are cherry-picked here so this branch builds; they drop out of the diff once #6594 lands in master and this branch takes it.

What changed

FastInSphereTesterSoS regains the floating-point pre-filter it lost in the port to FastInt: reset() computes the sphere's center in double, and every query far enough from the surface is answered by that alone, leaving the exact predicates for the points close to it. Both entry points are filtered again — operator() and outsideBothSpheres — restored as they were before the port, with convert_to<double>()toDouble().

W, M, E are converted, not recomputed in double:

E = 4*rSq*W^2 - |M|^2 = sqr( 2*h*W^2 )

a difference of two values below 2^322 that vanishes exactly when the circumradius reaches the ball radius. It cancels completely on precisely the near-degenerate triangles the filter has to decide, so a from-scratch double sqrt( E*W ) keeps no significant bit and the rSq*2^-44 tolerance is void. InSphereTesterSoS::reset() already has all three exact, and toDouble is correctly rounded, so its share of the error budget is one of the few 2^-53 the tolerance already assumes — the constant does not move. 5 conversions per reset(), none in the candidate loop.

Verification

Built ubuntu22 / GCC 11.4 / Release / Ninja, --target MRTest, prebuilt thirdparty, generated C bindings and legacy python off — clean.

Tests MRTest --gtest_filter='*AlphaShape*:*InSphere*:*PrecisePredicate*:*FastInt*'23/23 passed. The load-bearing one is fastInSphereTesterSoS, which asserts the filtered tester answers identically to InSphereTesterSoS over >10 000 randomized queries at magnitudes 1e2/1e6/1e9, on both spheres and after flip(), plus the four-concyclic-points case where every query is exactly on the sphere and the fast path must always defer.

Stressed on large clouds DISABLED_AlphaShapeBench (40k points; sphere, grid, random), A/B against the same build with MRInSphere.* reverted to the exact-only version — triangle count and hash identical on all three:

cloud triangles hash, filter off → on
sphere 159992 17403291826481596167 → same
grid 158404 635805191690857954 → same
random 8736 11472133144093973002 → same

Not verified here. No timings — this box is not a GitHub-hosted runner, and the measurement is reported only from those. No cross-platform build: this branch is based on alpha-shape-triangle-shadow, and build-test-distribute.yml is gated pull_request: branches: [ master ], so this PR gets no checks; the signal comes from #6566's run after squash-merge. No UI surface, nothing to screenshot.

CI labels

None — no checks run on this base anyway, and the change is neither doc-only nor cross-platform-risky.

The pre-filters that reject a case in double before evaluating it exactly
need a bignum-to-double conversion, which the family lacked: MSVC's
std::_Signed128 has no such operator at all. It is correctly rounded, and
deliberately platform-independent rather than deferring to the built-in
__int128_t conversion, since the stated error bound is what makes those
rejections safe.
mrbind emitted MR_toDouble(__int128 v), which no build accepts: gcc rejects
__int128 in a header compiled with -pedantic-errors, and MSVC has no such
keyword at all. FastInt128 has no C spelling, and the rest of the family is
already ignored for the same reason.
The center was computed exactly only, because the port to FastInt lost the
bignum-to-double conversion the floating-point pre-filter needs; toDouble brings
it back. W, M and E are converted rather than recomputed in double: E is a
difference of two values below 2^322 that cancels completely on exactly the
near-degenerate triangles the filter has to decide.
…er filter

This PR carried MeshLib#6594's first two commits cherry-picked; master's
toDouble has since gained the review round (doubleFromWords over a const
pointer + count in a new MRFastInt.cpp, built-in __int128 off MSVC).
All FastInt files resolve to master's side wholesale, leaving this PR the
MRInSphere.h/.cpp diff it should be; the toDouble( W / M[i] / E ) call
sites are unaffected.
@meshinspector-agent
meshinspector-agent Bot merged commit 937df58 into alpha-shape-triangle-shadow Aug 16, 2026
@meshinspector-agent
meshinspector-agent Bot deleted the agent/mlib-insphere-double-filter branch August 16, 2026 21:03
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.

0 participants