Neuer Befehl multiline.ts, baut auf derselben Offset-Geometrie auf wie der
bestehende offset-Befehl (offsetSegment) — erzeugt aber alle Kopien auf
einmal statt einzeln nacheinander offsetten zu müssen. Deckt gerade
Basislinien ab (häufigster Fall: Grenzlinie+Abstand, Leitungspaar,
Randlinien), keine mehrsegmentige Variante.
Ablauf: Start-/Endpunkt (Tab-Felder Länge/Winkel wie line.ts), dann Abstand
per Maus-Klick (Seite bestimmt Vorzeichen, wie bei offset.ts) oder getippt;
die Anzahl (Default 3, Bereich 2-6) zyklt über eine Inline-Option und bleibt
wie Abstand/Seite über Aufrufe hinweg persistent.
In Registry/Aliase (ml/parallel), ToolsPanel (COMMANDS_EDIT neben Offset),
CommandIcon, i18n de/en aufgenommen.
2 neue Tests. tsc -b / vitest run (916/916) / npm run build grün.
Anders als Fillet/Extend existierte hierfür noch gar keine Geometrie —
chamferCorner (src/geometry/kernel2d.ts) ist neu: gleicher Abstand vom Eck
auf beiden Schenkeln, gerade verbunden (klassischer Gleichabstands-Chamfer,
analog zu filletCorner, nur ohne Bogen — daher exakt statt tesselliert).
commands/cmds/chamfer.ts wortwörtlich nach dem fillet.ts-Muster: Ecke wählen,
Distanz per Maus oder getippt (Tab-Feld). In Registry/Aliase
(ch/fasen), ToolsPanel (COMMANDS_EDIT neben Fillet), CommandIcon, i18n
de/en aufgenommen.
3 neue Tests (Fasung, Fehltreffer, Distanz-zu-gross-No-op). tsc -b /
vitest run (914/914) / npm run build grün.
filletCorner (Eckpunkt-Verrundung) und extendSegment (Gegenstück zu Trim)
existierten fertig implementiert und getestet im Kernel (kernel2d.ts), hatten
aber keinen einzigen Aufrufer — kein Command, kein Werkzeug-Knopf, für den
Nutzer nicht erreichbar. Reine Verdrahtungsarbeit, kein neues Geometrie-
Problem:
- fillet.ts: Ecke einer polyline/rect wählen (nächstgelegener Eckpunkt mit
zwei Nachbarn), Radius per Maus oder getippt (Tab-Feld wie bei circle.ts).
Da Polylinien im Modell keine Bogen-Segmente kennen (kein "Bulge" —
bekannte, separate Lücke), wird die Verrundung als kurze Punktfolge
tessselliert statt als echtes Arc-Objekt gespeichert; ein rect wird beim
ersten Fillet zu einer polyline. Ehrlich im Kopfkommentar dokumentiert.
- extend.ts: offene Kurve (line/offene polyline) nahe einem Ende anklicken,
dieses Ende wird bis zur nächsten anderen Kurve verlängert (implizite
Cutter wie bei Trim). Kein Treffer → No-op, Befehl bleibt aktiv.
Beide in COMMANDS/ALIASES registriert (fi/verrunden, ext/verlaengern),
i18n de/en ergänzt, in ToolsPanel COMMANDS_EDIT neben Trim/Join aufgenommen,
eigene Icons in CommandIcon.tsx (bisher: unbekannter Name → kein Icon).
Rotate NICHT angefasst: der ursprüngliche Befund „Rotate ist keine getippte
Kommandozeilen-Aktion, nur ein UI-Button" war unvollständig — App.tsx routet
sowohl den Ribbon-Button als auch das getippte Wort „rotate"/„drehen" ganz
bewusst an startTransformOp() (den reicheren U/I/O/P-Move/Copy/Array/
Verteilen-Fluss), nicht an die generische Befehls-Engine (Kommentar dort
erklärt das explizit). Ein zuerst geschriebener, einfacher rotateCommand
(nur „move"-Modus) wäre über diese Sonderfälle nie erreicht worden UND hätte
über neue Aliase wie „ro" einen inkonsistenten Zweit-Pfad geöffnet (voller
Funktionsumfang bei „rotate", abgespeckter bei „ro") — verworfen, bevor
committet.
6 neue Tests (fillet: Verrundung + Fehltreffer; extend: Verlängerung +
Kein-Cutter-No-op). tsc -b / vitest run (911/911) / npm run build grün.
Zwei Klicks (Ecke → Gegenecke, Live-Vorschau + Mass-HUD); die Aussparung wird
der Decke des aktiven Geschosses hinzugefügt, die das Rechteck vollständig
enthält (alle 4 Ecken im Umriss), sonst No-op. Aliase 'deckenloch'/
'aussparung', BIM-Ribbon-Eintrag mit eigenem Icon. Komplettiert die Decken-
Aussparungen (b290120) um den Zeichenweg. 684/684 grün.