New Project

Materials & Hardware#

Material definitions, finish, colour, and purchased hardware catalogue items

Names: materials material type color finish hardware hardware_use hardware_mount qty

When to use#

  • material for anything you cut from stock: a timber species, a sheet good, solid metal.
  • hardware for anything you buy as-is and never machine: hinges, pulls, slides, screws, nails, casters, and non-wood fill sold by the hank or roll (rush, cane, webbing).
  • finish= to print a finishing note on the cut sheet. color= only to tint a material in the viewer.

This file covers the declarations and how hardware reaches the hardware schedule. Recesses and proxy geometry for hardware are a separate family; see INDEX.md.

Syntax#

materials {
    material <Name> type=hardwood|softwood|sheet|metal [nominal_th= finished_th=] [mill=rough|s2s|s4s|dimensional] [finish="'...'"] [color="#rrggbb"]
    hardware <Name> [supplier="..." part_no="..."] [price=<expr>] [<any other numeric property>=<expr>]
}
hardware_use <Name> [qty=<int|expr>] [at=<Part>@<Mark>]
joinery hardware_mount name=<J> { hardware <Name> qty=<n> }
  • type=: hardwood, softwood, sheet or metal. A sheet declares both nominal_th= and finished_th=; joinery uses the finished figure (real plywood is undersized). Glass and laminate are sheet. metal is solid stock with no grain.
  • Any material may add tolerance_slip=/tolerance_snug=/tolerance_press= (mm, issue #55): the female-side clearance a joint's fit= resolves (joinery-contract), read by fit class, female material wins. movement_radial_pct=/movement_tangential_pct= store a material's cited shrinkage for CEL and for reference; never applied to geometry automatically — see docs/KDL_AUTHORING.md §5 for the draft table and sourcing.
  • mill= (issue #56, hardwood/softwood only — an error on sheet): how far along the rough-to-S4S road the material's boards already are. Default s4s (already at finished size, zero allowance) when left off — every example that predates this issue omits it and keeps its exact stock-list/BOM output. mill=rough/s2s adds a milling allowance (by mill state, never by species) to the purchase size the stock list and BOM report alongside the finished size.
  • finish= (RFC-0122): optional on any material and on any part; a CEL expression to text, printed on the cut sheet. A part's own finish= overrides its material's. Write a real string literal: finish="'milk paint, barn red'".
  • color="#RRGGBB" (or #rgb): presentation only (viewer and scene JSON). A value that is not a hex colour is a warning, must be a hex string such as "#c8a06e"; ignored.
  • hardware <Name> takes free-form properties, kept verbatim: supplier= and part_no= are plain-text labels (never CEL); price= and every other property are CEL numbers, so a param can drive them. Typical: a hinge's leaf_length leaf_width leaf_thickness knuckle_dia, a slide's travel_distance slide_depth load_kg.
  • Two ways to use hardware (ADR-0017). Mounted: joinery hardware_mount name=... { hardware <Name> qty=<n> } applied through an ordinary join on two marks. It cuts nothing, like butt: no leaf mortise and no swing envelope are modelled. Unmounted: a bare hardware_use <Name> qty=<n> [at=Part@Mark] fact, for a slide screwed between two flat faces, a hank of rush, a box of screws. qty defaults to 1; at= is provenance only and is never checked against a mark.
  • Either way the item reaches the hardware schedule (ww pack's hardware-schedule.txt/.json) with a summed quantity, never the cut list.
  • @name slot references work anywhere a material or hardware name goes (see reuse-and-collections).

Example#

project name="Hinged Lid" units=mm schema_version=1 {
    params { glue_clearance 0.2 }
    materials {
        material WhiteOak type=hardwood finish="'danish oil'"
        material Ply type=sheet nominal_th=18.0 finished_th=17.6 color="#c8a06e"
        hardware ButtHinge_75mm supplier="Horton Brasses" part_no="H-06-75AB" \
            leaf_length=75.0 leaf_width=45.0 leaf_thickness=2.5 knuckle_dia=8.0 price=6.50
        hardware BallBearingSlide_16x300 travel_distance=300.0 slide_depth=16.0 load_kg=30.0 price=14.0
    }
    component Base role=carcass {
        stock Ply 400.0 300.0 18.0
        mark Hinge_Top x=400.0 y=150.0 z=0.0 normal=pos_x
    }
    component Lid role=door {
        stock WhiteOak 400.0 300.0 18.0
        mark Hinge_Top x=0.0 y=150.0 z=0.0 normal=neg_x
    }
    joinery hardware_mount name=LidHinge {
        hardware ButtHinge_75mm qty=2
    }
    assembly Root {
        part Carcass instance=Base { by top_sw; pos x=0.0 y=0.0 z=0.0 }
        part Lid instance=Lid finish="'shellac'" { by top_sw; pos x=400.0 y=0.0 z=0.0 }
        join joint=LidHinge male=Lid@Hinge_Top female=Carcass@Hinge_Top
        hardware_use BallBearingSlide_16x300 qty=2
    }
}

Pitfalls and diagnostics#

  • Naming a grain on a type=sheet material is a hard error (ADR-0007): sheet goods are cross-laminated and have no solid-timber grain.
  • Declare both nominal_th and finished_th on a sheet material (KDL_AUTHORING §5). The parser keeps them verbatim and does not refuse a missing one, so an omission is silent: joinery and the sheet packer then lack the real thickness. Using the nominal figure for a dado width is the classic error.
  • Never model a purchased part as a component with fake stock. A component needs exactly one stock line, and a hinge has no board to mill. kdl-check warns on a hardware item that is declared and never named by hardware_mount or hardware_use.
  • finish=hardwood (bare word) reads as an unknown identifier; quote it as a CEL string.
  • hardware_mount placement is not geometry: nothing is recessed or swung. Do not expect a clash or a recess from it.
  • supplier= / part_no= are labels, never expressions; price= is an expression.
  • Not covered here: hardware with a placed recess or proxy geometry. If a sibling file in features/ (see INDEX.md) documents it, that file's status: says whether it is built.

See also#

  • docs/KDL_AUTHORING.md §5 (materials, hardware), §15 (material color=).
  • docs/adr/0017-hardware-and-materials.md, docs/rfc/0122-finish-attribute.md, docs/rfc/0121-non-wood-materials-and-hardware.md.
  • components-and-stock.md (grain), reuse-and-collections.md (slots), examples/loom_shuttle.kdl and examples/filing_cabinet_vertical.kdl (hardware_use).

Names#

Every name this page declares, how the example library uses it, and the shortest real use.

materials#

project-level node; node in 114 of 116 examples (114 uses).

Shortest real use, from spindle.kdl:

materials {
    material Ash type=hardwood
}

material#

word-valued property; node in 114 of 116 examples (309 uses); property in 34 of 116 examples (116 uses); value in 1 of 116 examples (3 uses).

Shortest real use, from spindle.kdl:

material Ash type=hardwood

type#

word-valued property; property in 114 of 116 examples (309 uses).

Shortest real use, from spindle.kdl:

material Ash type=hardwood

color#

property; property in 85 of 116 examples (234 uses).

Shortest real use, from ebonised_incised_cabinet.kdl:

material Brass type=metal color="#b8923a"

finish#

property; property in 78 of 116 examples (147 uses).

Shortest real use, from farmhouse_harvest_table.kdl:

material Pine type=softwood finish="'none'"

hardware#

word-valued property; node in 36 of 116 examples (112 uses); value in 1 of 116 examples (1 uses).

Shortest real use, from kitchen_collections.kdl:

hardware @pull

hardware_use#

node in 5 of 116 examples (15 uses).

Shortest real use, from pennsylvania_schrank.kdl:

hardware_use DoorLock qty=1

hardware_mount#

joinery kind; value in 35 of 116 examples (49 uses).

Shortest real use, from step_ladder.kdl:

joinery hardware_mount name=TieRod { hardware TieRod_Steel }

qty#

property; property in 19 of 116 examples (34 uses).

Shortest real use, from adirondack_plank_chair.kdl:

hardware WoodScrew qty=2

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