New Project

Examples#

116 complete designs live in examples/; each is built by the test suite. Three are shown in full below (and compiled again when this page is generated), then the library is listed.

drawer_stack.kdl#

// examples/drawer_stack.kdl
//
// A BANK OF DRAWERS, instanced at two widths — the worked example of `import` and of
// overriding an assembly's params where it is instanced (proposal 0130, ADR-0020).
//
//   - `import DrawerBox from="std:drawer"` brings in a built-in library (no file needed, so
//     this works in the browser too): a Baltic-birch drawer box with corner finger joints and
//     a captured bottom, parametric in `width`, `depth` and `height`.
//   - `DrawerBank` stacks three of them, each at its own height, from the bank's own params.
//   - `DrawerStack` instances `DrawerBank` twice. The narrow bank keeps its defaults; the
//     wide one overrides `width` (from this file's slider) and `h_low`. Each distinct set of
//     overrides is compiled once and placed wherever it is used, so the two banks are two
//     different sets of parts, not a resized copy.
//
// Part ids run instancing part, then the library's own part names: `Wide/Bottom/Front`.
// For a library that lives in its own file see examples/imports/two_banks.kdl.

project name="Drawer Stack" units=mm schema_version=1 {

    import DrawerBox from="std:drawer" export=DrawerBox

    params {
        bank_width 600.0 min=400.0 max=900.0 step=10.0 label="Wide bank width" category="Envelope"
        bank_gap    60.0 min=30.0  max=200.0 step=5.0  label="Space between banks" category="Envelope"
    }

    assembly DrawerBank {
        params {
            width  400.0 min=250.0 max=900.0 step=10.0 label="Drawer width"
            depth  450.0 min=250.0 max=700.0 step=10.0 label="Drawer depth"
            gap     10.0 min=4.0   max=30.0  step=1.0  label="Gap between drawers"
            h_top   90.0 min=60.0  max=300.0 step=5.0  label="Top drawer height"
            h_mid  120.0 min=60.0  max=300.0 step=5.0  label="Middle drawer height"
            h_low  180.0 min=60.0  max=300.0 step=5.0  label="Bottom drawer height"
        }

        part Top instance=DrawerBox {
            width width
            depth depth
            height h_top
            by top_sw
            pos x=0.0 y=0.0 z=0.0
        }
        part Middle instance=DrawerBox {
            width width
            depth depth
            height h_mid
            by top_sw
            pos x=0.0 y=0.0 z="0.0 - h_top - gap"
        }
        part Bottom instance=DrawerBox {
            width width
            depth depth
            height h_low
            by top_sw
            pos x=0.0 y=0.0 z="0.0 - h_top - h_mid - (2.0 * gap)"
        }
    }

    assembly DrawerStack {
        part Narrow instance=DrawerBank {
            by top_sw
            pos x=0.0 y=0.0 z=0.0
        }
        part Wide instance=DrawerBank {
            width bank_width
            h_low 260.0
            by top_sw
            pos x="400.0 + bank_gap" y=0.0 z=0.0
        }
    }
}

inlaid_tray.kdl#

// examples/inlaid_tray.kdl
//
// BANDING / STRINGING / SUNBURST FIXTURE (M30, docs/rfc/0141-banding-stringing-sunburst.md,
// docs/adr/0025-banding-stringing-inlay.md) — the only piece in the library exercising
// `banding`, `stringing` and `veneer match=sunburst`. Two small show panels of the kind
// a Federal or Hepplewhite maker would inlay: a tray top and a round-fan lid panel.
//
//   Tray     300 x 200 x 22 poplar. Its top carries, from the edge in: a 1.5mm holly
//            string at 6mm, a 10mm herringbone band in walnut at 10mm (two half-strips
//            cut on opposing 45 degree diagonals, glued edge to edge) and a second
//            holly string at 22mm — the two strings are one `repeat`, ADR-0015. Every
//            strip is let flush into its own groove (3mm for the band, 2mm for a
//            string), mitred at the four corners.
//   Fan      160 x 160 x 16 poplar, faced with 8 walnut veneer leaves laid as a
//            sunburst from the middle of the panel, 0.6mm thick (paper-backed).
//
// No existing example fits: the closest, biedermeier_box.kdl, is veneer only — a book
// match, not a fan — and nothing in the library lets a contrasting strip into a face.
//
// Why a tray top and not a drawer front or a table: the inlay's whole claim is that
// the groove and the filler agree, which is a property of one panel's face, not of a
// carcase; a small flat panel isolates it. The strips do not touch the host's other
// parts, because there are none.
//
// Expected clashes, checked with `ww clash`: none. Every filler sits flush in its groove
// (a coplanar, complementary contact, exactly a flush veneer's) and the leaves are
// bonded flush to their own face; no `join` connects any of them to its host.

project name="Inlaid Tray" units=mm schema_version=1 {

    params {
        tray_width  300.0 min=240.0 max=400.0 step=10.0 label="Tray Width"     category="Tray"
        tray_depth  200.0 min=160.0 max=300.0 step=10.0 label="Tray Depth"     category="Tray"
        tray_th      22.0 min=18.0  max=30.0  step=1.0  label="Tray Thickness" category="Tray"
        band_width   10.0 min=6.0   max=14.0  step=1.0  label="Band Width"     category="Inlay"
        band_offset  10.0 min=8.0   max=14.0  step=1.0  label="Band Offset"    category="Inlay"
        string_gap   16.0 min=12.0  max=20.0  step=1.0  label="String Spacing" category="Inlay"
        fan_size    160.0 min=120.0 max=200.0 step=10.0 label="Fan Panel Size" category="Fan"
        fan_leaves    8.0 min=6.0   max=16.0  step=1.0  label="Fan Leaves"     category="Fan"
    }

    materials {
        material Poplar type=hardwood
        // The band: dark against the pale ground.
        material Walnut type=hardwood
        // The strings: the traditional pale line, holly.
        material Holly type=hardwood
    }

    assembly InlaidTray {

        part Tray role=panel {
            stock Poplar tray_width tray_depth tray_th lengthwise
            by top_sw
            pos x=0.0 y=0.0 z=0.0

            // The band, between the two strings. Herringbone: each strip is two half-width
            // pieces at +45 and -45 degrees, so the figure chevrons round the panel.
            banding face=pos_z material=Walnut width=band_width depth=3.0 \
                offset=band_offset pattern=herringbone

            // Two fine lines, one either side of the band: offsets 6 and 22 at the default
            // spacing. `repeat` unrolls in both the groove and the filler generator.
            repeat i count=2 {
                stringing face=pos_z material=Holly offset="6.0 + i * string_gap"
            }
        }

        part Fan role=panel {
            stock Poplar fan_size fan_size 16.0 lengthwise
            by top_sw
            pos x="tray_width + 30.0" y=0.0 z=0.0

            // A sunburst: leaves radiate from the middle of the panel, each clipped to the
            // face. Geometry only — the figure of each leaf is its recorded grain angle.
            veneer face=pos_z material=Walnut thickness=0.6 match=sunburst leaves=fan_leaves
        }
    }
}

chess_pawn.kdl#

// examples/chess_pawn.kdl
//
// A turned boxwood chess pawn: the simplest object that is a pure surface of revolution.
// Real pawn: ~45mm tall; base ~12mm diameter; skirt (belly) ~9mm; ball on top ~8mm.
//
// `stock shape=round` declares the round blank (RFC-0110), and `section axis=z
// interp=spline` (proposal 0101, RFC-0111) sweeps the profile through the ball, neck,
// collar, stem, skirt and base in one `revolve()` call. `AxisTop`/`AxisBottom` (RFC-0112)
// coincide exactly with `top_center`/`bottom_center`, and grain is derived as lengthwise,
// along the axis (RFC-0113).
//
// THE PROFILE, TOP DOWN. A section's `z` runs 0 at the top to negative values below it
// (D4), and a station's `circle r=` is a radius. The ball is sampled on a true sphere of
// radius `ball_diameter / 2` (stations at 0, 45, 90 and 135 degrees round it, the
// 90-degree one the equator), so the ball stays round at every `ball_diameter`. The neck,
// the collar ring (`collar_height` is the whole collar zone, ring and undercut), the stem
// and the skirt are fractions of `belly_diameter` and `total_height`, so every slider
// moves the whole silhouette with it rather than one hard-coded station.
//
// PLACEMENT. The part's origin is its top (D4); `by top_center` with `pos z=total_height`
// stands the pawn on the floor, base at z = 0, top at z = total_height.

project name="Chess Pawn" units=mm schema_version=1 {

    params {
        // ---- Envelope (user-facing) ----
        total_height      45.0 min=40.0 max=50.0 step=1.0 label="Total Height"     category="Envelope"
        base_diameter     12.0 min=10.0 max=14.0 step=0.5 label="Base Diameter"    category="Envelope"
        belly_diameter     9.0 min=8.0  max=10.0 step=0.5 label="Belly Diameter"   category="Envelope"
        collar_height      5.0 min=3.0  max=7.0  step=0.5 label="Collar Height"    category="Envelope"
        ball_diameter      8.0 min=6.0  max=9.0  step=0.5 label="Ball Diameter"    category="Envelope"

        // ---- Stock ----
        // RFC-0110: the blank is the round bar you buy, not the finished shape. It must
        // be at least as wide as the widest turned station, the base at `base_diameter`
        // (14.0 at its slider maximum), and `ww_build::turning` refuses a narrower one
        // (proposal 0101 section 3); `stock_size` therefore starts at that maximum.
        stock_size        14.0 min=14.0 max=16.0 step=0.5 label="Stock Blank"     category="Stock"

        // ---- Derived ----
        ball_r             "ball_diameter / 2.0"
        belly_r            "belly_diameter / 2.0"
        base_r             "base_diameter / 2.0"
        // Where the collar zone starts, below the ball and a short neck.
        collar_top         "ball_diameter + 1.2"
    }

    materials {
        material Boxwood type=hardwood
    }

    // ==================================================================
    // THE PAWN COMPONENT
    // ==================================================================

    component Pawn role=game_piece {
        // RFC-0110: a round blank — the square stock a lathe starts from, `stock_size` on
        // a side, `total_height` long down the spindle axis.
        stock Boxwood shape=round diameter=stock_size z=total_height

        // The turned profile (RFC-0111, proposal 0101 §1.3): a `circle` keyframe at every
        // station a caliper would check on the real pawn, `interp=spline` sweeping a
        // smooth curve between them — the base's cove, the stem's collar-belly-neck
        // curve, the ball's dome — in the one `revolve()` call ADR-0018 verifies. Radii,
        // not diameters, per the grammar; every station reachable from the envelope
        // params above.
        section axis=z interp=spline samples=64 {
            // Ball: four stations round a sphere centred `ball_r` below the top.
            at z=0.0                              { circle r="ball_r * 0.25" }
            at z="0.0 - (ball_r * 0.293)"         { circle r="ball_r * 0.707" }
            at z="0.0 - ball_r"                   { circle r="ball_r" }
            at z="0.0 - (ball_r * 1.707)"         { circle r="ball_r * 0.707" }
            // Neck, then the collar ring: a short flare, the ring, and the undercut.
            at z="0.0 - (ball_diameter + 0.5)"    { circle r="belly_r * 0.4" }
            at z="0.0 - collar_top"               { circle r="belly_r * 0.44" }
            at z="0.0 - (collar_top + 0.5)"       { circle r="belly_r * 0.8" }
            at z="0.0 - (collar_top + (collar_height * 0.4))" { circle r="belly_r * 0.8" }
            at z="0.0 - (collar_top + collar_height)"         { circle r="belly_r * 0.6" }
            // Stem: a slim waist, then the concave flare out to the skirt.
            at z="0.0 - (total_height * 0.52)"    { circle r="belly_r * 0.54" }
            at z="0.0 - (total_height * 0.72)"    { circle r="belly_r * 0.68" }
            at z="0.0 - (total_height * 0.84)"    { circle r="belly_r" }
            // Base: the skirt's foot swells to the base disc, which then runs straight.
            at z="0.0 - (total_height * 0.90)"    { circle r="base_r * 0.96" }
            at z="0.0 - (total_height * 0.93)"    { circle r="base_r" }
            at z="0.0 - (total_height * 0.97)"    { circle r="base_r" }
            at z="0.0 - total_height"             { circle r="base_r" }
        }

        // RFC-0112: `top_center`/`bottom_center` (D6, already free on every part) sit
        // exactly on the spindle axis for a `shape=round` part — the circumscribing
        // square's centre, by construction (ADR-0018 §4). These two marks name it for
        // the assembly's placement and any future joinery (a socket this pawn might sit
        // in), the same role `mark` always plays; they are not a stand-in for a part
        // origin the schema lacks.
        mark AxisTop    x="stock_size / 2.0" y="stock_size / 2.0" z=0.0 normal=pos_z
        mark AxisBottom x="stock_size / 2.0" y="stock_size / 2.0" z="0.0 - total_height" normal=neg_z
    }

    // ==================================================================
    // ASSEMBLY
    // ==================================================================

    assembly ChessPawn {
        // A single pawn, standing on the floor: the top-centre anchor lifted to
        // `total_height`, so the base is at z = 0. Per D5, placement is
        // M = T(pos) * R(rot) * T(-anchor).

        part PawnPiece instance=Pawn {
            by top_center
            pos x=0.0 y=0.0 z=total_height
        }
    }
}

The library#

FileLinesWhat it is
acrylic_panel_frame.kdl91examples/acrylic_panel_frame.kdl
adirondack_plank_chair.kdl337A Westport / Adirondack plank chair, ~720 W x 940 D x 940 H: everything is flat board stock,
adirondack_pole_side_table.kdl268A Great-Camp rustic side table, ~560 W x 420 D x 600 H, built the way the style builds it
appalachian_ladder_back_side_chair.kdl347Appalachian ladder-back side chair -- a post-and-rung chair in the mountain tradition.
appalachian_post_and_rung_bench.kdl456Appalachian post-and-rung bench -- a two-seat hall or porch settle in the mountain tradition.
arched_crest_side_chair.kdl337examples/arched_crest_side_chair.kdl
art_deco_cabinet_on_fuseau_legs.kdl352examples/art_deco_cabinet_on_fuseau_legs.kdl
art_deco_skyscraper_bookcase.kdl287examples/art_deco_skyscraper_bookcase.kdl
arts_crafts_cabinet_on_stand.kdl358examples/arts_crafts_cabinet_on_stand.kdl
arts_crafts_hayrake_table.kdl328examples/arts_crafts_hayrake_table.kdl
backyard_playset.kdl963examples/backyard_playset.kdl
bed.kdl347examples/bed.kdl
bedside_cabinet.kdl588examples/bedside_cabinet.kdl
biedermeier_box.kdl234examples/biedermeier_box.kdl
biedermeier_chest_of_drawers.kdl526examples/biedermeier_chest_of_drawers.kdl
biedermeier_pedestal_table.kdl269examples/biedermeier_pedestal_table.kdl
blanket_chest.kdl703examples/blanket_chest.kdl
bookcase.kdl547examples/bookcase.kdl
chess_pawn.kdl114examples/chess_pawn.kdl
country_rush_seat_ladder_chair.kdl422examples/country_rush_seat_ladder_chair.kdl
curved_apron_side_table.kdl186examples/curved_apron_side_table.kdl
danish_oak_dining_table.kdl248examples/danish_oak_dining_table.kdl
danish_slat_back_chair.kdl399examples/danish_slat_back_chair.kdl
danish_teak_sideboard.kdl481examples/danish_teak_sideboard.kdl
deco_console_table.kdl272examples/deco_console_table.kdl
deco_side_chair.kdl541examples/deco_side_chair.kdl
deco_veneered_tray.kdl104examples/deco_veneered_tray.kdl
desk.kdl449examples/desk.kdl
dining_chair.kdl561examples/dining_chair.kdl
dining_table.kdl381examples/dining_table.kdl
drawer_dividers.kdl69examples/drawer_dividers.kdl (#698)
drawer_stack.kdl72examples/drawer_stack.kdl
ebonised_incised_cabinet.kdl1093examples/ebonised_incised_cabinet.kdl
empire_columned_chest.kdl576examples/empire_columned_chest.kdl
empire_pier_table.kdl356examples/empire_pier_table.kdl
farmhouse_harvest_table.kdl590examples/farmhouse_harvest_table.kdl
federal_chest_of_drawers.kdl592examples/federal_chest_of_drawers.kdl
federal_tapered_leg_sideboard.kdl504examples/federal_tapered_leg_sideboard.kdl
filing_cabinet_lateral.kdl512examples/filing_cabinet_lateral.kdl
filing_cabinet_vertical.kdl594examples/filing_cabinet_vertical.kdl
flat_pack_scale_test_table.kdl161examples/flat_pack_scale_test_table.kdl
glazed_vitrine_whiplash_crest.kdl669examples/glazed_vitrine_whiplash_crest.kdl
high_back_ladder_chair.kdl351examples/high_back_ladder_chair.kdl
incised_walnut_washstand.kdl535examples/incised_walnut_washstand.kdl
inlaid_tray.kdl79examples/inlaid_tray.kdl
jacobean_joined_chest.kdl424examples/jacobean_joined_chest.kdl
jacobean_joint_stool.kdl310examples/jacobean_joint_stool.kdl
japanese_bench.kdl322examples/japanese_bench.kdl
kitchen_collections.kdl204examples/kitchen_collections.kdl
kumiko_andon_lantern.kdl421examples/kumiko_andon_lantern.kdl
loom_shuttle.kdl162examples/loom_shuttle.kdl
mid_century_credenza.kdl410examples/mid_century_credenza.kdl
mid_century_slat_bench.kdl238examples/mid_century_slat_bench.kdl
ming_horseshoe_armchair.kdl495examples/ming_horseshoe_armchair.kdl
ming_waisted_corner_leg_table.kdl471examples/ming_waisted_corner_leg_table.kdl
minimal_slab_low_table.kdl162examples/minimal_slab_low_table.kdl
minimal_wall_console.kdl199examples/minimal_wall_console.kdl
mission_keyed_bookcase.kdl213examples/mission_keyed_bookcase.kdl
mission_slatted_settle.kdl357examples/mission_slatted_settle.kdl
music_stand.kdl588examples/music_stand.kdl
neo_shaker_cherry_sideboard.kdl531Neo-Shaker cherry sideboard, ~1500 x 480 x 880mm: the Shaker case vocabulary (plain
neo_shaker_tapered_leg_table.kdl253Neo-Shaker cherry tapered-leg dining table, ~1600 x 850 x 740mm: the Shaker table
oak_floating_wall_shelf.kdl229examples/oak_floating_wall_shelf.kdl
oak_koshikake_bench.kdl311examples/oak_koshikake_bench.kdl
panel_door_and_window.kdl400examples/panel_door_and_window.kdl
pasadena_bedside_chest.kdl493examples/pasadena_bedside_chest.kdl
pasadena_library_table.kdl330examples/pasadena_library_table.kdl
pedestal_table.kdl178examples/pedestal_table.kdl
pennsylvania_dower_chest.kdl502examples/pennsylvania_dower_chest.kdl
pennsylvania_schrank.kdl757examples/pennsylvania_schrank.kdl
pierced_splat_side_chair.kdl566examples/pierced_splat_side_chair.kdl
pop_laminate_stepped_sideboard.kdl292examples/pop_laminate_stepped_sideboard.kdl
pop_laminate_totem_divider.kdl331examples/pop_laminate_totem_divider.kdl
postmodern_broken_pediment_cabinet.kdl331examples/postmodern_broken_pediment_cabinet.kdl
postmodern_flat_silhouette_chair.kdl231examples/postmodern_flat_silhouette_chair.kdl
primary_grid_lath_armchair.kdl327examples/primary_grid_lath_armchair.kdl
primary_grid_lath_side_table.kdl232examples/primary_grid_lath_side_table.kdl
queen_anne_side_chair.kdl553examples/queen_anne_side_chair.kdl
queen_anne_tea_table.kdl272Queen Anne tea table: a walnut tray-top table on four cabriole legs with pad feet and
scandinavian_birch_shelving_unit.kdl201examples/scandinavian_birch_shelving_unit.kdl
scandinavian_birch_trestle_desk.kdl274examples/scandinavian_birch_trestle_desk.kdl
serpentine_chest_bracket_feet.kdl508Serpentine chest of drawers on ogee bracket feet: mahogany with poplar secondaries, in the
serpentine_sideboard.kdl390examples/serpentine_sideboard.kdl
shaker_cherry_side_chair.kdl619examples/shaker_cherry_side_chair.kdl
shaker_side_table.kdl469examples/shaker_side_table.kdl
shaker_tall_chest_of_drawers.kdl452examples/shaker_tall_chest_of_drawers.kdl
shaker_trestle_dining_table.kdl329Shaker trestle dining table, ~1830 x 840 x 740mm: a pine top with pinned breadboard
shield_back_side_chair.kdl364examples/shield_back_side_chair.kdl
shoe_bench.kdl1042examples/shoe_bench.kdl
six_board_chest.kdl259examples/six_board_chest.kdl
speaker_ported.kdl323examples/speaker_ported.kdl
speaker_sealed.kdl323examples/speaker_sealed.kdl
speaker_transmission_line.kdl247examples/speaker_transmission_line.kdl
spindle.kdl170examples/spindle.kdl
square_back_side_chair.kdl498examples/square_back_side_chair.kdl
step_ladder.kdl351examples/step_ladder.kdl
studio_cabinet_on_stand.kdl457A small studio-craft cabinet on a stand, ~480 W x 330 D x 1080 H: the form the style's own
studio_slab_dining_table.kdl271A studio-craft slab dining table, ~1900 x 900 x 740 mm, in the form the style's own sketch
tall_white_cutout_cabinet.kdl301examples/tall_white_cutout_cabinet.kdl
tansu_kiri_chest.kdl445examples/tansu_kiri_chest.kdl
three_legged_stool.kdl611examples/three_legged_stool.kdl
trestle_table.kdl193
turned_leg_work_table.kdl205examples/turned_leg_work_table.kdl
victorian_balloon_back_chair.kdl544examples/victorian_balloon_back_chair.kdl
victorian_parlour_table.kdl335examples/victorian_parlour_table.kdl
wagon_wheel.kdl784examples/wagon_wheel.kdl
wall_shelf.kdl253examples/wall_shelf.kdl
walnut_side_table.kdl214examples/walnut_side_table.kdl
wedged_post_and_rung_stool.kdl169examples/wedged_post_and_rung_stool.kdl
welsh_dresser.kdl966examples/welsh_dresser.kdl
whiplash_leg_side_table.kdl469examples/whiplash_leg_side_table.kdl
william_and_mary_chest_of_drawers.kdl520examples/william_and_mary_chest_of_drawers.kdl
william_and_mary_lowboy.kdl657examples/william_and_mary_lowboy.kdl
windsor_fan_back_side_chair.kdl661examples/windsor_fan_back_side_chair.kdl
windsor_round_stool.kdl428examples/windsor_round_stool.kdl
workbench.kdl383examples/workbench.kdl

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