# Cut-Path Outlines

*Lines, arcs, polylines, and named paths for a pierced or shaped cut*

**Names:** `cut_path` `path` `keep` `line` `arc` `polyline` `point` `kerf`

## When to use

An outline cut through (or part-way into) a part, in the plane of one face: a round or curved
tabletop, a curved felloe, a bootjack notch, a pierced window, a semicircular cut-out. A
straight cut across a whole face is a `dado`/`groove` and a profile along an edge is
`chamfer`/`roundover`/`moulding` (all in `edge-and-face-cuts`).

## Syntax

```text
cut_path depth=<expr> [face=<face>] [keep="outside"|"inside"] [tilt=<deg> heading=<deg>] [kerf=<expr>] {
    line     from_x= from_y= to_x= to_y=
    arc      center_x= center_y= radius= start_angle= end_angle=      // degrees
    polyline { point x= y=; point x= y=; ... }                         // at least 2 points
}
cut_path depth=<expr> path=<Name>            // a named single segment
path <Name> arc center_x= center_y= radius= start_angle= end_angle=   // declared in the component
```

- `depth=0.0` is through; a positive depth stops short of the far face. A depth that reaches
  the far face is refused (write `0.0`). `face=` defaults to the broad face (as for `dado`).
- **`keep="outside"` (default):** the closed region is **removed** (a pierced cut-out).
  **`keep="inside"`:** everything *outside* the region is removed, so the path becomes the
  part's new footprint through its full thickness (a round top, a felloe's curved edge).
- **Segments.** `line` never closes alone (reported as a skip if used by itself). `arc` is in
  degrees (the `sin`/`cos` convention); a 360 degree sweep is a full circle, less closes along
  the chord. `polyline` has the closing edge from last point to first **implied**: never
  repeat the first point.
- **Compound path:** several segments in one inline `cut_path { ... }` chained in document
  order, each end meeting the next start (`arc`, `line`, `arc` is an annular wedge, the
  wagon-wheel felloe). The closing edge back to the start is implied; do not write a fourth.
- **Named path:** `path <Name> <kind> props...` declares exactly **one** segment once;
  `cut_path path=<Name>` uses it. Naming a `path=` and also giving inline segments is refused.
  Only an inline `cut_path` chains several.
- `tilt=`/`heading=` lean the cut (a raked wall); `kerf=` is inert on a closed path (kept for
  toolpath compensation).
- `id=`/`label=` are accepted syntax (both parse as strings) but nothing in the compiler
  reads them back: no diagnostic, no cross-reference, no cut-list or drawing output resolves
  against them (issue #551, same gap as `dado`/`groove`, issue #549). They are for the
  author's own bookkeeping only, not yet a real reference mechanism another node can resolve
  against.

## Example

```kdl
project name="Cut Paths" units=mm schema_version=1 {
    materials { material Oak type=hardwood }
    component Panel role=panel {
        stock Oak 200.0 150.0 20.0
        // a pierced rectangular window (closing edge implied)
        cut_path depth=0.0 {
            polyline {
                point x=60.0 y=50.0
                point x=140.0 y=50.0
                point x=140.0 y=100.0
                point x=60.0 y=100.0
            }
        }
        // a semicircular notch, named once and referenced
        path Notch arc center_x=100.0 center_y=0.0 radius=30.0 start_angle=0.0 end_angle=180.0
        cut_path depth=0.0 path=Notch
    }
    component Felloe role=felloe {
        stock Oak 200.0 150.0 20.0
        // a compound annular wedge: arc, line, arc, chained end to start
        cut_path depth=0.0 keep="inside" {
            arc center_x=100.0 center_y=75.0 radius=60.0 start_angle=0.0 end_angle=90.0
            line from_x=100.0 from_y=135.0 to_x=100.0 to_y=115.0
            arc center_x=100.0 center_y=75.0 radius=40.0 start_angle=90.0 end_angle=0.0
        }
    }
    assembly Root {
        part P instance=Panel { by top_sw; pos x=0.0 y=0.0 z=0.0 }
        part F instance=Felloe { by top_sw; pos x=300.0 y=0.0 z=0.0 }
    }
}
```

## Pitfalls and diagnostics

- **`spline` and `circle` segments are built** (ADR-0032): see `paths-and-splines.md`.
- Anything the build cannot read (an unknown `keep=` word, a missing `path=` target, a path
  with no geometry, a degenerate or self-meeting outline) is a **skip** in the scene JSON
  `"skipped"` list and a `ww check` warning, not a build error. Read the skip text.
- `keep="inside"` on the wrong side of the stock leaves nothing: size the blank over-length
  and let the path trim it.
- Coordinates are part-local in the face's own plane (`from_x`, `center_x` ...), not the
  part's `x`/`y`/`z`.

## See also

- `docs/KDL_AUTHORING.md` §7 (`cut_path`); `docs/adr/0016-path-geometry.md`;
  `docs/rfc/0120-curved-path-geometry.md` (levels 1 to 2 and compound).
- `examples/wagon_wheel.kdl` (compound felloe), `examples/three_legged_stool.kdl`,
  `examples/bed.kdl`, `examples/six_board_chest.kdl`, `examples/loom_shuttle.kdl`.
- `edge-and-face-cuts.md`, `round-stock-sections.md` (turned outlines).

## Names

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

### `cut_path`

feature; node in 50 of 116 examples (239 uses).

Shortest real use, from `ming_waisted_corner_leg_table.kdl`:

```kdl
cut_path depth=0.0 face=neg_y path=Hoof
```

### `path`

feature, word-valued property; node in 9 of 116 examples (15 uses); property in 9 of 116 examples (19 uses).

Shortest real use, from `jacobean_joint_stool.kdl`:

```kdl
path ArchLong {
    line from_x="span_w * 0.10" from_y=-5.0 to_x="span_w * 0.10" to_y=0.0
    spline {
        point x="span_w * 0.10" y=0.0
        point x="span_w * 0.30" y="arch_rise * 0.80"
        point x="span_w * 0.50" y=arch_rise
        point x="span_w * 0.70" y="arch_rise * 0.80"
        point x="span_w * 0.90" y=0.0
    }
    line from_x="span_w * 0.90" from_y=0.0 to_x="span_w * 0.90" to_y=-5.0
}
```

### `keep`

word-valued property; property in 27 of 116 examples (61 uses).

Shortest real use, from `postmodern_flat_silhouette_chair.kdl`:

```kdl
cut_path depth=0.0 keep="inside" path=RearOutline
```

### `line`

node in 33 of 116 examples (256 uses).

Shortest real use, from `postmodern_flat_silhouette_chair.kdl`:

```kdl
line from_x=w from_y=0.0 to_x=w to_y=seat_h
```

### `arc`

node in 19 of 116 examples (65 uses).

Shortest real use, from `windsor_fan_back_side_chair.kdl`:

```kdl
arc center_x=rf center_y=cy radius=rf start_angle=0.0 end_angle=180.0
```

### `polyline`

node in 21 of 116 examples (91 uses).

Shortest real use, from `incised_walnut_washstand.kdl`:

```kdl
polyline { point x="9.0 + (0.0000)" y="9.0 + (1.0000)"; point x="face_w - 9.0 + (0.0000)" y="9.0 + (1.0000)"; point x="face_w - 9.0 - (0.0000)" y="9.0 - (1.0000)"; point x="9.0 - (0.0000)" y="9.0 - (1.0000)" }
```

### `point`

node in 40 of 116 examples (1487 uses).

Shortest real use, from `country_rush_seat_ladder_chair.kdl`:

```kdl
point x=crx y=d
```

### `kerf`

property; property in 6 of 116 examples (8 uses).

Shortest real use, from `wedged_post_and_rung_stool.kdl`:

```kdl
wedge kerf=3.0 depth=18.0 flare=2.0 flare_depth=10.0
```

## Related terms

- [Bootjack](/almanac/techniques#bootjack)
- [Cut path](/almanac/techniques#cut-path)
