Skip to content

v0.0.3

Choose a tag to compare

@MagicalTux MagicalTux released this 30 May 02:37
· 30 commits to master since this release
262971c

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.