You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
Other
Round 188: curv2 2D trimming-curve tessellation
Round 182: basis-matrix surf surface tessellation
Round 14: Taylor polynomial surf surface tessellation
Round 14 (depth): cargo-fuzz harness + two parse-time panic fixes
Added
2D trimming-curve (curv2) tessellation under ObjDecoder::with_curve_tessellation(samples: u32). The decoder now
evaluates every curv2 directive — the parameter-space curve used as
an outer / inner trimming loop, a special curve, or for connectivity
(spec §"curv2") — into a Topology::LineStrip polyline on a new
synthetic mesh named "obj:curves2". A curv2 references vp
parameter vertices (spec §"vp u v w") and lies in the 2D parameter
space of the surface it trims, so each vp (u, v) is lifted into a [u, v, 0.0] control point and run through the same Bezier /
B-spline / Cardinal / Taylor / basis-matrix evaluators the 3D curv
path uses; the sampled x/y are the parameter-space coordinates and z stays 0.0. Unlike curv, a curv2 line carries no inline u0 u1 range — the B-spline evaluation window is taken from the
block's parm u knot vector ([parm_u[0], parm_u[last]]). The
optional 3rd vp coordinate is the rational weight (default 1.0; a
stored 0.0 — the vp padding default — is read back as 1.0 for
the rational forms since a zero weight is degenerate). Negative curv2 indices resolve relative-from-end against the vp pool (spec
§"Special point" example curv2 -6 -5 …). Synthetic primitives carry
the shared obj:tessellated_curve sentinel (so the encoder filters
them out and replays the original cstype / curv2 / end block
verbatim from Scene3D::extras["obj:freeform_directives"]) plus a obj:curve2 = true marker and the obj:curve_kind / obj:curve_degree / obj:curve_u_range / obj:curve_samples provenance. Malformed curv2 blocks (missing cstype, missing knot vector for B-spline, fewer than two control
points, out-of-range vp indices) are silently dropped. The trim / hole / scrv statements that reference these curves by
index still ride on freeform_directives verbatim — surface clipping
against the loops remains future work.
Basis-matrix surf surface tessellation under ObjDecoder::with_curve_tessellation(samples: u32). The decoder now
evaluates surf elements that sit under a cstype bmatrix (or cstype rat bmatrix) header into a triangulated Topology::Triangles
primitive on the synthetic "obj:surfaces" mesh, via the bivariate
tensor-product polynomial S(u, v) = Σ_a Σ_b (Σ_p B_u[a][p] · u^p) (Σ_q B_v[b][q] · v^q) · c_{base_u + a, base_v + b} (spec §"Basis matrix",
§"bmat u/v matrix", §"step stepu stepv"). Per-direction basis
matrices come from bmat u / bmat v (row-major, column index
varying fastest); per-direction segment strides come from step stepu stepv. The per-direction control-grid extent is the
inverse of the spec relation parm = (K − n) / s + 2, i.e. K = (parm − 2) · s + n + 1, applied independently in u and v per
spec §"step stepu stepv" ("For surfaces, the above description
applies independently to each parametric direction."). Multi-patch
grids are now decomposed into (K_u − n − 1) / stepu + 1 × (K_v − m − 1) / stepv + 1 polynomial segments; the global parameter (u, v) partitions into per-segment (seg_u, seg_v, t_u, t_v) with the
patch-local control window starting at (seg_u · stepu, seg_v · stepv). The cubic Bezier basis-matrix surface from the spec
§"Examples" reproduces the equivalent cstype bezier patch sample-
for-sample on its single-patch form. The rat bmatrix qualifier
routes to the same evaluator without per-vertex weight blending
(matches the round-10 1D curve behaviour — the user's basis is the
authoritative source). Malformed blocks (missing bmat u / bmat v,
missing step, wrong-size matrices, mismatched control-vertex
count) are silently dropped — the directive sequence still rides on Scene3D::extras["obj:freeform_directives"] for round-trip.
Synthetic primitives carry obj:tessellated_surface = true, obj:surface_kind ("bmatrix"), obj:surface_degree, obj:surface_u_range, obj:surface_v_range, and obj:surface_samples provenance plus the shared obj:tessellated_curve = true sentinel so the encoder filters the
synthetic geometry out and replays the original cstype / deg / bmat u / bmat v / step / parm u / parm v / surf / end block verbatim. Trim/hole loop
evaluation remains out of scope.
Taylor polynomial surf surface tessellation under ObjDecoder::with_curve_tessellation(samples: u32). The decoder now
evaluates surf elements that sit under a cstype taylor (or cstype rat taylor) header into a triangulated Topology::Triangles
primitive on the synthetic "obj:surfaces" mesh, via the bivariate
tensor-product Horner-rule evaluation S(u, v) = Σ_i Σ_j c_{i,j} · u^i · v^j (spec §"Taylor"). Control
points are the polynomial coefficients in spec §"Surface vertex data
— control points" row-major u-fastest order; a single Taylor patch
of declared degree deg degu degv needs exactly (degu + 1) × (degv + 1) coefficient vectors. The surf s0 s1 t0 t1
range supplies the global parameter clip; Taylor surfaces evaluate
against the raw [s0, s1] × [t0, t1] window directly (not a
normalised [0, 1] re-parameterisation). The implementation
collapses the inner u sum via Horner's rule across each v-row, then
a second Horner-rule pass in v over the collapsed points; total
surface sample count is (samples + 1)². The spec note in
§"Free-form curve/surface body statements" says the rational form
"does not make sense for Taylor", so rat taylor routes to the same
evaluator without per-vertex weight blending. Synthetic primitives
carry obj:tessellated_surface = true, obj:surface_kind
("taylor"), obj:surface_degree, obj:surface_u_range, obj:surface_v_range, and obj:surface_samples provenance plus the
shared obj:tessellated_curve = true sentinel so the encoder filters
the synthetic geometry out and replays the original cstype / deg / surf / parm / end block verbatim from Scene3D::extras["obj:freeform_directives"]. Basis-matrix surf
surfaces remain captured-only.