| … | … | @@ -710,3 +710,120 @@ G grid, R radial, C curve, B chamfer, D dice. The modal hint lists them. |
| 710 | 710 | determinism, undo). One dc-terrain release. |
| 711 | 711 | 3. Dice: `gate_mod_dice` (cell count, convexity, a cut after a dice). |
| 712 | 712 | 4. Keys: keymap_gate (no collisions), plus a check in the Stack panel gate. |
| 713 | |
| 714 | ## 13. L2 — the BoxCutter tool and the Q menu (DESIGN, 2026-10-18) |
| 715 | |
| 716 | Scope, user 2026-10-18: all four parts are kept: drawing cutters, cut modes while |
| 717 | drawing, modifiers while drawing, and stack / cutter housekeeping. Survey of what exists: |
| 718 | #120 comment of the same date. |
| 719 | |
| 720 | ### 13.1 The cutter is a `prism` shape |
| 721 | |
| 722 | - A new generator `prism` (`shapes/param/param_prism.gd`, gv 1). |
| 723 | - Params: |
| 724 | - `poly`: 2D points in the frame's xz; |
| 725 | - `depth`; |
| 726 | - `taper`: the top polygon's scale, 1 = straight; |
| 727 | - `shear`: [x, z], the top polygon's offset (a wedge). |
| 728 | - It emits ONE convex piece: `FaceKit.hull_sections(bottom, top)`. Taper and shear keep it |
| 729 | convex because a hull of two convex polygons is convex. **This is why taper/wedge are |
| 730 | prism params, not modifiers:** tapering an arbitrary piece is not a rigid transform, and |
| 731 | that is all ModFold may apply. |
| 732 | - Circle and ngon are `poly` generated from `{sides, radius}`. They are stored as points, |
| 733 | so editing one later is a polygon edit. |
| 734 | - A custom polygon is the CONVEX HULL of the placed points (cutters must be convex). The |
| 735 | status line says so when it drops a point. |
| 736 | - It stays an ordinary shape: G moves it, the Stack panel edits it, and a live op re-cuts. |
| 737 | |
| 738 | ### 13.2 The tool (`box_cutter_operator.gd`, on F3 ModalControls) |
| 739 | |
| 740 | The mouse is the camera in every builder tool, so "drawing" means aiming, as in the create |
| 741 | and curve tools. Phases: |
| 742 | |
| 743 | 1. **Footprint.** |
| 744 | - Tab cycles rect / circle / ngon / polygon. |
| 745 | - S cycles the surface: |
| 746 | - the aimed face (default); |
| 747 | - the view plane through the 3D cursor; |
| 748 | - the cursor's own plane; |
| 749 | - the world grid at the cursor's height. |
| 750 | - LMB / P sets the first corner (or the centre); the aim drags the other, snapped to |
| 751 | the grid on that plane. |
| 752 | - For polygon, P adds points and Backspace removes one. |
| 753 | - [ ] steps ngon sides, or circle segments. |
| 754 | 2. **Depth.** |
| 755 | - The default is THROUGH (§13.3). |
| 756 | - [ ] steps it in grid units; 0 = back to through. |
| 757 | 3. **Offset** (optional): [ ] slides the footprint along the normal (cut-in from above the |
| 758 | surface). Enter commits from any phase. |
| 759 | |
| 760 | **Commit = ONE gesture:** |
| 761 | - `shape.create {type: prism}` for the cutter; |
| 762 | - `op.create {op: mode, cutter, targets}`; |
| 763 | - one `mod.create` per modifier queued while drawing; |
| 764 | - linking the cutter into the Cutters collection (§13.5). |
| 765 | |
| 766 | One Ctrl+Z undoes all of it. |
| 767 | |
| 768 | Key: Shift+B opens the tool (Blender's BoxCutter is a tool, not a menu). keymap_gate |
| 769 | checks for collisions. |
| 770 | |
| 771 | ### 13.3 Through-depth |
| 772 | |
| 773 | - At commit, depth = the farthest extent of the targets' pieces below the footprint plane |
| 774 | (corners projected on −n), plus one grid step. |
| 775 | - It is stored as a number, NOT re-measured live: re-measuring would make the fold depend on |
| 776 | other shapes' state in a new way. |
| 777 | - The Stack panel shows "through (2.4 m)". Shift+R re-measures for a repeat. |
| 778 | |
| 779 | ### 13.4 Modes and modifiers while drawing |
| 780 | |
| 781 | - **X cycles the mode:** subtract → slice → intersect → inset → outset. In inset/outset, |
| 782 | [ ] edits that mode's depth when focused (Tab). |
| 783 | - **Extract** is a Q-menu row on a cut op, not part of the draw: |
| 784 | - each intersect piece (target ∩ cutter) becomes a new `hull` shape; |
| 785 | - those shapes go into a new collection "Extract"; |
| 786 | - they are ordinary shapes, ready to be used as cutters. |
| 787 | - **Modifier keys while drawing** queue `mod.create` records on the cutter: |
| 788 | - B chamfer; |
| 789 | - V array (Shift+V radial about the cursor); |
| 790 | - 1 / 2 / 3 mirror X / Y / Z; |
| 791 | - G grid. |
| 792 | |
| 793 | The queue shows on the status line; pressing the same key again removes it. ModFold |
| 794 | already copies a cutter's pieces with `cutter: true`, so a mirrored cutter cuts |
| 795 | mirrored holes. |
| 796 | - **T** steps taper and **Shift+T** steps shear (the wedge): prism params, §13.1. |
| 797 | |
| 798 | ### 13.5 Housekeeping |
| 799 | |
| 800 | - **Targets = the whole selection.** `_live_cut` takes every selected object's group (not |
| 801 | only the active one), excluding cutters. `op.create.targets` already takes many. |
| 802 | - **Cutters collection.** |
| 803 | - The first commit creates a room collection named "Cutters" (`col.create`, replicated |
| 804 | like any collection) and links every new cutter into it. |
| 805 | - Its outliner rows start hidden. That is view state, kept per player. |
| 806 | - The Shift+Alt+C overlay still shows the wires. |
| 807 | - **Q menu on a shape with cuts:** |
| 808 | - **Change cut ▸** subtract / slice / intersect / inset / outset (`set_op`); |
| 809 | - **Apply up to here ▸** <op>: `make_real` takes an op: it bakes the target as folded |
| 810 | with only the ops up to and including that one live, and retires those ops with |
| 811 | `op.apply`. The later ops stay live, and they cut the baked pieces, which keep the |
| 812 | target's group. |
| 813 | - **Stack scroll** (Ctrl+Alt+[ / ]): a LOCAL preview that turns off the ops after row k |
| 814 | for this player only. It is never journaled, and it clears when the tool or the |
| 815 | selection changes. It is HardOps' modifier_scroll, as a view. |
| 816 | - **Repeat** (Shift+R) after a BoxCutter commit re-enters the tool with the last |
| 817 | footprint, mode and queued modifiers. |
| 818 | |
| 819 | ### 13.6 Order and gates (each red first) |
| 820 | |
| 821 | 1. `prism` generator + taper/shear: `gate_param_prism` (one convex piece, hull exact, taper 0.5, |
| 822 | shear, circle/ngon poly). |
| 823 | 2. Through-depth function: `gate_cut_through` (slab, stepped target, two targets). |
| 824 | 3. The tool, rect on a face, mode X, commit as one gesture: `gate_box_cutter`. |
| 825 | 4. Footprints circle / ngon / polygon and surfaces view / cursor / grid: `gate_box_cutter` B-checks. |
| 826 | 5. Modifier keys while drawing, plus T / Shift+T: `gate_box_cutter` M-checks. |
| 827 | 6. Whole-selection targets, the Cutters collection, repeat: `gate_box_cutter` H-checks. |
| 828 | 7. Q menu Change cut, Extract, Apply up to here: `gate_q_stack`. |
| 829 | 8. Stack scroll preview: `gate_q_stack` S-checks. |