Spline
App: apps/spline_demo/
Demonstrates the Spline curve primitive (engine PLM-243 / ADR 0080), the
keystone of Block SPL (splines / geometry / scatter). A 5-point Catmull-Rom curve
is drawn as a line strip and its rotation-minimizing orientation
frames are drawn as gizmos — tangent
red, normal green, binormal blue — the moving basis a mesh extruder sweeps a profile
along.
Run from root
Section titled “Run from root”% ./plume3d spline_demoAn oblique camera looks at the curvy 3D path; the line strip traces it and 16 evenly-spaced axis gizmos ride along it. The demo captures a screenshot at frame 90 and exits.
What it does
Section titled “What it does”-
Builds an empty spline and appends five control points (the default type is
"catmullrom", which passes through every point), then logs its arc length:_spline = Spline.new()_spline.addPoint(-4, 0, -2)_spline.addPoint(-2, 2.5, 2)_spline.addPoint(0.5, -1.5, 3)_spline.addPoint(2.5, 2, -1)_spline.addPoint(4, -0.5, -3)Logger.info("spline length = %(_spline.length), points = %(_spline.pointCount)") -
Samples the curve as a line strip at constant arc-length spacing — using
positionAtDistancerather thanposition(t), so the vertices never bunch up on the tight turns (tis not constant-speed):var L = _spline.lengthvar n = 80var cv = []for (i in 0...n) {var p = _spline.positionAtDistance(L * i / (n - 1)) // p = [x, y, z]cv.add([p[0], p[1], p[2], 0, 1, 0, 0.95, 0.85, 0.25, 1, 0, 0])}_curve = Graphics.newMesh(cv, "linestrip", _flat) -
Asks for 16 evenly-spaced orientation frames and draws each frame’s three axes as gizmo lines. Each frame is a flat 13-number list
[px,py,pz, tx,ty,tz, nx,ny,nz, bx,by,bz, width], so the tangent is slots3..5, the normal6..8, and the binormal9..11:var frames = _spline.sampleFrames(16)for (f in frames) {addAxis(gz, f, 3, 6, g, [1.0, 0.35, 0.35]) // tangent (red)addAxis(gz, f, 6, 9, g, [0.35, 1.0, 0.4]) // normal (green)addAxis(gz, f, 9, 12, g, [0.4, 0.6, 1.0]) // binormal (blue)}
- The frames are rotation-minimizing — they transport the normal along the curve without twist, so the gizmo basis never suddenly flips over between samples.
sampleFrames(count)is the direct input to mesh extrusion: place a cross-section profile at each frame’s position, oriented by its normal/binormal and scaled by itswidthslot.
See Spline for the full method surface — Bézier / closed-loop / roll
options, addPointFull per-point width, and the t-vs-distance distinction.