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#
materialfor anything you cut from stock: a timber species, a sheet good, solid metal.hardwarefor 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,sheetormetal. Asheetdeclares bothnominal_th=andfinished_th=; joinery uses the finished figure (real plywood is undersized). Glass and laminate aresheet.metalis solid stock with no grain.- Any
materialmay addtolerance_slip=/tolerance_snug=/tolerance_press=(mm, issue #55): the female-side clearance a joint'sfit=resolves (joinery-contract), read byfitclass, 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 — seedocs/KDL_AUTHORING.md§5 for the draft table and sourcing. mill=(issue #56,hardwood/softwoodonly — an error onsheet): how far along the rough-to-S4S road the material's boards already are. Defaults4s(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/s2sadds 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 anymaterialand on anypart; a CEL expression to text, printed on the cut sheet. A part's ownfinish=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=andpart_no=are plain-text labels (never CEL);price=and every other property are CEL numbers, so a param can drive them. Typical: a hinge'sleaf_lengthleaf_widthleaf_thicknessknuckle_dia, a slide'stravel_distanceslide_depthload_kg.- Two ways to use hardware (ADR-0017). Mounted:
joinery hardware_mount name=... { hardware <Name> qty=<n> }applied through an ordinaryjoinon two marks. It cuts nothing, likebutt: no leaf mortise and no swing envelope are modelled. Unmounted: a barehardware_use <Name> qty=<n> [at=Part@Mark]fact, for a slide screwed between two flat faces, a hank of rush, a box of screws.qtydefaults to 1;at=is provenance only and is never checked against a mark. - Either way the item reaches the hardware schedule (
ww pack'shardware-schedule.txt/.json) with a summed quantity, never the cut list. @nameslot references work anywhere a material or hardware name goes (seereuse-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=sheetmaterial is a hard error (ADR-0007): sheet goods are cross-laminated and have no solid-timber grain. - Declare both
nominal_thandfinished_thon asheetmaterial (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
componentwith fakestock. Acomponentneeds exactly onestockline, and a hinge has no board to mill.kdl-checkwarns on ahardwareitem that is declared and never named byhardware_mountorhardware_use. finish=hardwood(bare word) reads as an unknown identifier; quote it as a CEL string.hardware_mountplacement 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/(seeINDEX.md) documents it, that file'sstatus:says whether it is built.
See also#
docs/KDL_AUTHORING.md§5 (materials,hardware), §15 (materialcolor=).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.kdlandexamples/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