Commit Graph

13 Commits

Author SHA1 Message Date
jyviko a5de86aaf8 surface: the fitted extension path is deleted; the exact extension is the only one
Deleted: Surface/Plane/OffsetSurface/BSplineSurface create_extended_surface(_dir), with
create_extended_surface_dispatched, extend_side and MAX_EXTEND_HALVINGS/DOUBLINGS
(CreateExtendedSurface on every kind), srf_adv::p1::extend_by_dist (N_SrfExtendByDist) and
srf_adv::p2's ST_surxsdr (extend_by_dist_at_depth/_in_place, SrfContinuity,
MAX_EXTEND_DEPTH). Their only callers were each other: every caller extends through
surface::extend since the switch. remove_knot_conditional and extend_by_param_dist stay.

difftest: their ops are removed with their FFI ops, C++ shim cases, fixtures and fuzz
corpus entries (nlib.srf_adv_p1/p2, surface.surface_p2, surface.plane_p1,
nurbs.b_spline_surface_n_lib_p1, surface.surf_of_extrusion_p2, surface.offset_surface; each
unit passes in full; removed shim op numbers are left unused).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NvoxKMbMFSQU8tzRtoJhtT
2026-11-05 08:11:22 -05:00
Brett Lawson e06fb0adfc wire: port SmOffsetSurface and SmSrfInVolume AssertValid
Replace the two UNPORTED arms of Surface::assert_valid with faithful ports of
SmOffsetSurface::AssertValid (context, base owner, self-intersection via
GlobalSurfaceIntersect with its status ignored) and SmSrfInVolume::AssertValid
(nested base-surface and volume checks, owner and context tests). Co-port the
volume checks it nests into (SmVolume, SmTransform, SmBSplineVolume, bend,
unbend and twist) as Volume::assert_valid, with an explicit next-map depth bound.

Difftest: an AssertValid step in the offset-surface script runner (100 avNNNN
cases on a separate seed stream) and an AssertValid op in the srf-in-volume
runner (avNNNN cases), comparing every report against C++. Regression test
crates/solidcore/tests/surface_assert_valid_offset_srf_in_volume.rs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MNXLXj2sJf943y2dDF36Vy
2026-10-30 14:48:32 +01:00
Brett Lawson c281589321 difftest: coverage cases for eleven green surface units; hyperbola generators
From the llvm-cov run of `difftest --green`: 136 fixture cases
(fixtures/<unit>/coverage.json, each citing the upstream branch and the
Rust line it covers) execute about 70 previously uncovered spans in
offset_surface (zero first derivatives replaced by base tangents, a
hyperboloid base), sphere (coincident/concentric spheres, degenerate
arcs, tangency marks, cone and box rejects, pole and seam inversion),
surface_p5 (singular iso curve, CoverOtherCoincidentSurface branches,
IdenticalSolutions at a pole), surface_p4 (curve/surface crossing
classification on dome, saddle and cylinder points), surf_of_extrusion_p1
(coincident generators touching or disjoint), surface_p6 (solutions at a
pole), surface_point_solve_p2 (cross-seam solutions), torus (horn torus,
axis-start minor circle), curve_bounded_surface (== stops) and
surf_of_revolution_p1/p3 (revolutions of a real SmHyperbola).

The surf_of_revolution_p1 runner, FFI and shim gain a hyperbola
generator; the five shims sharing that generator block parse it too.
Fuzzing it showed SmHyperbola's constructor ignoring a failed MakeNurb
(NULL or non-finite NURB, then a segfault): the shims refuse such a
hyperbola, and plan/upstream-issues.md UB-46 records the trigger.
Generated cases are unchanged.

All eleven units PASS with 0 failures and 0 deferred (max_rel_err 0);
--perturb SENSITIVE on all; --fuzz 200 (p1, p3, offset): FUZZ-PASS.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 12:10:34 -07:00
jijinbei 4418ba3204 shim: share flg(SmBoolean), put_ivl and put_mat through sc_sm.h
Adds the three helpers to sc_sm.h, copied from the per-shim copies they
replace, and switches 19 shims to the shared flg/put_mat/put_vec/put_ivl/st/
put_dom. Shims touched by open PRs are left alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 11:00:12 +09:00
Pluto-XI ef995afa13 surface.offset_surface: run the C++ reference in process (review)
The maintainer asked for the build-script and Cargo changes to go to a
separate PR: the per-case offset-reference worker (build.rs link step,
GNU ld --wrap, offset_reference.rs, offset_worker.cpp) and cc's parallel
feature. build.rs, the solidcore-ffi Cargo.toml, Cargo.lock, lib.rs and
the difftest README are back to main's.

The shim now runs in the difftest process:
- CreateExtendedSurface is refused (FFI and shim): UB-107 and the
  HANG-6/HANG-22 searches inside it cannot be detected outside NLib, as
  the worker already did where it had no --wrap. The upstream-derived
  fixture api_offset_m12_copy_split_extend loses its two extension steps
  (ours; TestSmCreateOffsetSurface never extends) and is renamed.
- A surface of revolution base keeps surf_of_revolution_p1's in-process
  1e-6 minimum sizes (the worker's deadline had made them unnecessary).
- IsPlanar gets the shim's box-chain check over its natural domain, and
  the generator preflights it: after an outer offset's STEPInversion
  made an inner offset store an extension, IsPlanar's virtual box
  reached the inner's SmSurface body (UB-173) and overflowed the stack
  in a 100,000-seed run.
- BaseOffset distances are generated relative to the base's size (as in
  surf_of_revolution_p2): a 1e149 offset of a unit revolution makes a
  degenerate generator offset, and CreateSimpleOffset then copies an
  uninitialised dMaxGap3d.
- gen5909 (HANG-22) stays an FFI regression: it stops at its extension.

Also: rustfmt on the #[path] unit files, and issue IDs renumbered past
main and every open PR (UB-171..174, HANG-21/22, WR-160..166).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 12:10:25 -06:00
Pluto-XI 3cd2a278dd surface.offset_surface: renumber issues past main and open PRs again
Main took UB-163 (heal props, #164) and open PRs claim UB-162 (#139,
#145), UB-164 (#173) and HANG-17/18 (#149). Renumbered simultaneously so
no mapping chains: UB-162..165 -> UB-165..168, HANG-17/18 -> HANG-19/20.
WR-159..165 are still free.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 19:55:38 -06:00
Pluto-XI ec9e30a9bd Merge origin/main (5b1b5498) into unit/surface.offset_surface
Conflicts resolved in favour of main where main superseded this branch's
code, combined where both added; main's new kernel argument threaded
through the offset point solves, the fillet solver's LocalPointSolve and
copy_and_add_analytics callers; OffsetSurface arms added to main's new
SurfaceKind matches (evaluation copy, drop curve, CrvOnSurf dispatch gap,
loop UV gap test).

With surface_point_solve_p3 landed, the 213 cases that deferred on
LocalPointSolve_1 now run, and 5 disagreed: Rust found a pole solution C++
rejects. Cause: upstream's owning offset does m_pSurface->SetOwner(this),
so LocalPointSolve_1 on the base takes GetZoneTol3d(GetOwner()) as its
loose tolerance instead of 0.01. Ported that ownership: an owning offset
gives its base the BASE_OWNER surface owner wherever upstream calls
SetOwner(this) (constructor, Copy, ReadFromDB), and hands down the face
its own owner chain reaches, so Surface::face of a base follows the chain
as GetFace does. This replaces the face_owned flag the box code passed
down (review item 2 keeps its Unported(topology.face_p2) result). The
approximation-tolerance and surface-cache zone checks that asked "any
owner" now ask GetFace(), as SmTol::GetZoneTol3d(const SmObject*) does.
The six cases (three generated, base owned and shared) are fixtures.

surface.offset_surface: 3072 cases, 3072 passed, 0 failed, 0 deferred.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 19:55:03 -06:00
Pluto-XI 9be2c68dfe surface.offset_surface: portable worker-guard flag; test the no-wrap path
Replace the GCC/Clang-only weak symbol with a plain flag the shim defines
(at namespace scope, external linkage) and the worker's main() sets when it
is linked with its NLib --wrap wrappers. Verified the non-Linux branch by
forcing it on Linux: the worker builds without __wrap_ symbols and refuses
every extension step; the regression now asserts that per platform.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 11:53:05 -06:00
Pluto-XI d2c45e1733 surface.offset_surface: review nice-to-haves (guards, worker, dispatch, docs)
FFI guards now refuse only what C++ cannot handle, each probed against the
isolated worker:
- drop the 1e6 coordinate cap, the 1e-3 transform-scale floor, the 1e3
  extension-distance cap and the 1e-6 revolution generator minimum (offset
  callers only; surf_of_revolution_p1's in-process calls keep it);
- orders: cap 64 (caller array bound; upstream refuses >3 before writing);
  UB-116 moves into the worker on the actual compound distance, so zero
  offsets are compared;
- box guard follows CalculateBoundingBox level by level against each
  offset's own m_pSurface instead of only the innermost base.
Remaining refusals are UB-107 and HANG-6, the latter by a 20,000-call
arc-length work bound (normal searches: <=45) instead of the deadline.

Worker: a timeout is rerun once with 60 s before it is a harness failure;
off Linux it is built without GNU ld --wrap and the shim refuses extension
steps instead of running them unguarded.

Dispatch: new BaseOffset op compares GetBaseSurface()->CreateOffsetSurface
through SmSurface* (4 fixtures, 81 generated over every base kind).
Generator covers magnitudes 1e-9..1e150, tiny revolutions, zero/negative
scales and orders up to 8 (484 such cases pass, 41,252 values).

nurb_of documented: a NURB-less revolution base is UB upstream before
GetOrCreateGwNurbPointer runs. nurbs.b_spline_surface_p1 note counts fixed.

surface.offset_surface: 3066 cases, 2853 pass, 0 failed, 213 deferred;
6000 seeds: 6066 cases, 5620 pass, 0 failed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 11:25:27 -06:00
Pluto-XI 64857e0873 Merge origin/main (780658a9) into unit/surface.offset_surface
Resolve conflicts with the newly ported surface p3-p6, srf_in_volume,
topology face/vertexuse/edge and query units:

- Add OffsetSurface to the new SurfaceKind dispatch arms and SrfInVolume
  to the offset nesting walk; GetSingularities now runs (surface_p3).
- Thread the kernel through SrfInVolume copy/split and the surface cache
  subdivision split, which now call Surface::copy/split_at.
- Implement the new SurfaceEvaluate solver methods for OffsetEval on a
  snapshot that keeps this evaluation's extension.
- Renumber this PR's upstream issues past main and every open PR:
  UB-99..102 -> UB-116..119, WR-81..87 -> WR-97..103,
  HANG-13/14 -> HANG-14/15; link HANG-15 to main's UB-107.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-15 16:38:33 -06:00
Pluto-XI 988d9c9050 Merge origin/main into unit/surface.offset_surface
Main added UB-98, HANG-12 and WR-73 (topology.proto_topology_p1), so this
branch's upstream issues are renumbered: UB-98..101 -> UB-99..102,
HANG-12/13 -> HANG-13/14, WR-73..79 -> WR-74..80, in the plan files and in
the offset FFI, shim and difftest README. The offset unit's notes keep
main's CO-PORTED record from blend.fillet_custom_solver (PR #78).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 21:02:19 -06:00
Pluto-XI 9ab0e97fc8 Merge main and repair offset surface review findings
Resolve dispatcher conflicts; bound nesting, preserve exact replay, and guard invalid C++ extension searches in an isolated oracle. Keep numerical results unchanged. Offset default and 6000-seed comparisons pass with genuine foreign-unit deferrals.

Co-Authored-By: OpenAI Codex <noreply@openai.com>
2026-10-14 20:44:58 -06:00
Pluto-XI ffc35b1716 surface.offset_surface: difftest harness (WIP), NLib and box fixes
Shim, FFI wrapper, runner and fixtures (upstream TestSmCreateOffsetSurface,
smTopoTest nested offsets, smMergeTest .sms offsets, edge cases). 3057 cases:
1479 bit-identical, 0 failed, 1578 deferred (GetSingularities, surface_p3).

Fixes found by the difftest: N_SrfIsClosedSmooth stores its flag before
returning a failed-angle error, so N_SrfEvalPtDerivsUnbounded keeps the copy
and flag for a retry (nlib.srf_nurb, nlib.srf_adv_p1); SmSurface's base
CalculateBoundingBox maps a failed cache to SM_ERR_NULL_POINTER (NER).

WIP: a 30k-seed run still has one C++ hang to guard (case gen120xx).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 14:35:42 -06:00