# Grain Axis

*Pinning a part's grain direction to a named axis*

**Names:** `stock` `along_x` `along_y` `along_z`

## When to use

Use `along_x`, `along_y` or `along_z` on a rectangular `stock` line when you know which way
the grain runs and the board's proportions can change. `lengthwise` and `crosswise` are
re-derived from the board's *current* dimensions at every parameter value, so a parametric
panel whose depth and height can cross over silently turns its grain 90 degrees, and every
`dado` and `groove` on it turns with it. A drawer side or a chest end is the usual case: the
grain runs front to back (or along the end's length) whether the part is wider than tall or
not. Pin it and the grain stays put.

Leave `lengthwise` (the default) on members and fixed-proportion parts. Sheet goods
(`type=sheet`) have no grain; naming one is still an error.

## Syntax

`stock <Material> x y z [grain]`, where `grain` is one of:

| Word | Meaning |
| --- | --- |
| `lengthwise` (default) | Along the unique longest dimension |
| `crosswise` | Across the shorter of the broad face's two axes |
| `along_x` | Along the part-local x axis, at every parameter value |
| `along_y` | Along the part-local y axis |
| `along_z` | Along the part-local z axis (the thickness axis, when the board is flat in z) |

The axes are the part's own D4 frame, before placement; a rotation or mirror in `pos`
does not change which local axis is pinned. It is a bare word in the fifth positional slot,
not a CEL expression and not a named property (`grain=y` is rejected, ADR-0007 rule 4).

Effects of a pinned axis:

- ADR-0011 rule 2 reads it directly: a `groove` runs along it and a `dado` across it. A
  cut into a face whose normal is the pinned axis is end grain and is skipped, with that
  reason shown.
- The cut list and part cards put the pinned axis first: its length is L (runs with the
  grain), even when another dimension is larger. The grain line reads `along_y`.
- There is no tie error: a board with two equal long dimensions is fine once pinned.

## Example

```kdl
// A drawer side 278 mm deep and 312 mm tall: taller than it is deep, so the default
// `lengthwise` would run the grain up the side and turn the bottom groove vertical.
// Pinned along_y, the grain and the groove run front to back at every setting.
project name="Pinned Grain Side" units=mm schema_version=1 {
    params {
        side_d 278.0 min=200.0 max=400.0 step=1.0 label="Side Depth"  category="Envelope"
        side_h 312.0 min=100.0 max=400.0 step=1.0 label="Side Height" category="Envelope"
    }

    materials {
        material WhiteOak type=hardwood
    }

    assembly Root {
        part Side material=WhiteOak role=drawer_side {
            stock WhiteOak 15.0 side_d side_h along_y
            groove width=6.0 depth=6.0 offset=10.0
            by top_sw
            pos x=0.0 y=0.0 z=0.0
        }
    }
}
```

## Pitfalls and diagnostics

- **It is one axis for the whole board, not grain per face.** A quadrilinear post (four
  mitred quartersawn boards round a core) still cannot say that each face shows the same
  figure; `docs/styles/models/quadrilinear-leg.kdl` stays approximate for that reason
  (per-face grain is not in the language; RFC-0113, grain on turned stock, is still open).
- **Pinning the thickness axis makes the broad faces end grain** (a butcher-block end):
  every `dado`/`groove` on those faces is skipped as end grain, by design.
- **Do not pin out of habit.** A leg or rail that never changes proportion gains nothing;
  the default already reads its longest dimension. Pin parametric panels whose
  depth and height ranges overlap.
- **Round stock** (`stock <Mat> shape=round ...`) takes no grain word at all: its grain is
  derived, along the turned axis. The pinned words are for rectangular stock.
- `ww-expand` rejects any other word: ``grain is `lengthwise`, `crosswise`, `along_x`,
  `along_y` or `along_z` ``. A grain word of any kind on a `type=sheet` material is the
  error "`<Mat>` is a sheet material and has no grain".

## See also

- `docs/rfc/0072-grain-pinned-to-an-axis.md`, `docs/adr/0028-grain-pinned-to-an-axis.md`
- `docs/adr/0011-dado-and-groove-placement.md` (rule 2), `docs/adr/0007-stock-line.md`
- `docs/KDL_AUTHORING.md` section 10, house rule 4
- `examples/bedside_cabinet.kdl`, `examples/blanket_chest.kdl`, `examples/six_board_chest.kdl`,
  `examples/biedermeier_box.kdl`

## Names

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

### `stock`

feature; node in 114 of 116 examples (910 uses).

Shortest real use, from `glazed_vitrine_whiplash_crest.kdl`:

```kdl
stock Glass dw 6.0 dh
```

### `along_x`

grain; value in 35 of 116 examples (133 uses).

Shortest real use, from `kumiko_andon_lantern.kdl`:

```kdl
stock Hinoki wo pan_th prh along_x
```

### `along_y`

grain; value in 25 of 116 examples (34 uses).

Shortest real use, from `shaker_tall_chest_of_drawers.kdl`:

```kdl
stock Poplar box_th box_d h along_y
```

### `along_z`

grain; value in 27 of 116 examples (44 uses).

Shortest real use, from `kumiko_andon_lantern.kdl`:

```kdl
stock Hinoki sw pan_th ph along_z
```

