cut_out
Cut a hole in a floor area shape for columns, drains, or casework. Uses boolean subtraction to handle overlapping cuts without double-deducting and adds perimeter.
Instructions
Cut a REAL hole in a committed floor_area shape (#206) — the way the canvas cuts one (#137): the same lib/cutout.js boolean subtract, so the two surfaces can never disagree about what a hole holds. The parent keeps its outer ring plus the reconciled hole(s) (verts_norm_holes), its computed nets for real — N cuts compose, overlap between cuts never double-deducts (set subtraction), a hole ADDS perimeter — and the deduct commits carrying cuts_shape_id so the report and legend read the reconciled number, never a second arithmetic pass. This is the verb for a column, a floor drain, an island of casework INSIDE a room; an independent measure_polygon role:"deduct" stays the tool for a deduction that isn't a hole in one parent. Refusal over guessing: the ring must sit FULLY inside the parent's outer ring (an edge-crossing cut is a boundary correction — edit_shape the parent instead), and a cut that would erase the parent or split it in two refuses whole (trace the pieces as rooms). One journal entry — undo_last restores parent and hole together; delete_shape on the deduct later reverts the cut too (a multi-cut parent rebuilds from the chain's pristine snapshot minus the survivors). Coordinates are image px at render scale 2.0: PDF pt × 2, origin top-left, y down (the browser canvas's native space). Sheet payloads carry dims in both px and pt.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| verts | Yes | The hole's ring, image px, fully inside the parent | |
| parent_shape_id | Yes | A committed floor_area shape id (list_shapes) |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| note | Yes | ||
| holes | Yes | Holes the parent now carries | |
| hole_sf | Yes | What this cut actually removed from the parent's net — 0 when the ring fell entirely inside an existing hole | |
| parent_net | Yes | ||
| deduct_shape_id | Yes | The reconciled deduct — carries cuts_shape_id; totals skip it (the parent nets the hole) | |
| parent_shape_id | Yes |