Skip to content

fix: the G^n section's equal-area default thumbweight and the ease's w 0, opt-in (smlib#78 6148773 = 1947a45, 22d258a = adb9854, #2250) - #2261

Merged
bherbruck merged 5 commits into
tangency-labs:mainfrom
brett19:fix/fillet-gn-equal-area
Nov 1, 2026
Merged

bherbruck merged 5 commits into
tangency-labs:mainfrom
brett19:fix/fillet-gn-equal-area

Conversation

@brett19

@brett19 brett19 commented Nov 1, 2026 •

Copy link
Copy Markdown
Collaborator

Units: blend.fillet_section (G^n section), blend.fillet_executive (session, ease), blend.fillet_solver (generator dispatch). Tracking: #2250 (smlib#78).

This PR is stacked on #2260 and uses the same flag, fillet_gn_section_generator (WR-685; addendum plan/upstream-issues/WR-685--addendum-2026-11-01-equal-area-thumbweight.md). It ports two fork commits:

  • 6148773 (= 1947a45 in the history of d01d7b0, the revision SolidCraft pins): the equal area default thumbweight.
  • 22d258a (= adb9854): the ease before a setback keeps thumbweight 0.

Only the fork's source/SMLib behaviour is ported. No capi or SolidCraft code is copied. With the flag off nothing changes.

What is in it

  • section.rs: the default thumbweight is equal area.
    • New constants: GN_THUMBWEIGHT_EQUAL_AREA = -2, and GN_DEFAULT_THUMBWEIGHT = equal area.
    • is_valid now accepts -1 < w < 1, or -2.
    • New functions: equal_area_thumbweight (EqualAreaThumbweight: a bisection of sm_GnSectionAreaIntegral, composite Simpson on 2048 intervals) and resolve_thumbweight (ResolveThumbweight).
    • build resolves the thumbweight at the centre line's middle station; contact_order_at resolves it at its own station. Both follow the fork in operation order.
  • Solvers share the resolved thumbweight (the one structural deviation).
    • In the fork, every solver of one SetFilletParameters shares one SmGnSectionFSG. The first blend built writes the resolved thumbweight into its mutable member, so every edge gets the first blend's wedge.
    • The port's solvers hold copies, so I reproduced that sharing:
      • GnSectionFsg::shared records which session generator a copy came from.
      • create_surface_replacing_uv now works on the solver's own generator (fillet_surface_generator_mut).
      • After each solver's CalcFilletGeom (its first build), the session hands the resolved value to the generator and to every unresolved copy (share_gn_thumbweight).
    • ContactOrderAt reaches the generator through an immutable borrow. It resolves on a copy it does not keep, but its generator is already resolved by then, because the blend is built before its side faces' ribs.
  • ease.rs: EaseSetBackSections builds its order-2 target at w = 0 (adb9854).

Checked against the fork

I built fork d01d7b0 locally (SMLib and SM_API only, with the harness's flags and -ffp-contract=off). The scratch drivers are not committed. The eased setback is driven through SmFilletExecutive in the same call order as the Rust test.

case Rust fork d01d7b0 rel err
EqualAreaThumbweight, n 2..4 x 6 wedges (0.3 to 3 rad) bit-identical; same refusals 0
box edge r 3, equal area, n 2 23922.7433394661 23922.743344462557 2.1e-10
box edge, n 3 23922.7433411157 23922.743341082103 1.4e-12
box edge, n 4 23922.7433411275 23922.743340991368 5.8e-12
box corner, three edges r 3, equal area 23829.6524969874 23829.652499315507 9.8e-11
box corner, w 0 23876.3619293612 23876.361929859548 2.1e-11
chamfered box: 135-degree edge, then 90-degree edge 23468.1839014115 23468.183912205881 4.6e-10
the same two edges, 90-degree first 23461.4980148861 23461.498019658513 2.0e-10
135-degree edge alone 23496.5576826813 23496.557686573007 1.7e-10
90-degree edge alone 23465.6637062614 23465.663708708515 1.0e-10
40 mm box corner r 8, setback 12, ease 4 62375.6826245161 62375.682794873181 2.7e-9
the same, ease 0 62279.3329096180 62279.332678480074 3.7e-9

The volumes are not bit-identical, for two reasons:

  • These are whole-fillet runs, and some of the fork's other changes there are not in the port.
  • The volume integrator runs at 1e-7 (1e-6 for the eased corner).

At a square corner, order 2, the fork gives w = -0.52521240458756147. The figure -0.5252123889 quoted from SolidCraft differs from it by 3e-8, so the tests use the fork's value.

Regression tests

The tests are in crates/solidcore/tests/wr685_gn_section.rs and blend::fillet_section::section::tests:

test expected value how it was checked without the fix
equal_area_thumbweights_are_the_fork_s (unit) 15 thumbweights and 6 refusals; the area at a square corner is 1 - pi/4 to 1e-12; resolve keeps the first value fork d01d7b0, bit for bit; closed form does not compile (no equal_area_thumbweight)
box_edge_equal_area_round_takes_off_the_circle_s_area 24000 - 360 (1 - pi/4), n 2..4, rel 1e-7; w = -1 refused closed form; fork d01d7b0 to 2.1e-10 -2 is refused (is_valid)
box_corner_equal_area_rounds_take_the_fork_s_volume the fork's two volumes fork d01d7b0 to 9.8e-11 -2 is refused
equal_area_thumbweight_is_the_first_blend_s_for_every_edge the fork's four volumes, order-dependent fork d01d7b0 to 4.6e-10 fails with the sharing removed: 23462.22 against 23468.18, measured
eased_setback_takes_the_order_2_section_at_thumbweight_0 the fork's two eased-corner volumes fork d01d7b0 to 3.7e-9 fails with the default as the ease's target: 62281.46 against 62375.68, measured

form_is_the_section_of_its_definition now also covers negative thumbweights.

Completion evidence

Operation / upstream symbols Implementation Successful native comparison Remaining gap
EqualAreaThumbweight, sm_GnSectionAreaIntegral complete bit-identical with fork d01d7b0 none
ResolveThumbweight in Build / ContactOrderAt, shared across solvers complete; sharing via the session (deviation above) box edge, corner and two-wedge volumes against d01d7b0 ContactOrderAt keeps no resolution it makes itself (its generator is resolved already)
IsValid (-1, 1) or -2 complete refusals tested none
EaseSetBackSections: target at w 0 complete eased setback corner against d01d7b0 none

The pinned C++ has no G^n generator, so the native difftest compares only the default, flag-off path. That path is unchanged:

PASS blend.fillet_solver_p1 cases=351 passed=351 failed=0 deferred=0 max_rel_err=0e0 with_values=351 no_values=0 vacuous=0
PASS blend.fillet_solver_p2 cases=311 passed=311 failed=0 deferred=0 max_rel_err=6.447848034425354e-16 with_values=311 no_values=0 vacuous=0
PASS blend.fillet_solver_p4 cases=651 passed=651 failed=0 deferred=0 max_rel_err=0e0 with_values=651 no_values=0 vacuous=0
PASS blend.fillet_intersector cases=1292 passed=1292 failed=0 deferred=0 max_rel_err=0e0 with_values=1292 no_values=0 vacuous=0
PASS blend.fillet_corner_p1 cases=308 passed=308 failed=0 deferred=0 max_rel_err=0e0 with_values=290 no_values=18 vacuous=0
PASS blend.fillet_corner_p2 cases=630 passed=606 failed=0 deferred=0 max_rel_err=0e0 with_values=595 no_values=11 vacuous=0 rejected=24
PASS blend.fillet_executive_p2 cases=278 passed=278 failed=0 deferred=0 max_rel_err=0e0 with_values=275 no_values=3 vacuous=0
PASS blend.fillet_executive_p3 cases=788 passed=786 failed=0 deferred=0 max_rel_err=0e0 with_values=786 no_values=0 vacuous=0 rejected=2
PASS blend.fillet_geom_p5 cases=300 passed=300 failed=0 deferred=0 max_rel_err=0e0 with_values=300 no_values=0 vacuous=0

The full local gate (fmt, clippy, clippy-cpp, tests, test-opt, wasm, runner tests and the difftest above) passes at 716af66. scripts/ci/check_record_ids.py passes.

Out of scope

🤖 Generated with Claude Code

https://claude.ai/code/session_01SdcgEtwSrdwZxqTQp5MfnU

brett19 and others added 2 commits November 1, 2026 20:56
…s solvers; the ease keeps 0 (WR-685, smlib#78 6148773 = 1947a45, 22d258a = adb9854, tangency-labs#2250)

Under fillet_gn_section_generator: SM_GN_THUMBWEIGHT_EQUAL_AREA (-2) is the default
thumbweight, resolved once per generator by EqualAreaThumbweight (a bisection of
sm_GnSectionAreaIntegral) from the wedge at the first blend's middle station or at
ContactOrderAt's; thumbweights run over (-1, 1). The fork's solvers share one
generator, so the session hands a resolved thumbweight to the generator and every
solver's copy after each CalcFilletGeom. EaseSetBackSections builds its order-2 target
at w = 0.

Checked against fork d01d7b0 built locally: EqualAreaThumbweight bit-identical over
orders 2-4 and six wedges; box edge, box corner, two-wedge (both orders) and eased
setback volumes within 3.7e-9 relative.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SdcgEtwSrdwZxqTQp5MfnU
@brett19 brett19 changed the title fix: equal-area curvature thumbweight and eased setback, opt-in (smlib#78 6148773, 22d258a, #2250) fix: the G^n section's equal-area default thumbweight and the ease's w 0, opt-in (smlib#78 6148773 = 1947a45, 22d258a = adb9854, #2250) Nov 1, 2026
@brett19
brett19 marked this pull request as ready for review November 1, 2026 20:35
@brett19

brett19 commented Nov 1, 2026

Copy link
Copy Markdown
Collaborator Author

Ready, stacked on #2260. EqualAreaThumbweight is bit-identical with fork d01d7b0 built locally. Volumes agree with the fork to at most 3.7e-9 rel: box edge, corner, two wedges in both orders (order-dependent, as in the fork), eased setback. The local gate passes.

@bherbruck bherbruck left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed: opt-in under #2260's flag, flag-off unchanged, fork-checked. It conflicts with main now; once it's merged with main and CI is green it goes into the queue.

brett19 added a commit to brett19/solidcore-fork that referenced this pull request Nov 1, 2026
…step 7

Step 7 builds on the G^n section and its certificate (tangency-labs#2260, tangency-labs#2261, tangency-labs#2262).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SdcgEtwSrdwZxqTQp5MfnU
…illet-gn-equal-area

Doc-only conflict in the fillet_gn_section_generator flag docs: keeps this
branch's equal-area paragraph and main's variable-round paragraph.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SdcgEtwSrdwZxqTQp5MfnU

@bherbruck bherbruck left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-approved automatically: the commits since the last approval (716af66..f9ac2a3) touch no CI/build files and add no red-flag patterns.

…s generator

After merging main, tangency-labs#2262's fold check in CreateSurface read
this_ang_tol_rad and this_approx_tol_3d through the solver while this
branch holds its generator mutably (for the shared equal-area
thumbweight). Both values are now read first; nothing else changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SdcgEtwSrdwZxqTQp5MfnU

@bherbruck bherbruck left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-approved automatically: the commits since the last approval (f9ac2a3..bb5d525) touch no CI/build files and add no red-flag patterns.

@bherbruck
bherbruck merged commit 1155937 into tangency-labs:main Nov 1, 2026
13 checks passed
brett19 added a commit to brett19/solidcore-fork that referenced this pull request Nov 1, 2026
p1 (b9d6a72) and p2 (7102bc5) change the equal-area thumbweight tangency-labs#2261 ports.
kernel.rs: the flag doc takes tangency-labs#2261's first paragraph and keeps main's
variable-round paragraph.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SdcgEtwSrdwZxqTQp5MfnU
brett19 added a commit to brett19/solidcore-fork that referenced this pull request Nov 1, 2026
…to step 7

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SdcgEtwSrdwZxqTQp5MfnU
brett19 added a commit to brett19/solidcore-fork that referenced this pull request Nov 1, 2026
… one resolved at every station, opt-in (WR-685, smlib#79 b9d6a72, 7102bc5, tangency-labs#2273)

Under fillet_gn_section_generator, the step 7 prerequisites p1 and p2:
- b9d6a72: IsValid takes any finite w < 1; SM_GN_THUMBWEIGHT_EQUAL_AREA is 2;
  EqualAreaThumbweight's bracket steps down from -1 to -1000.
- 7102bc5: each station takes the equal area thumbweight of its own wedge and
  its s-derivative (sm_GnStationThumbweight); the surface interpolates the
  normalized form's homogeneous rows; the certificate bounds their remainder
  (sm_GnRowTermsOver, sm_Centred, sm_GnAreaCells). New tay.rs (sm_Tay and the
  area/target series); form.rs is ring-generic (sm_Binom, sm_GnFormT,
  sm_GnFormNormalized); sm_GnEvaluate returns V; ContactOrderAt takes its
  station's ThumbweightAt. The generator's thumbweight is no longer written, so
  tangency-labs#2261's shared-thumbweight plumbing goes.

Checked against fork 7102bc5 built locally: EqualAreaThumbweight bit for bit
(n 2-4, 8 angles), blend nets within 1e-9 and volumes within 1e-7 on the box
edge, the chamfer and box edges in both orders, and the pipe on a plate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SdcgEtwSrdwZxqTQp5MfnU
brett19 added a commit to brett19/solidcore-fork that referenced this pull request Nov 1, 2026
p4.rs: kept this branch's removal of the circular section's sm_BallsFold
check (the fork's 410dfe1 replaced it by BallIsRegular), on main's mutable
generator access from tangency-labs#2261.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SdcgEtwSrdwZxqTQp5MfnU
brett19 added a commit to brett19/solidcore-fork that referenced this pull request Nov 1, 2026
brett19 added a commit to brett19/solidcore-fork that referenced this pull request Nov 2, 2026
…nd-step6-overflow

Step 6 builds on the generic-blend section and variable rounds of tangency-labs#2260/tangency-labs#2261/tangency-labs#2262.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SdcgEtwSrdwZxqTQp5MfnU
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.

2 participants