Resolve topology.assert_valid.toml notes: main's #1631 copy_ops text and
this PR's #1702 WP3b text both kept in place.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Conflicts in the fillet_executive_p3 runner and shim resolved keeping both
forms (attributed and two_offset_chamfer); has_other_form also covers
two_offset_chamfer.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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
The Rust purity state is the whole source B-rep, gap caches included, but
the native snapshot never observed the vertex-use and edge-use gap caches.
On the Fillet box_diff_cyl / cyl_on_box_w_fillet sources both kernels reset
the same 8 vertex/face gap caches on the source (CalcVertexFaceGap resets
every same-face use before caching its own), so the C++ side reported pure
and the Rust side impure.
The shim now emits per vertex use the vertex/edge and vertex/face gap init
flags with their edge t / face UV, and per edgeuse the max edge/face gap
init flag, read only through already-initialised caches. input.pure
compares them before/after. Adds the 66 Fillet DoSolidOffset cases
(fillet_files.json) and a unit test that a reset cache alone breaks purity.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MNXLXj2sJf943y2dDF36Vy
Each owning curve unit (hermite_curve, offset_curve, projected_curve,
crv_on_surf, crv_in_volume) gets an assert_valid op in its shim, ffi and
runner, and 300 cases on their own seed stream (the existing streams are
unchanged). Both sides write the full report list through a shared encoder
(sc_assert_reports.h / util::assert_reports) with object identities by first
appearance. The ffi wrappers reject a failed Hermite test 1 with a list
(upstream reads past the one-entry default label table).
The native comparison showed that upstream links contained parts to the
compound curve (SetOwner(this)) only on some construction paths: the
UV-line constructor, SetUVCurve and ReadFromDB of SmCrvOnSurf, ReadFromDB of
SmCrvInVolume and the SmOffsetCurve copy constructor link nothing. The
offset, curve-on-surface and curve-in-volume structs now record those links
and the owner tests read them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MNXLXj2sJf943y2dDF36Vy
Port the SmBrep overloads of SmTol (Get/SetModelSizeEstimate,
Get/SetLargeSmallSizeRatio, GetZoneTol3d/GetApproxTol3d/GetXSectTol3d,
CalcFace/Edge/VertexZoneTol3d and GetScaledZero) as geom::tol::brep_* and
scaled_zero_of_brep, and use them in place of the local copies in
heal_data p2, vertex corner, brep_cache and the fillet finish. Add
geom.tol brep difftest cases (shim sc_geom_tol_brep) and unit tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MNXLXj2sJf943y2dDF36Vy
set_surface_caches now takes the kernel and the caches mutably and asks each
for its tree with SurfaceCache::get_tree, as SmSurfaceIntersector::Intersect
does (pSC->GetTree(), NER), instead of returning Unported for a cache without
tree. The m_apTrees assignment for callers that ran GetTree themselves
(DoIntersection) is bind_caches.
difftest: a build-trees mode (trees flag 2) in the intersect.adv_surface_intersector
runner, shim and ffi builds both trees with GetTree on fresh caches, compares
them node by node and runs solves over them (18 inline edge_built_tree_* cases).
The shim now sets the intersector's m_cpContext as DoIntersection does before
FindInteriorCurves; left NULL, FlushCurve made context-less curves whose
DropPoint failed, so IsPointOnCurve reported every later start point on a curve.
Regression test: crates/solidcore/tests/adv_surface_intersector_get_tree.rs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MNXLXj2sJf943y2dDF36Vy
Resolve topology_face_p1 FFI docs: keep the owner outputs and #1677's DeleteInnerLoop op.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>