Components & Stock#
Grain direction and marks for joining
Names: component stock role grain mark normal tilt heading lengthwise crosswise
When to use#
Every distinct piece of timber or sheet is one component (a reusable template) with exactly
one stock line, plus the marks that joints attach to. Use a part with an inline stock
(see parts-and-assemblies) for a one-off that nothing else reuses. Turned (round) stock
and its section profile are in round-stock-sections.
Syntax#
component <Name> [role=<free text>] {
[params { ... }] // defaults, overridable per instance
stock <Material> <x> <y> <z> [lengthwise|crosswise] // REQUIRED, exactly one
mark <Name> x=<expr> y=<expr> z=<expr> normal=<face> [tilt=<expr> heading=<expr>]
<features...> // see edge-and-face-cuts, cut-paths
}
stock <Material> x y z: the material name, then three positional dimensions (floats or CEL), then an optional grain word.xis width,yis depth,zis length down the part (the part's own frame, ADR-0007). Exactly one per component. Aparthas eitherinstance=or an inlinestock, never both.- Grain (
lengthwisedefault, along the longest dimension; orcrosswise). State it where it decides a joint. Atype=sheetmaterial takes no grain (hard error). The grain word vocabulary and the style finish rule are a separate family; seeINDEX.md. role=is free text for BOM grouping (leg,apron,rail,stile,panel,top,shelf,door,drawer_face, ...). It has no compiler meaning, except thatrole=referencemakes a part a reference part (seeparts-and-assemblies).markis a named datum: a point plus a facing, attached to the part's own frame. Joints address it asPart@Mark.normalis one ofpos_x neg_x pos_y neg_y pos_z neg_zand points out of the material, toward the mating part. Write coordinates in the component's own params (x=leg_dim,y="apron_th / 2.0"), never as bare constants.tilt=/heading=(RFC-0022, built in M25) make a mark an oriented reference: the facing leanstiltdegrees off the named face's outward direction, towardheadingdegrees counter-clockwise from that face's own+u. Both default to0.0and then the mark is exactly the named face. Use them for a mitred end, a compound-angle approach or a spoke at an azimuth. A mark that sits set back from a face but still faces squarely along an axis needs neither. Worked examples:examples/wagon_wheel.kdl(Hub,Felloe).paramsinside a component are defaults an instance can override with child nodes on itspartline.
Example#
project name="Leg Frame" units=mm schema_version=1 {
params {
leg_dim 45.0 min=30.0 max=70.0 step=1.0 label="Leg" category="Stock"
leg_len 700.0 min=400.0 max=900.0 step=10.0 label="Leg length" category="Envelope"
felloe_half_angle 18.0
}
materials { material Ash type=hardwood }
component Leg role=leg {
stock Ash leg_dim leg_dim leg_len lengthwise
mark MortiseFace_X x=leg_dim y="leg_dim / 2.0" z=-55.0 normal=pos_x
// an oriented mark: leans off pos_x by the mitre's half angle
mark Spoke_1 x=leg_dim y="leg_dim / 2.0" z=-300.0 normal=pos_x tilt=felloe_half_angle heading=0.0
}
assembly Root {
part Leg_A instance=Leg { by top_sw; pos x=0.0 y=0.0 z=0.0 }
}
}
Pitfalls and diagnostics#
- A component declared and never instantiated by a
partis akdl-checkwarning. It is a real bug that has happened: a Welsh dresser's centre support was declared with marks and never placed, so the shelf span was more than double what the file claimed. - A mark not on any real stock face fails at
jointime, not at themarkline. Withtilt=/heading=this now covers a mitred end or compound corner that is within the stock. Still not built: a mark on a curved turned surface (only the flat axis ends,normal=pos_z/neg_z, are reachable) and a mortise cut into a curved face. Tenon into the square pommel instead (seeround-stock-sections). A compound mitre joint (miterthat leans and turns) is also not synthesised; seejoinery-frames. - A mark's coordinates are in the component's frame before any
rot; the placement is the part'sby/pos/rot, not the mark's. - A
componentwith nostocknode is akdl-checkerror ("has nostocknode"). Write exactly one (KDL_AUTHORING §6); the position of the line among the features does not matter. - Mark names and
id=s inside arepeatmust interpolate the loop variable (mark "Pin_{i}" ...), or they collide (kdl-checkenforces this). shape=roundtakes no grain argument; naming one is rejected.
See also#
docs/KDL_AUTHORING.md§6 (component,mark), §7b (naming), ADR-0007 (the stock line).docs/rfc/0022-compound-angle-joint-frame.md(resolved; the residual gaps above).parts-and-assemblies.md(placing a component),joinery-contract.md(what marks are for),round-stock-sections.md(turned stock).
Names#
Every name this page declares, how the example library uses it, and the shortest real use.
component#
project-level node; node in 110 of 116 examples (819 uses); value in 1 of 116 examples (1 uses).
Shortest real use, from glazed_vitrine_whiplash_crest.kdl:
component Pane role=glass {
stock Glass dw 6.0 dh
}
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
role#
word-valued property; property in 114 of 116 examples (900 uses).
Shortest real use, from glazed_vitrine_whiplash_crest.kdl:
component Pane role=glass {
stock Glass dw 6.0 dh
}
grain#
feature, word-valued property; property in 2 of 116 examples (3 uses).
Shortest real use, from biedermeier_pedestal_table.kdl:
stock Cherry shape=round diameter=top_diameter z=top_thickness grain=across
mark#
feature; node in 110 of 116 examples (2193 uses).
Shortest real use, from windsor_fan_back_side_chair.kdl:
mark Top x=7.5 y=7.5 z=0.0 normal=pos_z
normal#
word-valued property; property in 110 of 116 examples (2207 uses).
Shortest real use, from windsor_fan_back_side_chair.kdl:
mark Top x=7.5 y=7.5 z=0.0 normal=pos_z
tilt#
property; property in 2 of 116 examples (6 uses).
Shortest real use, from primary_grid_lath_armchair.kdl:
mark Seat x=0.0 y="lath / 2.0" z="0.0 - dm" normal=neg_x tilt=0.01 heading=0.0
heading#
property; property in 2 of 116 examples (6 uses).
Shortest real use, from primary_grid_lath_armchair.kdl:
mark Seat x=0.0 y="lath / 2.0" z="0.0 - dm" normal=neg_x tilt=0.01 heading=0.0
lengthwise#
grain; value in 26 of 116 examples (84 uses).
Shortest real use, from ming_horseshoe_armchair.kdl:
stock Huanghuali length th h lengthwise
crosswise#
grain; not used by any example yet.