Skip to content

difftest: own imported geometry under the harness's keys (brep_p6, merge_p2) - #618

Merged
bherbruck merged 3 commits into
tangency-labs:mainfrom
erlis:difftest/geometry-owners
Oct 23, 2026
Merged

bherbruck merged 3 commits into
tangency-labs:mainfrom
erlis:difftest/geometry-owners

Conversation

@erlis

@erlis erlis commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Two difftest runners import B-reps whose geometry owners don't match the names the runner hands the library. The topology solver depends on those owners:

  • BrepObjects::curve_edge finds an edge from its curve's owner;
  • BrepCache::build_trees adds an edge or face to the solver trees only when its curve's or surface's owner equals the caller's key.

In the C++ fixtures an edge owns its curve and a face its surface, so the inputs differed.

topology.brep_p6, op 3 MakeFaceTopology

  • The import owns face surfaces under the runner's key_of names but leaves edge curves unowned.
  • In cube_faces_6, the infinite-region ray from (1.50002)³ hits the edge y=1,z=1 at t=0.9427. The C++ solves it there, which sets best² = 0.8888 and prunes the x=0 and y=0 face boxes.
  • Rust skips that edge (curve_edge is None), so it classifies face x=0 and creates 4 UV trims the C++ never makes.
  • Fix: own every edge curve under key_of(Edge).

boolean.merge_p2, MergeEdge / MakeFaceuse

  • p5::import owns the operands' geometry under arena identities (edge i → key i), but the runner names entities with the copy keys (edge i → 2 000 000 + i, face i → 4 000 000 + i).
  • MakeFace's infinite-region rays use those names, so their tree held no edges and only the new face, and the shell rays failed with edge owner is not in source B-rep.
  • The C++ solves the hit edge, treats the ray as ambiguous and fires the 0.789 / 0.189 retries.
  • Fix: own both operands' curves and surfaces under the copy's destination and source names.

util::own_edge_curves / own_face_surfaces take the names; own_arena_geometry now calls them with arena identities (unchanged behaviour).

Results (Linux, pinned reference c9c5979; tolerances and fixtures unchanged)

This branch (merged with main 7935b4c):

PARTIAL topology.brep_p6 cases=595 passed=586 failed=0 deferred=9 max_rel_err=0e0 with_values=586 no_values=0 vacuous=0 blocked_by=topology.edgeuse_p3(9)
PARTIAL boolean.merge_p2 cases=45 passed=42 failed=0 deferred=3 max_rel_err=0e0 with_values=42 no_values=0 vacuous=0 blocked_by=curve.curve_p2(1),topology.face_p2(2)
  • merge_p2 make_faceuse_square_to_make_face and make_faceuse_circle_region_given move from topology.edgeuse_p3 (GetOrCreateUVTrimCurve, read-only refusal) to topology.face_p2 SmFace::GetTolerance and curve.curve_p2 SmCurve::GetNaturalInterval. No other case of either unit changed.
  • The other own_arena_geometry runners show no change on any case: query.brep, boolean.merge_p1, topology.brep_p2, boolean.merge_p5.

With #613 (shell ray fires create the missing trims), on main + #613:

FAIL topology.brep_p6 cases=595 passed=586 failed=2 deferred=7   (cube_faces_6, cube_faces_6_reversed)

and on main + #613 + this branch:

PARTIAL topology.brep_p6 cases=595 passed=588 failed=0 deferred=7 max_rel_err=0e0 with_values=588 no_values=0 vacuous=0 blocked_by=topology.edge(7)
PARTIAL boolean.merge_p2 cases=45 passed=42 failed=0 deferred=3 max_rel_err=0e0 with_values=42 no_values=0 vacuous=0 blocked_by=curve.curve_p2(1),topology.face_p2(2)

Checks (after merging main 7935b4c): cargo fmt --all --check; cargo clippy --workspace --all-targets -- -D warnings; cargo clippy -p difftest -p solidcore-ffi --features difftest/cpp --all-targets -- -D warnings; cargo test -p difftest --features cpp (258 passed); difftest --unit for the 7 units above. No library code changed.

How it was found: a gdb trace of the C++ reference (SmTopologySolver::MayContainAnswer, SmTLSPointEdge/Face::SolveIt, SmFace::PointClassify) next to a traced Rust run, while looking at the cases #541 moved to the read-only trim refusal.

🤖 Generated with Claude Code

erlis and others added 2 commits October 23, 2026 08:53
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rge_p2)

The topology solver finds an edge from its curve's owner, and the B-rep cache
trees hold only the curves and surfaces whose owner equals the name the caller
hands the library. Two runners imported geometry under other names:

- topology.brep_p6 MakeFaceTopology left edge curves unowned, so the
  infinite-region rays skip the edge the C++ hits first and classify a face the
  C++ prunes (cube_faces_6, cube_faces_6_reversed, once trims are created).
- boolean.merge_p2 MergeEdge/MakeFaceuse owned the operands under arena
  identities but names entities with the copy keys, so MakeFace's rays saw no
  edges and one of two faces (make_faceuse_*).

util::own_edge_curves / own_face_surfaces take the names; own_arena_geometry
uses them with arena identities.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@erlis
erlis marked this pull request as ready for review October 23, 2026 13:56
@bherbruck
bherbruck added this pull request to the merge queue Oct 23, 2026
Merged via the queue into tangency-labs:main with commit 68ab8bb Oct 23, 2026
7 checks passed
henlamp added a commit to henlamp/solidcore that referenced this pull request Oct 23, 2026
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