Commit Graph

7 Commits

Author SHA1 Message Date
Brett Lawson f83d5e830a surface: model lazy surface cache trees (#568)
Upstream keeps one cache per surface object and builds its tree lazily: a
cache made during a Boolean operation has no tree, and its continuity arrays
stay empty until a GetTree. GetDomainWithContinuity and LiftCurve read those
arrays without GetTree, so their answer depends on that history (gen0266:
the face caches were made while reading the .smb file).

Surface now carries a cache slot (no cache / cache without tree / cache with
tree) shared by its evaluation copies; the trimmed cache makers honour and
record it, BuildTreeBase marks it built, ComputeUVPoint records the cache its
global fallback makes, and the continuity readers take their cache from
continuity_surface_cache. GetTree users build a missing tree (solve caches,
offset solve contexts, the tracer constructor).

Difftest: the offset_geometry_creation export carries each face surface's
cache state and the runner seeds it; the upstream:cache-history deferral and
OP_LIFT_OFF_DOMAIN are removed (all 4 cases pass). surface.surface_p1 DomCont
gains a cache history and 96 domhist cases (15 fail without the model).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 17:18:03 -07:00
Brett Lawson 414efd434d surface.surface_p1: port CreateSilhouetteCurves' trace and split; prog_test my_test_sil_adv cases
Surface::create_silhouette_curves stopped at UNPORTED(intersect.surface_tracer)
although the tracer and SmSurfaceSilhouette are ported. It now builds the
SurfaceSilhouette, runs do_trace with the optional tolerances and, for a
parallel projection, splits each traced curve at interior tangents
parallel to the view vector (GlobalPropertyAnalysis SM_CP_PARALLEL_TO_VECTOR
within 100 * SM_EFF_ZERO_SQRT, copy + two Trims with the snapped
intervals, the same split on the UV curve, new pieces appended), as
SmSurface.cpp does. The analysis' solutions name the curve (natural
interval for IdenticalSolutions). Copying the surface colour attribute
is left to callers (free surfaces carry no attributes; header Deviations).

Difftest: a `sil` op on the surface.surface_p1 runner, shim and FFI guard
recording every 3D and UV curve in full, with an optional translation.
harness/fixturegen/sil_adv.py turns the 34 my_test_sil_adv calls
(smAdvancedTest.cpp, .smb faces) into fixture cases (27 pass, 7 defer on
SmSurface::DropCurve); 64 generated sil cases on their own seed stream.
Upstream's asserted counts are after SmFace::CreateCurvesByTrimming,
which this op does not run (noted per case).

PARTIAL surface.surface_p1 cases=904 passed=854 failed=0 deferred=50 (was 806/793/13)
PASS intersect.surface_silhouette 709/709; intersect.surface_tracer,
intersect.topology_solver_p1, blend.hcr: 0 failures, unchanged
SENSITIVE surface.surface_p1 perturbed=854 detected=854; --fuzz 300 FUZZ-PASS
cargo test -p solidcore 1551 passed; clippy, fmt, wasm32 clean

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 11:19:23 -07:00
jijinbei 875291c4d9 shim: share identical C++ helpers through sc_sm.h, sc_nlib.h, sc_gw.h
125 shims carried private copies of the same small helpers (put_vec, st,
nl_status, Rd, dump_crv, read_nurb, ...). Move the most common, byte-identical
form of each into three headers grouped by the upstream API they need, and have
those shims pull them in with `using sc::<name>;`. Shims with a different
variant keep their own copy; files touched by open PRs are left alone.
`the_context()` stays per shim (its function-local SmContext must not be shared).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FBLgPenT24P1dunqnZR1Dj
2026-10-17 06:43:03 +09:00
bherbruck 885dc45f0b Merge origin/main into unit/surface.surface_p1
Brings in intersect.topology_solver_p1 (PR #30).

- topology_solver sm_GetFaceSilhouettes: wire the UNPORTED(surface.surface_p1)
  stub. It now builds the cache with smsurf_GetSurfaceCache (the 3-argument
  port), checks HasCachedCurves(SM_AS_TRIMMED_SILHOUETTE, 10 * tol, 20 deg,
  view vector, FALSE), and calls CreateSilhouetteCurves over the face's UV
  domain (a non-B-spline surface, a NULL SM_CAST_PTR upstream, is an
  error). It then stops at UNPORTED(topology.face_p2):
  SmFace::CreateCurvesByTrimming.
- Renumber this unit's upstream issues UB-80/UB-81 to UB-83/UB-84. Main's
  surf_of_extrusion_p1 and topology_solver_p1 entries already use UB-80/81.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BY8UpXKuMci15rAWGXsbsm
2026-10-14 12:33:47 -04:00
Marius van Voorden 727031303c surface.surface_p1: review fixes
- StepSurface::knots: ContainsValue's default tolerance is 0, not SM_EFF_ZERO.
- A plane's polar box comes from SmPlane::EvaluateNormal (plane_bounding_box),
  also for the surface caches (their plane stub is gone).
- UB-81: SmSurface::CalculateBoundingBox recurses without bound on a polar box of a
  curve-bounded or STEP surface; the base body and the cache dispatch refuse it
  (InvalidInput), the FFI never asks the C++ for it; the cache's other boxes of
  those kinds defer on CalculateContinuities.
- The remaining stubs on this unit become DISPATCH GAPs (iso curve and crv-on-surf
  readers, ApproximateSize, the grid, p7's sm_IsNodeValid and solver patch reads).
- FFI: IsOnBoundary / IsInDomain accept points up to a side outside the domain for
  planes and clamping B-splines; BBox prints the polar box of B-splines and planes.
- Generators: STEP knot intervals just inside the domain ends, outside points.
- Fixtures: the review's cases. is_planar checks the face owner first; comments on
  the hard-coded face state and the B-spline zone tolerance.

difftest: 806 cases, 764 pass, 0 fail, 42 deferred; --perturb 764/764.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 16:34:38 +02:00
Claude 6bdb98ac24 surface.surface_p1: FFI binding, difftest runner, back-edge wiring
- solidcore-ffi: surface_surface_p1 (22 ops, matching the shim's codes 0-21) with
  input validation; the shim reads SmPseudoBox::GetBasis and guards
  GetDomainWithContinuity without a surface cache (upstream NULL dereference, UB-75).
- difftest: surface_surface_p1 runner (800 generated cases over B-spline, plane and
  curve-bounded surfaces, optionally STEP-wrapped): 758 pass bit-identical, 42
  deferred, --perturb 758/758.
- Wire SmBSplineSurface's IsDegenerateCurve / IsDegeneratePoint / first-derivative
  back-edges and its bounding box zone tolerance (Surface handles a face owner);
  retag LocalPointSolve (surface_p5), GlobalPointSolve (surface_p4) and
  CreateOffsetSurface (surface.offset_surface).
- trim_srf_cache runner: face cases defer on SmBrep::CreateFaceFromSurface.
- Step arms in the cpp-only runners; clippy fixes; unit tests assert the wired
  behaviour.
- plan: surface.surface_p1 partial; findings and upstream-issues entries; reports of
  the touched units (all improved, none regressed).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RsMto2bEoBSCSCJku4nT4u
2026-10-14 02:48:59 +00:00
Marius van Voorden 806a75dafc surface.surface_p1: WIP wiring of back-edges, C++ shim (22 ops), shared test helpers
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 03:50:07 +02:00