SmSurfaceCache object and simple queries, SmBezierAux2d/SmBezierPatch node data
with lazily built polar boxes, SmPatchBoundaryBoundingPlanes, SmAltSrfCache,
sm_ComputeBezierApproximation, ComputeSizeTolerances, GetCorners, BuildTreeTop,
FindUnmarkedLeafNode, GetConnectedRegion, MarkFaceContainment,
GetSurfaceContinuity, GetIsoBoundaryCurves, sm_CullArray; shim, ffi, difftest
runner and fixtures (872 cases, 709 pass bit-identical, 163 deferred).
Wired UNPORTED(surface.surface_cache_p1): SmTree::GetOwnerObject of surface
trees (Tree::set_owner_surface), sm_GetOriginalSurface; retagged the stubs that
need the cache's patch data from a bare tree to surface.surface_cache_p3 and
smsurf_GetSurfaceCache paths to surface.surface_p1 (CacheMakeOrValidate).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V8ohWGLCzFPoZriCeSSero
SurfaceKind::CurveBounded with the evaluation overrides passed along to the
basis surface, base-class defaults for the rest of the SmSurface dispatch,
type queries, operator==, SetContext and ReadFromDB (wired into
Surface::read_from_db, which now takes the kernel for the boundary curve
readers). C++ shim, ffi wrapper, difftest runner and fixtures: 535 cases,
359 pass, 176 deferred (surface_p1/p3/p5/p7).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V8ohWGLCzFPoZriCeSSero
Wires the UNPORTED(curve.composite_curve_p2) SmCompositeCurve::ReadFromDB stub in
Curve::read_from_db. difftest: 661 cases, 361 pass, 300 deferred on curve.curve_p5.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V8ohWGLCzFPoZriCeSSero
Port the composite curve object and segment records (constructors, copy,
operator==, GetCurveSegment, GetCanonical, IsClosed, type queries), the
overrides GetNaturalInterval, GetKnots, CalculateBoundingBox,
ApproximateCurve (with sm_convert_to_BSplineCurves) and Transform, the
statics ComputeProjectedLoopOrientation and BuildCompositesFromCurves
(with sm_FlushCrv), the file-static sm_CreateCorner, sm_CurveClassify and
break-list helpers, and the type queries of SmCompositeCurveRegion,
SmCompositeCurveSegment and SmOffsetMapAttribute.
Difftest: 3093 cases (93 fixture + 3000 generated), 2781 pass
bit-identical, 312 deferred (curve.curve_p5: AssertValid of the joined
approximation, corner/classify solves); 30k-seed run clean; --perturb
SENSITIVE. Upstream out-of-bounds reads recorded in plan/findings.md.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V8ohWGLCzFPoZriCeSSero
Resolve CurveKind dispatch with the merged parabola and curve-on-surface
kinds; thread &Kernel through the curve-on-surface, bounding-box and
planarity paths that can reach an ellipse's polar converter.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V8ohWGLCzFPoZriCeSSero
Shim, ffi wrapper, difftest runner (58 fixture cases from the SM_API
rectangle/polygon and reversed-line-join inputs plus edge cases, 3000
generated). Wires the UNPORTED(curve.curve_p8) stub in
nurbs::b_spline_curve::p3 (TrimGap).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V8ohWGLCzFPoZriCeSSero
Wire UNPORTED(curve.ellipse_p1) SmCurve::GlobalCoincidenceChecker of
ellipses (curve.curve_p6 landed); dispatch the ellipse in curve_p6's
GlobalPointSolveSTEP, bounding box and deform overrides.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V8ohWGLCzFPoZriCeSSero
Resolve CurveKind dispatch: Parabola joins main's Line, Hyperbola, Iso,
Projected, Offset and CrvInVolume variants and runs the SmBSplineCurve
methods on its base wherever main routes Hyperbola to its base (tessellate,
is_line, is_linear, is_degenerate, bounding box, curve cache NURB, deform,
curve max distance, Line::join_with). GlobalPointSolveSTEP now calls the
ported SmCurve::GlobalPointSolve (curve.curve_p1) and is dispatched from
Curve::global_point_solve_step; ReadFromDB(PARABOLA_TYPE) runs inside the
nesting guard.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V8ohWGLCzFPoZriCeSSero
Port MakeNurb (owner-aware), ConvertTo2D, ConvertTFromNURBSToSTEP,
AdjustSTEPInterval, GlobalPointSolveSTEP, JoinWith, Notify,
ReverseParameterization, Trim, Copy, CreateCanonical, AssertValid,
ReadFromDB, the SmCircle class (constructors, CreateCanonical, IsArc,
CreateSimpleOffset, AssertValid, ReadFromDB) and SmPolarConversion
ConvertToPolarParameter, IsCurrent, AssertValid, ReadFromDB.
Wire UNPORTED(curve.ellipse_p1) stubs: Curve::read_from_db for ellipses
and circles, the ellipse global point solve in IntersectWith*,
CreateAnalyticCurve's SmCircle and CreateSurfOfRevolution's sweep circle.
Thread &Kernel through the Curve methods whose ellipse override rebuilds
the polar converter. Difftest: 2028 cases, 132 deferred (curve.curve_p5).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V8ohWGLCzFPoZriCeSSero
Difftest: 3083 cases, all non-deferred bit-identical, 590 deferred on
curve.curve_p5; --perturb SENSITIVE; 12,083-case run clean.
SolutionObject gains a default natural_interval() so IdenticalSolutions can
read a curve object's parameter interval, as upstream does.
Wired: nurbs.b_spline_curve_p1 TessellateByBisection (now green),
b_spline_curve_p2 ApproximateCurve, hyperbola GlobalPointSolveSTEP,
ellipse IntersectWithLine's line solve; the ellipse's own GlobalPointSolve
now waits on curve.ellipse_p1.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V8ohWGLCzFPoZriCeSSero
BSplineVolume holds the NURBS record as VolumeKind::BSpline; the volume base
dispatches GetNaturalParamDomain, Copy, operator==, EvaluateSimple,
InvEvaluateGuessPointSimple, IsBoundedSimple and TransformSimple to it. The
SmBSplineVolume UNPORTED stub now only covers the surface.b_spline_volume_n_lib
overrides. difftest 2333 cases (333 fixture + 2000 generated), 0 deferred,
bit-identical; 30k-seed run clean; --perturb SENSITIVE.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V8ohWGLCzFPoZriCeSSero
Iso curves, surfaces of revolution, spheres from arcs, trimmed planes from
ruled surfaces, control point access/editing, SetCanonical, CopySubPatch,
SplitAt, SwapUV, AdjustSTEPUVDomain and the back-edge stubs. difftest:
763 cases, 702 pass, 61 deferred, max_rel_err 0.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V8ohWGLCzFPoZriCeSSero