Restore the double query filter in FastInSphereTesterSoS - #6595
Merged
meshinspector-agent[bot] merged 4 commits intoAug 16, 2026
Merged
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
FastInSphereTesterSoSregains the floating-point pre-filter it lost in the port toFastInt:reset()computes the sphere's center indouble, 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()andoutsideBothSpheres— restored as they were before the port, withconvert_to<double>()→toDouble().W,M,Eare converted, not recomputed indouble:a difference of two values below
2^322that 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-scratchdoublesqrt( E*W )keeps no significant bit and therSq*2^-44tolerance is void.InSphereTesterSoS::reset()already has all three exact, andtoDoubleis correctly rounded, so its share of the error budget is one of the few2^-53the tolerance already assumes — the constant does not move. 5 conversions perreset(), 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 isfastInSphereTesterSoS, which asserts the filtered tester answers identically toInSphereTesterSoSover >10 000 randomized queries at magnitudes 1e2/1e6/1e9, on both spheres and afterflip(), 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 withMRInSphere.*reverted to the exact-only version — triangle count and hash identical on all three:17403291826481596167→ same635805191690857954→ same11472133144093973002→ sameNot 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, andbuild-test-distribute.ymlis gatedpull_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.