New Project

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 keyrect boundssweep runs
z (default)z=x_min= x_max= y_min= y_max=z = 0 to z = -size.z (top face to foot)
xx=y_min= y_max= z_min= z_max=x = 0 to x = size.x
yy=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 (circle stations). Grain is derived lengthwise. interp=linear joins 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 a profile: a closed outline in (radius, z) (x is the distance from the axis), written with the same line / arc / polyline children as cut_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= and samples= do not apply; a section is stations or a profile, never both.
  • Curved rect member (interp=spline on rect stations, ADR-0034). Each of the four bounds is a smooth curve through its keyframes; samples=<n> (chords per interval) or tolerance=<len> (default 0.01) sets the fineness, one or the other. See the worked case in examples/trestle_table.kdl.
  • Tapered rect member (rect stations). Straight between keyframes. Stations must run the whole part (the sweep axis's own 0 to its far face; repeat a rectangle to hold a run constant), and no rectangle may leave the blank. rect bounds are corner-anchored: for a taper that keeps one face flush, hold the lower bound at 0.0 on every station; for a centred taper, inset both sides equally.
  • axis=x / axis=y member (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 own axis=x, never a second axis=y case). Worked case: examples/curved_apron_side_table.kdl's Apron (axis=x interp=spline, full height where it tenons into a leg, waisted thinner at mid-span).
  • A square pommel over a turning (square stock plus circle stations that stop short of the top) is the RFC-0127 form in docs/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=across on rect stock is refused: rect stock states grain as its fifth positional argument. On round stock across is the only value.
  • "declared blank is …mm across, but the profile reaches …": the diameter must cover the widest point. Likewise a profile taller than z=.
  • "reaches x=-…": x is 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 spline child inside profile is not a segment; use line, arc or polyline.
  • "a rect section must run the whole part": add a station at z=0.0 and one at z="0.0 - <length>".
  • "leaves the blank": a section only removes material; widen the stock.
  • circle beside rect: one section is one shape family.
  • "overshoots the blank" (interp=spline on rect stations): 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 in z", or "pinches the member", is refused too.
  • samples= / tolerance= without interp=spline, or both together, are refused.
  • A kdl-check warning on by top_sw (or any corner/edge anchor) of a round part: use top_center, bottom_center or center, 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 for taper (still supported; a rect section builds the same solid, and examples/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.md
  • docs/rfc/0129-faceplate-and-profile-path-turning.md, docs/rfc/0101-functional-sections.md, docs/rfc/0127-round-tenon.md
  • docs/superpowers/specs/2026-10-11-curved-rect-section-axis-x-design.md (#459, axis=x/ axis=y on a rect section)
  • 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"

Settings

Region

A region picks sensible defaults; change any of these separately.

Units

In inches, type lengths the way you say them: 34 1/2, 3/4", 1'-2" or 12.7mm. A length that can't be read is flagged, never rounded to something else.

Paper
Date order
Clock