Turning & Sections#
Faceplate turning, profile sections, and turned-part cards
Names: stock section turn profile
When to use#
- A part with a round cross-section made on a lathe: a spindle, baluster, leg, bowl, platter, pedestal-table top or foot.
- A rectangular member that changes size along its length: a tapered spoke or a leg narrowing to a foot.
- You want the cut list to say how the grain runs on a disc (
across axis (faceplate)).
Not for a flat round outline with the faces left flat (use cut_path), nor for a curved
(barrel or ogee) rectangular profile (not built: RFC-0101 stays partial for that alone).
Syntax#
section defines the part's base solid, the role stock's cube plays for every other
part. circle/profile turned sections are axis=z only (one spindle axis). A rect
section may sweep axis=z (default), axis=x or axis=y (#459, ADR-0034's "not done" bullet
— now built): the physical bound names rect and at take follow the sweep axis.
axis= | at key | rect bounds | sweep runs |
|---|---|---|---|
z (default) | z= | x_min= x_max= y_min= y_max= | z = 0 to z = -size.z (top face to foot) |
x | x= | y_min= y_max= z_min= z_max= | x = 0 to x = size.x |
y | y= | x_min= x_max= z_min= z_max= | y = 0 to y = size.y |
Stations and bounds are otherwise in the part's own frame (D4): for axis=z, z = 0 is the
top face and down is negative.
stock <Material> shape=round diameter=<d> z=<length> [grain=across] // round blank
stock <Material> <x> <y> <z> // rect blank
section axis=z [interp=linear|spline] [samples=<n>] {
at z=<expr> { circle r=<expr> } // spindle: radius at a station
}
section axis=z { profile { line … arc … polyline { point x= y= } } } // faceplate: drawn outline
section axis=z { at z=<expr> { rect x_min= x_max= y_min= y_max= } } // tapered rect member
- Spindle (
circlestations). Grain is derived lengthwise.interp=linearjoins the stations;interp=spline(samples=, default 64) draws a centripetal curve through them. - Faceplate (
grain=across). The blank is a disc cut from a board; the grain crosses the axis. Pair it with aprofile: a closed outline in (radius, z) (xis the distance from the axis), written with the sameline/arc/polylinechildren ascut_path, chained end to start. The closing edge back to the first point is implied, so write the outline from the axis at one face, out around the profile, and back to the axis. Winding is normalised;interp=andsamples=do not apply; asectionis stations or aprofile, never both. - Curved rect member (
interp=splineonrectstations, ADR-0034). Each of the four bounds is a smooth curve through its keyframes;samples=<n>(chords per interval) ortolerance=<len>(default 0.01) sets the fineness, one or the other. See the worked case inexamples/trestle_table.kdl. - Tapered rect member (
rectstations). Straight between keyframes. Stations must run the whole part (the sweep axis's own0to its far face; repeat a rectangle to hold a run constant), and no rectangle may leave the blank.rectbounds are corner-anchored: for a taper that keeps one face flush, hold the lower bound at0.0on every station; for a centred taper, inset both sides equally. axis=x/axis=ymember (a curved apron or shaped rail, #459). The apron's own length runs along its local sweep axis, whichever way it is placed in the assembly (a side apron turned 90 degrees still sweeps its ownaxis=x, never a secondaxis=ycase). Worked case:examples/curved_apron_side_table.kdl'sApron(axis=x interp=spline, full height where it tenons into a leg, waisted thinner at mid-span).- A square pommel over a turning (square
stockpluscirclestations that stop short of the top) is the RFC-0127 form indocs/KDL_AUTHORING.md§6.
Example#
project name="Turned And Tapered" units=mm schema_version=1 {
materials {
material Maple type=hardwood
material Oak type=hardwood
}
// A faceplate bowl: a disc cut from a board, grain across the lathe axis. The
// profile is a closed outline in (radius, z); the edge down the axis is implied.
component Bowl role=bowl {
stock Maple shape=round diameter=200.0 z=70.0 grain=across
section axis=z {
profile {
polyline {
point x=0.0 y="0.0 - 70.0"
point x=60.0 y="0.0 - 70.0"
point x=100.0 y="0.0 - 20.0"
point x=100.0 y=0.0
point x=92.0 y=0.0
point x=0.0 y="0.0 - 60.0"
}
}
}
}
// A spindle: stations of diameter, grain derived lengthwise.
component Baluster role=baluster {
stock Maple shape=round diameter=40.0 z=300.0
section axis=z interp=spline {
at z=0.0 { circle r=14.0 }
at z="0.0 - 60.0" { circle r=20.0 }
at z="0.0 - 150.0" { circle r=10.0 }
at z="0.0 - 300.0" { circle r=16.0 }
}
}
// A tapered rectangular member: straight between keyframes, whole length.
component Spoke role=spoke {
stock Oak 44.0 44.0 420.0
section axis=z {
at z=0.0 { rect x_min=0.0 x_max=44.0 y_min=0.0 y_max=44.0 }
at z="0.0 - 40.0" { rect x_min=0.0 x_max=44.0 y_min=0.0 y_max=44.0 }
at z="0.0 - 420.0" { rect x_min=7.0 x_max=37.0 y_min=7.0 y_max=37.0 }
}
}
assembly Set {
part Bowl1 instance=Bowl {
by top_center
pos x=0.0 y=0.0 z=0.0
}
part Baluster1 instance=Baluster {
by top_center
pos x=300.0 y=0.0 z=0.0
}
part Spoke1 instance=Spoke {
by top_sw
pos x=500.0 y=0.0 z=0.0
}
}
}
The compiled cut list prints across axis (faceplate) for the bowl, along axis for the
baluster and lengthwise for the spoke. Each turned part's drawing card carries a TURNED
line with one depth below top → ⌀ pair per authored station (a tapered member prints
→ width × thickness); on a rect section, "depth below top" is axis=z's own wording — an
axis=x/axis=y member's card instead reads "depth from {entry face}" (e.g. depth from x=0), since it has no top or foot. Full worked examples: examples/pedestal_table.kdl
(turned), examples/curved_apron_side_table.kdl (axis=x rect section).
Pitfalls and diagnostics#
grain=acrosson rect stock is refused: rect stock states grain as its fifth positional argument. On round stockacrossis the only value.- "declared blank is …mm across, but the
profilereaches …": thediametermust cover the widest point. Likewise a profile taller thanz=. - "reaches x=-…":
xis a distance from the axis and cannot be negative; the kernel would silently clip it, so it is refused. - "does not close into a loop that encloses an area": segments must chain end to start, and the outline must not cross itself. Do not repeat the first point at the end.
- A
splinechild insideprofileis not a segment; useline,arcorpolyline. - "a
rectsection must run the whole part": add a station atz=0.0and one atz="0.0 - <length>". - "leaves the blank": a section only removes material; widen the
stock. circlebesiderect: onesectionis one shape family.- "overshoots the blank" (
interp=splineonrectstations): the smooth curve bulged past the stock between keyframes. Add a keyframe where the curve turns, or declare the blank wider. A curve that "doubles back inz", or "pinches the member", is refused too. samples=/tolerance=withoutinterp=spline, or both together, are refused.- A
kdl-checkwarning onby top_sw(or any corner/edge anchor) of a round part: usetop_center,bottom_centerorcenter, which are the axis. - Turning is a bench operation in the fabrication pack: no CNC setup is generated for it.
- A mark on the curved surface of a turning is not reachable; only the flat ends
(
normal=pos_z/neg_z) are.
See also#
docs/KDL_AUTHORING.md§6 Turned stock, and §7 fortaper(still supported; arectsection builds the same solid, andexamples/wagon_wheel.kdl's spoke now uses one)docs/adr/0018-turned-stock.md,docs/adr/0031-faceplate-turning-and-profile-sections.md,docs/adr/0034-curved-rect-sections.mddocs/rfc/0129-faceplate-and-profile-path-turning.md,docs/rfc/0101-functional-sections.md,docs/rfc/0127-round-tenon.mddocs/superpowers/specs/2026-10-11-curved-rect-section-axis-x-design.md(#459,axis=x/axis=yon arectsection)examples/pedestal_table.kdl,examples/chess_pawn.kdl,examples/spindle.kdl,examples/wagon_wheel.kdl,examples/curved_apron_side_table.kdl
Names#
Every name this page declares, how the example library uses it, and the shortest real use.
stock#
feature; node in 114 of 116 examples (910 uses).
Shortest real use, from glazed_vitrine_whiplash_crest.kdl:
stock Glass dw 6.0 dh
section#
feature, word-valued property; node in 47 of 116 examples (93 uses); property in 18 of 116 examples (36 uses).
Shortest real use, from pop_laminate_stepped_sideboard.kdl:
section axis=z interp=linear {
at z=0.0 { circle r="drum_d / 2.0" }
at z="0.0 - drum_h" { circle r="drum_d / 2.0" }
}
turn#
not used by any example yet.
profile#
word-valued property; node in 11 of 116 examples (12 uses).
Shortest real use, from arts_crafts_cabinet_on_stand.kdl:
profile "square"