Commit Graph

2088 Commits

Author SHA1 Message Date
Brett Lawson e46bbde814 query.face_p4: call GetLoopCrossings for the loop bisector in ClassifyLoops
SmFace::ClassifyLoops still returned Unported for a target loop that crosses
no seam, although SmCurveClassification::GetLoopCrossings is ported. Call it
with the target loops, the face props and the bisector's classification, as
upstream does; its status stays ignored.

The query.face_p4 runner now also exports the face props the bisector and
GetLoopCrossings read (zone tolerance, no-vertex poles, pole points, missing
seam direction). Faces whose surface or loop edge curves the importer cannot
reproduce exactly report inexact_geometry on both sides when ClassifyLoops
may evaluate them, decided from the export as unit query.face_p3 does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 22:47:46 -07:00
denelson1-dot d2b0cc531e Merge branch 'main' of https://github.com/tangency-labs/solidcore into fix/521-vertex-undef-tangent 2026-10-23 22:42:36 -04:00
denelson1-dot f3df18881f plan: renumber this PR's entry WR-256 (#703 took WR-255 on main)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 22:17:54 -04:00
denelson1-dot c0d77ea329 Merge branch 'main' of https://github.com/tangency-labs/solidcore into fix/521-vertex-undef-tangent 2026-10-23 22:17:36 -04:00
Brett Lawson 0c1f499545 Merge remote-tracking branch 'origin/main' into fix/face-p1-ub137-rejected 2026-10-23 19:14:25 -07:00
Brett Lawson d3f79a40fa difftest: face_p1 UB-137 crash-trap cases are rejected, not deferred
A seam call whose forked child crashes (or that the shim cannot fork for)
is an input undefined in C++ (UB-137), so face_p1's run_cpp now returns
Output::rejected naming UB-137 and the trap: the Rust side is not run and
nothing is compared. The generic runner no longer lets a C++-side deferral
win; a deferral from run_cpp is a harness error, so deferrals are decided
by the Rust side only. The runner test for the removed path now checks
both behaviours.

face_p1: 2315 cases, 2276 pass, 0 deferred, 37 rejected, 2 known
mismatches (was 37 deferred to cpp-crash-guard:UB-137).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 19:00:46 -07:00
bherbruck 6cf5b4978f Merge pull request #702 from denelson1-dot/wire/fillet-geom-solver-p3-stubs
wire: blend.fillet_geom_p3 corner calculators and GetOtherFilletCorner (follow-up to #236, #242)
2026-10-24 01:55:12 +00:00
denelson1-dot fb0aec152c fix: a failed end tangent reads SmVector3d's UNDEF default, as upstream (#521)
At c9c5979 SmVector3d defaults to SM_UNDEF_DOUBLE, so the tangent a failed
GetEndTangent leaves in SmVertex::AreEdgesTangent / IsTopologicalVertex is
defined: AngleBetween reports 0 and both answer TRUE. The port returned
InvalidInput there and the topology.vertex shim refused the input. Read
Vec3::UNDEF instead, refuse only a null curve in the shim, and record WR-255
(correcting UB-106) plus the per-site #521 audit in findings.

70 compared cases in fixtures/topology.vertex/end_tangents.json (zero end
tangents, 1e-30 end spans) and a unit test on a composite-curve edge, whose
evaluation always fails.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 21:51:30 -04:00
denelson1-dot 03a6e27f88 wire: blend.fillet_geom_p3 corner calculators and GetOtherFilletCorner
Follow-up to #236 and #242: the three stubs on main that still named
blend.fillet_geom_p3 / blend.fillet_solver_p3.

- FilletCorner::calc_corner_vert_geom calls FilletBrep::calc_corner_vert_geom.
- FilletCorner::calc_corner_edge_geom calls the new
  FilletBrep::calc_corner_edge_geom_of_corner, which resolves the edge's
  corner to the calling corner (upstream asserts it is its own).
- ExecutiveAccess::solver_other_corner becomes a required adapter that
  delegates to FilletSolver::other_fillet_corner, like solver_corner; the
  runners and p3_tests refuse it as they refuse solver_corner.

The fillet_corner_p1 shim runs CalcCornerVertGeom / CalcCornerEdgeGeom on
corners with vertices / edges now (fixtures); generated corners keep empty
lists, since random models crash upstream's per-type calculators.
fillet_corner_p1: 173/174 passed, 0 failed, 1 deferred (was 170, 4).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 21:37:58 -04:00
Brett Lawson 480e258094 Merge remote-tracking branch 'origin/main' into stack/face-p1-ub137-fork-trap-on-main
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 18:16:43 -07:00
Brett Lawson 7fb233bf18 Merge remote-tracking branch 'origin/main' into stack/face-p1-ub137-fork-trap-on-main
# Conflicts:
#	plan/units/topology.face_p1.toml
2026-10-23 17:25:56 -07:00
Brett Lawson 4fe4e33246 Merge branch 'main' into recover/trans-sweep-face-fixture 2026-10-23 17:10:21 -07:00
Brett Lawson 7ce3af1b35 difftest: trans_sweep_geometry op 8 makes its face with CreateFaceFromSurface
The FaceSweepSame fixture built its face natively with
SmBrep::CreateFaceFromSurface but in Rust as a bare face record, and a
failed native CreateFaceFromSurface was recorded as a rejected fixture.
The Rust runner now calls topology::brep::p8::create_face_from_surface on
a B-rep with its infinite region, and the shim returns the failed status
as the case output. The 11 cases that were rejected for it now compare
SM_ERR on both sides; gen0411 now defers on the face-owned surface cache
of a shell ray fire, so the unit is partial.

Also explains in findings.md the small fixture rejections in
blend.fillet_geom_p3, boolean.merge_p4 and offset.offset_executive_p2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 16:57:48 -07:00
Brett Lawson ae47be0e82 Merge origin/main into the shell ray face geometry branch
Carries #613 onto main bcc2f80be. Conflicts:
- primitive/api_primitives.rs: keep main's comment on the torus point
  classification; with #613's prepared trim cache the partial torus now
  builds, so the test asserts a manifold solid instead of a deferral.
- plan/units notes (api_primitives, primitive_creation_p1, query.brep,
  topology.brep_p10): keep main's CI status prefix and #613's update text.

query/face/p2.rs merged cleanly: main's WithMadeTrimCurves and mutable
face queries stay alongside #613's prepared-cache point classification.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 15:52:04 -07:00
bherbruck 82fb6910aa Merge pull request #671 from brett19/stack/topology-edge-on-main
port: topology.edge (stacked on #596, merged with main)
2026-10-23 21:31:44 +00:00
bherbruck 776a04e376 Merge pull request #669 from tdamsma/codex/face-uv-domain-attempt
fix: preserve partial UV-domain outputs on calculation failure
2026-10-23 21:21:40 +00:00
Brett Lawson fd833525f7 Merge origin/main into stack/topology-edge-on-main
Brings #596's topology.edge exact-surface transport up to date with main,
including the offset gen0730 importer fix. Merged without conflicts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 14:14:49 -07:00
Thijs Damsma b0d70d9f9c Merge current main into face UV-domain output fix
Co-Authored-By: OpenAI Codex <noreply@openai.com>
2026-10-23 22:44:00 +02:00
Thijs Damsma 8503a6d7cc fix: retain partial face UV-domain outputs
Expose initialized output on error without changing the existing Result API. Compare actual native output with real shifted-trim failure and success fixtures.

Co-Authored-By: OpenAI Codex <noreply@openai.com>
2026-10-23 22:43:48 +02:00
bherbruck 1ba79426ff Merge pull request #658 from brett19/fix/g5-fillet-law
wire: fillet law in EvaluateLawPoint; DoLawIntersection on SmFilletIntersector (surface_intersector_p2/p3, fillet_standard_solver_p2 green)
2026-10-23 20:42:06 +00:00
Henrik Lampe c287538553 Merge remote-tracking branch 'origin/main' into codex/primitive-integration 2026-10-23 22:40:49 +02:00
bherbruck 37bf197b4e Merge pull request #666 from oursland/difftest/topology-tracker-lists
difftest: compare topology change-tracker chg lists and events
2026-10-23 20:37:07 +00:00
Brett Lawson ea817b7c4d wire: fillet law in EvaluateLawPoint and DoLawIntersection on SmFilletIntersector
- SurfaceIntersector::evaluate_law_point takes &mut FilletLaw, evaluates it and sets
  the shared offset surfaces' distances (the stale dispatch-gap stubs are gone).
- DoLawIntersection / SplitSpan / ComputeLawPointValues are generic drivers over
  IntersectorVirtuals, which gains EvaluateLawPoint, ComputePointValuesDelta and
  TestSpanAccuracy; FilletIntersector::do_law_intersection dispatches them to the
  fillet intersector's overrides. DoLawIntersection's guesses alias the end points'
  own UVs, as upstream (LawGuess::PointUvs).
- SmVariableRadiusFS: SetEdgeArcLength wired, impl FilletSolverOps, and
  ReCalcFilletGeom runs DoLawIntersection on its SmFilletIntersector.
- IntersectorSolver keeps base extensions in step between the solver's offsets and
  the intersector's copies (OffsetSurface::follow_extension_of), as upstream's one
  object does.
- Runners pass the shim's base SmFilletLaw; std_solver_p2's no-geometry recalc
  cases keep the constructor's default fillet geometry on both sides instead of
  being rejected.

surface_intersector_p2 1660/1660, surface_intersector_p3 1527/1527,
fillet_standard_solver_p2 405/405: all three green.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 13:28:01 -07:00
Jacob Oursland d661aa337a difftest: compare topology change-tracker chg lists and events
The runner compared the tracker's rm and add lists only, and its pool objects
were all bare SmTopology (type 16001), which the tracker's IsKindOf filter
ignores: the lists were always empty and capture's bookkeeping was unobservable.
Two-tier mutation testing found 11 mutants in `topology::topology` that neither
the unit tests nor this unit noticed.

- TRACK_LISTS now emits GetChgList and GetNotifyEvents (action, caller,
  data1..3) on the C++ side and TrackTopologyChanges::lists() on the Rust side.
- A new SET_KIND op gives a pool object a stand-in topology type code
  (SmTopology, SmFace, SmEdgeuse, SmEdge, SmVertex). The object keeps SmTopology
  storage; SmTrackTopologyChanges classifies by type code alone, and the state
  dump asks the base class explicitly, so its type answers are unchanged.
  Existing cases keep the default kind.
- A fixed case drives every capture arm (ChangeGeometry, PostEdit, AddToBrep,
  SplitInBrep, TrimNoSplitInBrep, MergeInBrep, RmFromBrep, Destruction) with a
  tracker and dumps the lists and events after each, so later operations cannot
  mask an arm.

difftest (Linux): PASS topology.topology cases=658 passed=658 failed=0
deferred=0 max_rel_err=0e0. Replaying the saved mutations: the ChangeGeometry/
PostEdit tracked selection, SplitInBrep, TrimNoSplitInBrep,
ChangeGeometry|Split|Merge, Destruction and remove_key mutants now fail the
unit. The owner-walk and accessor mutants remain unit-test coverage (they need
geometry stand-ins with owner links; #656 has the tests).

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-23 13:00:39 -07:00
Jacob Oursland 7289cd2952 difftest: compare topology change-tracker chg lists and events
The runner compared the tracker's rm and add lists only. Mutation testing found
11 mutants in `topology::topology` that neither the unit tests nor this runner
noticed; most change `capture`'s bookkeeping, which is only visible in the chg
list and the captured notify events (or through the owner map those events use).

TRACK_LISTS now emits `GetChgList` and `GetNotifyEvents` (action plus caller and
data1..3 indices) on the C++ side and the Rust tracker's `lists()` on the other,
so the gate compares the complete captured state.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-23 11:44:21 -07:00
Thijs Damsma 660ed01b4e Merge current main into primitive production adapter comparisons
Keep main shared face/axis defaults and consumed-curve slot semantics, while preserving production notification-aware deletion and native geometry comparisons.

Co-Authored-By: OpenAI Codex <noreply@openai.com>
2026-10-23 19:56:18 +02:00
Philipp Rossak 6e5ddd44cc fix: destroy edge uses, faces and shells with their destructors' notifications (#556)
- edgeuse::p2::destroy (~SmEdgeuse), face::p3::destroy (~SmFace) and
  shell::destroy (~SmShell): SM_NO_DESTRUCTION through the object's context
  (status ignored, Unported propagates), the record dropped with what it owns,
  then ~SmAObject's ClearAttributes. edge::with_object_context is shared with
  edge::destroy.
- brep_p4: DeleteEdge's edge uses and merged-away face, DeleteVertex's vertex
  shell. brep_p5: GlueVertices' shells. brep_p3 DeleteFace now deletes what
  upstream deletes there: the easy branch's edge uses (it only unlinked them),
  the other shell of a region merge, the emptied shell and the last new shell
  of the nesting pass; destroy_face also clears the face's attributes.
- difftest: the brep_p3 recorders count SM_NO_DESTRUCTION per caller kind
  (edge, edge use, face, shell); DeleteFace records end with the four counts.
  All 90 delface cases agree (23 failed with only the brep_p4 changes).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TYEpC4tUKxEP3MCaFL5Kz2
2026-10-23 18:03:42 +02:00
Henrik Lampe c97f821e47 Merge remote-tracking branch 'origin/main' into codex/primitive-integration 2026-10-23 17:58:34 +02:00
Henrik Lampe 3b617cac85 fix: keep production ray preparation in one solve
Use live topology reads and cache-first face classification while retaining exact evaluation geometry. Forward constructor identities into stitching region queries and compare primitive geometry, tolerances, trims and rays against SMLib.

Co-Authored-By: Codex <noreply@openai.com>
2026-10-23 17:26:15 +02:00
Philipp Rossak db2a623d40 Merge remote-tracking branch 'tl/main' into fix/edge-destruction-attributes 2026-10-23 17:17:26 +02:00
Philipp Rossak 5672c89215 difftest: compare edge destructions of DeleteFace natively; notes for #556
Both GeomRecorders (brep_p3 shim and runner) count the SM_NO_DESTRUCTION
notifications whose caller is an edge (~SmEdge), and DeleteFace records end
with that count. 13 of the 90 delface cases destroy an edge through
DeleteEdge; without topology::edge::destroy they fail (C++ 1, Rust 0).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TYEpC4tUKxEP3MCaFL5Kz2
2026-10-23 17:16:55 +02:00
bherbruck 67e9a5e9db Merge pull request #621 from altvnk/harness/poly-real-owner
port: query.poly
2026-10-23 14:56:51 +00:00
bherbruck 13219b2818 Merge pull request #622 from altvnk/diagnostic/fillet-span-probes
port: blend.fillet_intersector
2026-10-23 14:56:48 +00:00
Alex Lytvynenko 6514e96a3c Merge upstream/main into diagnostic/fillet-span-probes
Integrate verified authoritative main without changing the diagnostic-only scope.

Co-Authored-By: OpenCode GPT-6.1 Sol Fast <noreply@openai.com>
2026-10-23 16:44:09 +02:00
Alex Lytvynenko ad1e8771fb Merge authoritative upstream/main into harness/poly-real-owner
Sync with verified main 27b698e905 before the approved documentation-only clarification.

Co-Authored-By: OpenCode (GPT-6.1 Sol Fast) <noreply@openai.com>
2026-10-23 16:41:15 +02:00
Charles Galant 40c62ee3eb wire: trimming_tools face_has_seam_problem to face_p4 (promotes to green)
Wire face_has_seam_problem to has_seam_problem_in_brep via HealLoopHandle, resolving the 3 remaining deferred cases (gen0414, gen0590, gen1061). Update C++ shim to run SplitAtSeams instead of TT_NOT_RUN. difftest: 3263 passed, 0 deferred, 0 failed.

Co-Authored-By: Gemini 3.8 Flash <noreply@google.com>
2026-10-23 10:40:57 -04:00
Alex Lytvynenko b995a21546 difftest: limit fillet probes to actual-call observations
Remove optional post-operation span reconstruction and its private snapshot dependency. Retain genuine delegating observers, tags 1 through 4 and both original 189-value per-side bit-identity gates. No corpus, exception, production, reference or tolerance changes.

Co-Authored-By: OpenCode GPT-6.1 Sol Fast <noreply@openai.com>
2026-10-23 16:16:17 +02:00
Alex Lytvynenko 7ea03f3b94 query.poly: preserve native context allocation for owner faces
Forward only the public SmObject context allocator and matching ordinary/placement deletes, avoiding SmTopology's hidden allocator and SmObject's private overloads. No geometry, protocol, guard or fixture changes.

Co-Authored-By: OpenCode (GPT-6.1 Sol Fast) <noreply@openai.com>
2026-10-23 16:09:05 +02:00
Alex Lytvynenko 880d1de51b difftest: correct const probe reads and check diagnostic helpers
Use the pinned getters' public UV matrix fields without casts or point copies. Make unit-local Rust probe helpers fallible and checked while retaining checkpoint payloads, successful evaluation order and the per-side original-record bit-identity gates.

Co-Authored-By: OpenCode GPT-6.1 Sol Fast <noreply@openai.com>
2026-10-23 15:57:01 +02:00
Alex Lytvynenko 29b5803771 query.poly: compare genuine owner geometry without replacing legacy cases
Add an opt-in real-face resolver and port the native UV/pole/seam degeneracy continuation. Compare real SmFace surfaces, independent mapped samples, and native IsDegenerate decisions in 16 new fixtures (27 calls). Preserve the original generator and opaque-owner paths; no tolerance or unit-status changes.

Co-Authored-By: OpenCode (GPT-6.1 Sol Fast) <noreply@openai.com>
2026-10-23 15:55:49 +02:00
Alex Lytvynenko 2efc98e065 harness: compare explicit native surface caches in geom.grid
Add six affine surface/cache cases and unit-local native grid observations while preserving the original 615 inputs and both opaque deferrals. Add canonical-CI identity, node-validation and mutation-sensitivity controls. No production paths or tolerances change.

Co-Authored-By: GPT-6.1 Sol Fast <noreply@openai.com>
2026-10-23 15:50:22 +02:00
Alex Lytvynenko f7cf85485f difftest: observe original clipped fillet step without changing parity
Add unit-local native-feature checkpoints around the genuine plane solve, StepSolve return and ComputePointValues. Keep supplemental span reconstruction explicitly separate, and require instrumentation to preserve each original 189-value record bit-for-bit.

Co-Authored-By: OpenCode GPT-6.1 Sol Fast <noreply@openai.com>
2026-10-23 15:42:46 +02:00
bherbruck 7935b4c09b Merge pull request #610 from Loohi/unit/intersect.curve_class_p5
port: intersect.curve_class_p5
2026-10-23 13:08:37 +00:00
Louis 8aea27690f Merge remote-tracking branch 'origin/main' into unit/intersect.curve_class_p5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013dBoSgwB37oA88rLG9LZ6E
2026-10-23 20:54:11 +08:00
Louis 9430122056 intersect.curve_class_p5: port the in-place edits, compare them on real B-reps
sm_InsertSolutions now raises an edge-end vertex's tolerance to the edge's
(SmVertex::SetTolerance) and IntersectVertices runs the GWC:CHANGED_SSS block:
knot-snap cull, surface projections, sm_SetXSectCurveThroughPoint on the
classification curve, SetIsCurveCurrent(FALSE) and deleting the UV trim curves
of the vertex's edges and their topology intersector mates. The _mut entry
points take a ClassGeometryMut; the read-only ones defer where an edit is due.

New B-rep difftest cases (shim intersect_curve_class_p5_topo.cpp): 30 fixtures
and 300 generated, all bit-identical. Unit goes green.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013dBoSgwB37oA88rLG9LZ6E
2026-10-23 20:54:06 +08:00
Thijs Damsma b5018deb00 Merge origin/main into primitive p3 adapters
Co-Authored-By: OpenAI Codex <noreply@openai.com>
2026-10-23 14:42:38 +02:00
Philipp Rossak 5a18f8e540 Merge remote-tracking branch 'tl/main' into wire/primitive-p3-brep-faces 2026-10-23 14:25:47 +02:00
Philipp Rossak 7495fbf509 wire: primitive.primitive_creation_p3 B-rep face services (unit to green)
PrimitiveAccess's CreatePlanarFace(s)With3DCurves, CreateFace(s)FromSurface
(topology.brep_p8) and DeleteFace (topology.brep_p3) defaults were UNPORTED
stubs; they now call the ported B-rep functions through
SweepAccess::with_brep_mut. PrimitiveModel's identical overrides are removed.

The difftest adapter gains a tag store, untagged curve lookups and face
deletion through KernelManifoldIntersector::delete_faces_with_keys, and every
entry-point record now also compares the B-rep's face/edge/vertex counts.

difftest: 296 cases, 295 bit-identical passes, 0 deferred (was 9), 1 UB-78
rejection, 0 failures.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 14:02:15 +02:00
bherbruck 7d58e690f4 Merge pull request #612 from zorak1103/wire/ray-tracer-add-surface
wire: intersect.ray_tracer AddSurfaceToGrid (unit to green)
2026-10-23 11:42:24 +00:00
Thijs Damsma a21d0d6dbb difftest: compare cone/sphere faces the shared exports carry exactly
The "SurfaceKind::Cone/Sphere (SmCone/SmSphere dispatch)" deferrals of
surface.surface_p2 were runner pre-checks keyed on the C++ face surface type,
not a missing Surface arm: Surface::read_from_db already returns Cone and
Sphere, and the shared exports carry such faces exactly (sc_analytic_export.h).

- blend.fillet_corner_p1/p2: defer on ImportTypes::inexact_surface (as p3).
- topology.face_p3: skip faces the import rebuilt exactly.
- topology.vertex: the shim emits the exact record head; the runner reads it.
  topology.vertex: 5508 passed, 0 deferred (was 536 deferred) -> green.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvuXmr7S5RoUXxVohC1giE
2026-10-23 13:13:50 +02:00