New Project

Hardware Mounting#

Placement, profile, recess cuts, and display-proxy geometry for catalogue hardware

Names: hardware hardware_mount hardware_use distribute

When to use#

Use it when a purchased item has a position on the wood, or asks something of it: a knob or pull that is screwed through a door front, a hinge whose leaf is let into an edge, a bail handle you want to see in the viewer. If the item only needs counting (a box of screws, a slide, a hank of rush) use hardware_use and stop; nothing here is needed.

Keywords: knob, pull, handle, hinge, leaf, recess, mortise, bore, screw hole, drawer pull, bail, proxy, display, hardware_mount, one-sided join.

Syntax#

A catalogue item in materials. Only the numbers the cut or the picture needs:

hardware <Name> supplier="…" part_no="…" price=<n> \
    screw_diameter=<n> screw_length=<n> \          // a `hole` takes its size from these
    leaf_length=<n> leaf_width=<n> leaf_thickness=<n> \   // a recess takes its footprint from these
    shape=round|turned|bar|bail|custom|leaf|span color="#rrggbb" \  // optional display proxy
    diameter=<n> projection=<n> length=<n> width=<n>

A mount, and the join that places it. female= may be left off for a hardware_mount joint, and only for that kind:

joinery hardware_mount name=<Joint> {
    hardware <Name> [qty=<n>]          // required; qty is per join, for the schedule
    hole [diameter=<n>] [depth=<n>] [dx=<n> dy=<n> dz=<n>] [normal=pos_x…neg_z]
    mortise_depth <n> [mortise_length <n>] [mortise_width <n>]
    axis x|y|z                         // part-local axis the leaf's long side runs along
    distribute [from=<mm>] [to=<mm>] [count=<n>] [setback=<mm>]   // N items along the axis (ADR-0078)
}
join joint=<Joint> male=Part@Mark [female=Part@Mark]
RowDoesDefaults
holebores the male part's face at the markdiameter from screw_diameter, depth from screw_length; depth=0.0 is through
mortise_depthrecesses a leaf on every end the join namesfootprint from leaf_length by leaf_width; the long side runs along axis (the hinge axis) when the joinery names one, else along the face's longer in-face axis
neithercounts the item and cuts nothingthe behaviour of every design written before ADR-0030

distribute (ADR-0078) spreads N items along the mark's long axis instead of one at the mark: from/to are the zone the items must lie within, signed mm from the mark's point along the male face's axis (default: the whole run of the male face, so a bare distribute hangs a door along its full edge). The first and last item's near end sits setback inside the zone's ends (the catalogue item's setback=, or the row's); N is ceil(D / max_pitch) + 1 for D the centre-to-centre run (the item's max_pitch=), or the row's count=; the items are evenly spaced. One join places every item on every end it names, each recess, hole and proxy included, and the schedule counts N. A zone too short for one item and its setbacks is hardware-distribute; so is a missing setback or max_pitch (never invented). A zone that keeps hinges clear of a till divider is just a from/to pair.

Proxy shapes and the numbers each needs: round/turned need diameter, projection; bar/bail need length, diameter, projection; custom needs length, width, projection; leaf needs leaf_length, leaf_width, leaf_thickness; span needs only diameter (RFC-0145): a bar drawn from the male mark to the female mark, so a join with shape=span must name both ends (hardware-span otherwise), and its marks are apart by design (the join gap check skips it). A proxy is a display solid only: it is in no cut list, stock list, drawing or clash check, so it never clashes with the wood it is mounted on. An item with no shape= draws nothing.

Example#

project name="Cabinet door" units=mm schema_version=1 {
    materials {
        material Oak type=hardwood
        hardware Knob shape=round diameter=30.0 projection=25.0 \
            screw_diameter=4.0 screw_length=12.0 color="#b08d57" \
            supplier="Horton Brasses" part_no="K-30" price=4.0
        hardware Hinge shape=leaf leaf_length=60.0 leaf_width=18.0 leaf_thickness=2.0 price=3.5
    }
    component Door role=door {
        stock Oak 400.0 300.0 20.0
        mark PullPoint x=200.0 y=150.0 z=0.0 normal=pos_z
        mark HingeEdge x=0.0 y=150.0 z=-10.0 normal=neg_x
    }
    component Post role=post {
        stock Oak 40.0 300.0 20.0
        mark HingePost x=40.0 y=150.0 z=-10.0 normal=pos_x
    }
    joinery hardware_mount name=KnobMount { hardware Knob; hole }
    joinery hardware_mount name=HingeMount { hardware Hinge qty=2; mortise_depth 2.0 }
    assembly Root {
        part D instance=Door
        part P instance=Post { pos x=-40.0 }
        join joint=KnobMount male=D@PullPoint
        join joint=HingeMount male=D@HingeEdge female=P@HingePost
    }
}

The knob is bored ⌀4 by 12 into the door's face and drawn as a ⌀30 by 25 cylinder standing on it. The hinge is let 2 mm into the door's edge and the post's edge, and a leaf plate is drawn on each. The hardware schedule says one knob and two hinges.

Pitfalls and diagnostics#

  • A recess is a fit you size. There is no clearance allowance. recess-fit (error) means the leaf is larger than the face it is let into; shrink mortise_length/mortise_width or choose a bigger edge.
  • remaining-wall (error): a blind bore or recess as deep as the part is thick. Write depth=0.0 for a through bore.
  • hardware-size (error): a hole has no diameter or depth and the catalogue item has no screw_diameter/screw_length; or a mortise_depth has no leaf size.
  • hardware-face (error): the mark is a standard anchor, which has a point but no facing. Use a declared mark … normal=, or give the hole a normal=.
  • hardware-fit (error): a bore overruns the face. Move the mark or shrink the bore.
  • hardware-shape (warning): shape= is not one of the words above, or its numbers are missing or not positive. No proxy is drawn; the mount itself is unaffected.
  • A one-sided join on any other joint is an error (ww::expand::one_sided_join).
  • A proxy is an envelope, not a model of the product: a knob is a cylinder, a bail a box. Do not read it as a clearance check. A join that carries a travel is swept in motion, but only the wood is (ADR-0075, travel).
  • The proxy count is one per mount mark. qty= is the schedule's count only.

Reveals, orientation and ww joins#

  • Which way the leaf lies. Without axis the recess (and the drawn leaf) follows the face's longer in-face axis, which is right for a door taller than it is wide. For a wide lid, or any part hung on its long edge, write axis x|y|z: the part-local axis the hinge runs along. It must be one of the face's two in-face axes; the face normal, or an axis the face does not carry, is a recess-axis error naming the axis and the face.
  • A reveal is not a gap. An inset door stands off the carcass by its reveal and the hinge spans it. ww joins reports a leaf-hinge hardware_mount join (the item gives leaf_length and leaf_width) whose parts stand apart by no more than the hinge reaches (its catalogue knuckle_dia, else leaf_width) as bridged, counted apart from gaps; a bolt, a pull or a hinge pulled further apart than its reach is still a gap.
  • Veneer is not a gap. A veneer leaf bonded to a marked face stands proud of the host by its own thickness; ww joins takes that thickness off the measured distance, so veneering a face a part is joined to neither opens a gap nor changes the reveal.

See also#

  • docs/adr/0030-hardware-placement-profile-and-recess.md, docs/adr/0017-hardware-and-materials.md, docs/adr/0075-travel-primitive.md
  • travel: sweeping a part that moves
  • docs/rfc/0128-hardware-placement-and-profile.md, docs/rfc/0071-hardware-hinges.md
  • docs/KDL_AUTHORING.md §5 (hardware) and the joinery table
  • examples/blanket_chest.kdl, examples/six_board_chest.kdl (hinged lids), examples/welsh_dresser.kdl (counted-only hinges)
  • docs/styles/models/hardware-mount.kdl

Names#

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

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_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 }

hardware_use#

node in 5 of 116 examples (15 uses).

Shortest real use, from pennsylvania_schrank.kdl:

hardware_use DoorLock qty=1

distribute#

node in 2 of 116 examples (2 uses).

Shortest real use, from welsh_dresser.kdl:

distribute

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