diff --git a/CLAUDE.md b/CLAUDE.md index 52ca296..756661c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -108,7 +108,7 @@ Detaillierte Dokumentation aller Funktionen und Befehle: siehe `Lisp/README.md`. | `ssg_texttools.lsp` | SSG_TEXT_ERSETZEN, SSG_TEXT_PARALLEL, SSG_TEXT_HOEHE, SSG_TEXT_STIL | Text-Werkzeuge (Ursprung ACADSST `CHGTEXT`/`PARTEXT`/`ALTHOEHE`/`ALTSTIL`): Suchen/Ersetzen in TEXT, MTEXT und Block-Attributen (nutzt `ssg-bt-*`, daher NACH `ssg_blocktools` laden), Text parallel zu Linie/Polylinie/Bogen (lesbar ausgerichtet, Abstand), Hoehe/Stil aendern. Arbeitet in der XY-Ebene des Welt-KS. Reine Kerne `ssg-tt-lesbarer-winkel`, `ssg-tt-versetzt` getestet | | `ssg_stueckliste.lsp` | SSG_FAEHNCHEN_STUECKLISTE | Positions-Faehnchen + Stuecklistentabelle, komplett AUS DER ZEICHNUNG - es wird keine Datei eingelesen. Der Benutzer waehlt die Elemente aus (`ssg-sl-erkannte-elemente`: `ssget`-Auswahl, Enter ohne Auswahl = alle erkannten im aktuellen Layout; der reine Filter `ssg-sl-elemente-aus-ss` laesst nicht erkannte Objekte still wegfallen, man darf also grosszuegig ein Fenster aufziehen). `ssg-sl-klasse` klassifiziert Blocknamen (`KREISEL_*`/`ECKRAD_*` -> "ILS Kreisel/Eckrad", `VF_*`/`GF_*` -> "ILS Streckengruppe", `GR_*` -> "Rohrgeruest", `AP60*`/`AP110*`/`AP_110*`/`APG110*` -> je eigene Omniflo-Geraden-Gruppe; wirksamer Blockname ueber `ssg-bt-effname`, also auch dynamische Bloecke). Jedes einzelne Element bekommt ein Faehnchen (`ssg-sl-faehnchen`, Rechteck/Kreis/Automation-Rahmen + Text) an der unteren linken Ecke seiner Bounding-Box (aus `csv:get-bbox` - liefert Zentrum+Abmessungen, NICHT Eckpunkte, die Ecke wird im Code daraus berechnet); die Tabelle (`ssg-sl-tabelle-zeichnen`) gruppiert GROB je Elementklasse (keine Sivas-Artikelaufloesung wie `export_sivas.py`) zu einer Zeile mit Anzahl + Laengensumme aus dem `LAENGE`-Attribut (`ssg-sl-gruppieren`/reiner Kern `ssg-sl-gruppieren-werte`), mehrere gleichartige Elemente tragen daher dieselbe Positionsnummer. **Bewusst KEIN Datei-Import wie bei Walz/Bihler**: dort vergab ein externes System die Positionsnummern und lieferte sie als Datei zurueck, die das CAD nur abzeichnete - bei Walz (`MENU/POSITION.LSP`) eine `.pos`/`.zei` aus einem Clipper-Warenwirtschaftssystem mit Koordinaten-Zuordnung, bei Bihler ITB (`Walz_und_Bihler/SBCADBib/ITB-Module_ori.lsp`, `c:bea_pos`) eine `.pos` mit Zuordnung ueber den Entity-Handle. Diese Umwege sind hier nicht nachgebaut (Entscheidung 2026-10): Nummern und Mengen entstehen in dieser Funktion, die Stuecklisten-AUSGABE liefern EXPORTSIVAS/EXPORTCSV aus denselben Block-Attributen. Der alte `c:stueckl` (Laengen-Summierung ueber hartcodierte Walz-Profillayer wie `L-2`=ST, `A-7`=AP110) hat ebenfalls kein Aequivalent im dxfmakros-Datenmodell (Block-Attribute statt Linien-Layer). Braucht `csv:get-bbox`/`csv:get-attrib` aus `export.lsp` und `ssg-bt-effname` aus `ssg_blocktools.lsp` - muss daher NACH beiden geladen werden (siehe `ssg-ensure`-Reihenfolge in `SSG_LIB.mnl`/`ssg_load.lsp`). Reine Kerne `ssg-sl-klasse`, `ssg-sl-gruppieren-werte` in `tests/test_unit.lsp` getestet | | `KreiselInsert.lsp` | KreiselInsert, KreiselConnect, KreiselRedraw, KreiselQuick, KreiselEdit, KreiselParams, KreiselLabelSetup, KreiselLabelPos, KreiselLabelHoehe, ILS_Eckrad, EckradEdit, KREISEL_WEICHEN | ILS Kreisel und Eckrad komplett in AutoLISP. **Drehrichtungspfeil**: `draw-module` fuegt `data/ils/Drehrichtungspfeil.dwg` auf AN8-Mitte (Block-KS 90 Grad, da die DWG fuer Kreisel Nord->Sued gezeichnet ist; cfg `kreisel.pfeil_winkel`) und SP8-Mitte (+180) mit in den KREISEL_n-Block ein, GUZ = X-Skalierung -1 (reiner Kern `kreisel-pfeil-params`, getestet); Eckrad: ein Pfeil auf der Radmitte mit dem AN8-Winkel (`eckrad-pfeil-params`); bei wiederverwendeter Blockdefinition (KREISEL_n bzw. ECKRAD_n) zieht `kreisel-pfeil-aktualisieren` die Spiegelung per `entmod` nach. **Beruehrpunkte/Weichen** (`kreisel-bp-*`, Befehl KREISEL_WEICHEN, Menue Kreisel-Module -> Weichenpunkte ermitteln): ermittelt aus den Blockparametern (Einfuegepunkt, Drehung, ABSTAND - nicht aus der Geometrie, Modell wie `draw-module`) die Beruehrpunkte aller `KREISEL_*`/`ECKRAD_*` GLEICHER Hoehe (`toleranz_hoehe`): Rad/Rad (`Kreis/Kreis`) und Rad/Laufprofil (`Kreis/Tangente`), nur auf der freien Radseite (aeusserer Halbkreis inkl. Flanken; Eckrad ganz frei), Toleranz `toleranz_beruehrung` (component_defaults.json, Sektion kreisel). Kapsel-Mindestabstand < 2r - tol = KOLLISION (Ueberschneidung), Kreisel Seite an Seite (Beruehrung nur an Flanke/Profil) = KOLLISION `Tangente/Tangente` - beide werden gemeldet, aber nie zur Weiche. Ausgabe: Konsolenliste + Kreis-Marker (Layer `kreisel_weiche`/`kreisel_kollision` aus layer.cfg, XDATA `SSG_KR_WEICHE`, jeder Lauf ersetzt die alten). Der Export schreibt dieselben Punkte als `kreisel_weichen.json` neben `export_raw.json` (`csv:kreisel-weichen-schreiben`, export.lsp); `export_csv.py` uebernimmt sie (`export_neighbors.load_lisp_kreisel_weichen`/`lisp_touch_switches`, Rueckfall auf `compute_kreisel_touch_switches` nur ohne Datei), `export_sivas.py` setzt daraus Merkmal 4403 "Anzahl Weichen ILS". Reine Kerne `kreisel-bp-element`/`-paar`/`-berechnen` in `tests/test_unit.lsp` (`tu-tests-kreisel-bp`, u.a. mit den 11 Einfuegungen aus `tests/testdata/schnittspunkte_kreisel.dxf` -> 10 Beruehrungen) getestet. Eckrad: eigener Dialog `eckrad_edit.dcl` (`eckrad-dialog`, reiner Kern `eckrad-dialog-werte` getestet) beim Einfuegen (ILS_Eckrad, ohne GUI Konsolen-Rueckfall) und per Doppelklick (EckradEdit); kein Abstand/Typ, Drehung als freier Winkel statt fester Kreisel-Ausrichtung. `ils-eckrad-insert` behaelt eine vorhandene NUMMER (Edit -> gleicher Blockname `ECKRAD_n`). Kreiselname: `draw-module` setzt `Bezeichnung` nur noch bei leerem Wert auf die Vorgabe `KreiselN` (eigener Name aus KreiselEdit bleibt erhalten); Beschriftung `kreisel-label-text` = `KREISEL n: _` (ohne Namen bzw. bei Vorgabename wie bisher `KREISEL n: _`); da die Beschriftung als TEXT in der wiederverwendeten Blockdefinition `KREISEL_n_TYP_ABSTAND` steckt, setzt `kreisel-label-aktualisieren` sie dort per `entmod` neu (wirkt auf alle Referenzen der Definition) | -| `VarioFoerderer.lsp` (Wrapper fuer `vf_core.lsp`/`vf_standard.lsp`/`vf_etage.lsp`/`vf_linienzug.lsp`) | FOERDERANLAGE, VARIOFOERDERER_EDIT, VARIOFOERDERER_NACHRUESTEN, Vario_Kette_Merge, VF_SEKTION_RESTORE, VF_WIZARD_AN, VF_WIZARD_AUS | Vario-Foerderanlagen Generator (Typen Standard/Etage/Linienzug); Standard- UND Etage-Typ: Werteingabe per DCL-Dialog, inkl. der vorgelagerten Eingabemodus-Wahl 3D-Linie/Werte manuell (`vfc_eingabemodus`, `vfc-dialog-eingabemodus-waehlen`) - beide Modi laufen seitdem in denselben Basis-/Winkel-Dialog, der Konsolen-Pfad ist nur noch Rueckfall bei abgeschalteter GUI/anderer Sprache. Der Dialog-Ablauf ist zentral in vf_core (`vf-dialog-ablauf`/`vf-dialog-berechnen-einfuegen`, parametrisiert ueber Typ-Registry `*vf-typ-registry*` + Flag `horizontal-p`); `vfs-standard-dialog-ablauf`/`vfe-etage-dialog-ablauf` sind nur noch duenne Wrapper darauf. Beide nutzen dieselben Dialoge `vfs-dialog-eingabe-basis`/`vfs-dialog-winkel-verteilung` und den gemeinsamen L_GF/L_VF-Solve `vf-winkel-solve` (vf_core; berechne-alle-winkel/berechne-winkel-etage teilen ihn); Doppelklick auf VF_n-Block ruft VARIOFOERDERER_EDIT, das per SSG_VF_EDIT-XDATA-Marker ("standard"/"etage"/"linienzug") in den passenden Neuaufbau-Zweig dispatcht (`vfe-edit-ent` fuer Etage, `vfl-edit-ent` fuer Linienzug); Altbestand-Bloecke ohne Marker werden abgewiesen. Linienzug (Modus 1, `vf-linienzug-modus`) zeichnet jede interaktive Eingabe in einem Journal auf (`vfl-in-point`/`-string`/`-real`/`-int`) und schreibt es als XDATA auf den fertigen `VF_n`-Block; ein Abbruch (ESC) loescht dadurch nichts mehr, sondern wickelt die bis dahin gebaute Teil-Geometrie ebenso zu einem Block (`vfl-modus-abbruch-sichern`) - sie bleibt stehen und ist sofort per Doppelklick weiter editierbar/fortsetzbar. Der komplette Linienzug-Hauptstrang (Menue-Fragen von AS-Element bis Kettenende, inkl. GF-Bogen/Vario-Kurve/VF-Einheit-Fortsetzung) laeuft per Default ueber DCL-Dialoge statt Konsole (`*vfl-wizard-mode*`, Befehle VF_WIZARD_AN/VF_WIZARD_AUS): `vfl-in-string`/`-int`/`-real` zeigen bei aktivem Wizard-Modus generische Dialoge aus `dcl/vf_linienzug_wizard.dcl` (Zahl-Eingabe bzw. Mehrfachauswahl aus `vfl-menu`/`vfl-menu-int`) statt `getstring`/`getint`/`getreal` aufzurufen; die ORIGINALEN Konsolen-Fragen (princ + get*, de/en ueber ssg-text) bleiben unveraendert im Code (Fallback bei Fehlern via `vl-catch-all-apply`, siehe `doc/variofoerderer.md`). `vfl-edit-ent` liest das Journal, zeigt die Sektionen ueber einen DCL-Dialog (`vfl-dlg-position`, `dcl/vfl_edit.dcl`) an, kuerzt bei Bedarf auf eine gewaehlte Sektion (stummer Replay der behaltenen Eingaben, umgeht den Wizard-Zweig komplett) und baut danach interaktiv weiter. Linienzug Modus 2 (Pfad+Zielhoehe-Solver, `vf-linienzug-modus2`) nutzt dieselben Wrapper PLUS die neue Objektauswahl-Wrapper-Funktion `vfl-in-selection` (Pfad-Objekte als stabile Entity-Handles journalisiert, neue Journal-Art `"OBJS"`) und schreibt sein Journal unter dem eigenen XDATA-Marker `"linienzug2"`; Doppelklick baut hier NICHT abschnittsweise, sondern per vollem Reset 1:1 aus dem Journal neu auf (`vfl-edit-ent2`, dispatcht aus `vfl-edit-ent` per Marker) - Modus 3 (Vorwaerts-Nachbau) baut dieselbe Pfad-Geometrie VORWAERTS mit vorgegebenen Winkeln durch: die Endhoehe ist dort ein Ergebnis, kein Ziel (Anfangs- statt Randwertproblem) - genau das ist sein eigener Anwendungsfall, und er schreibt ein eigenes Journal (Marker `"linienzug3"`), ist also ebenso per Doppelklick editierbar. Seit 2026-10-22 fragt er wie Modus 2 "AS bauen?"/"ES bauen?" (je mit Winkel+Seite in EINEM Dialog, `vflw-gruppe-as-impl`), und die **ES-Frage steht VOR dem Bau** - erst damit traegt die Trimmung der letzten Geraden (`- Separator - ein-dx`) den echten ES-Fussabdruck statt eines Schaetzwerts bzw. des Werts der vorherigen Kette. Aeltere `"linienzug3"`-Journale erkennt `alt-journal` am WERT des ersten Antwort-Eintrags (`"30"`/`"90"` = alt vs. `"1"`/`"2"` = neu, disjunkte Mengen; Helfer `vfl-replay-peek-wert`) und spielt sie in der alten Reihenfolge ab. **Helfer-Namensschema**: die Rechenkerne heissen nach ihrer ROLLE, nicht nach der Modus-Nummer - `vfl-zsolve-*` (Hoehen-Solve, nur Modus 2) und `vfl-pfad-*` (Arbeit am gezeichneten Pfad, von Modus 2 UND 3 genutzt). Die frueheren Praefixe `vfl3-`/`vfl2-` stammten aus einer Planungsphase vor der endgueltigen Menue-Zuordnung und waren dazu vertauscht (umbenannt 2026-10-22). `Vario_Kette_Merge` (in vf_linienzug.lsp) fuehrt mehrere einzeln gebaute VF_n-Bloecke ab einem gewaehlten Start-Baustein ueber die reale KS_AUS->KS_EIN-Nachbarschaft zu einem Gesamt-Block zusammen (aggregierte Attribute, Luecken-Erkennung). Die interaktiven Editier-Pfade (`vfl-edit-ent` Sektions-Zweig, `vfl-edit-ent2`) rufen den Neuaufbau BEWUSST direkt auf, NICHT ueber `vl-catch-all-apply`: der alte Block ist beim Neuaufbau schon per `entdel` weg, und ein Catch faengt den Abbruch VOR `*error*` ab - der Abbruch-Wickler `vfl-modus-abbruch-sichern` kaeme nie zum Zug und die ganze Kette bliebe als lose Einzelteile ohne Block liegen (Fehlerbild "VF-Block aufgebrochen"). Nur der nicht-interaktive Batch-Konverter `vfl-konvertiere-ent` behaelt den Catch (die Batch-Schleife muss weiterlaufen) und meldet den betroffenen Block. Die Abbruch-Handler setzen zusaetzlich `*ssg-ils-dim*` zurueck, weil der Aufrufer, der das sonst tut, nach einem Abbruch nicht mehr erreicht wird. Recovery-Pfad fuer bereits aufgebrochene Ketten: `VF_SEKTION_RESTORE` (vf_linienzug.lsp) setzt das Ketten-Journal aus der XDATA der losen Objekte zusammen - `SSG_VF_EDIT_SEG` traegt pro Entity den Journal-Abschnitt DER ITERATION, in der es entstand (indiziert mit dem ersten Glied-Index darin; eine VF-Einheit mit eingebetteten Vario-Kurven erzeugt mehrere Glieder in einer Iteration), `SSG_VF_EDIT_PRE` auf den Entities des ersten Gliedes die Praeambel (Startpunkt/Starthoehe/AS). Die `.dbg`-Dateien sind reine AUSGABE und werden von keinem Befehl gelesen (dbgopen legt sie bei jedem Lauf neu an) - Wiederherstellungs-Daten gehoeren in die XDATA. `vf_konstanten.lsp` (von vf_core.lsp vor den drei Submodulen geladen) sammelt alle Laengen-/Winkel-/Toleranz-Magic-Numbers aus dem VarioFoerderer-Cluster als dokumentierte `*vfk-*`-Konstanten. Die Migration ist abgeschlossen: vf_core/vf_standard/vf_etage/vf_linienzug referenzieren durchgaengig die zentralen Konstanten statt roher Literale (Winkel, Stations-/Separator-Laengen, Mindestlaengen, AS/ES-Fallback-Versaetze, Text-/Label-Masse) - Ausnahmen sind in `vf_konstanten.lsp` selbst dokumentiert (Werte mit fuehrender Config-Anbindung via `ssg-cfg-or`, itoa-/Integer-Kontexte, Blocknamen-Strings, die 2000.0-mm/m-Umrechnung). `*vfk-gf-bogen-winkel*` (30/60/90, GF-Bogen + Vario-Kurve) und `*vfk-as-es-winkel*` ("30"/"90", AS/ES; bewusst STRING, da 2-wertig und im Journal als STR gefuehrt) sind Beispiele; vf_linienzug hat fuer beide einen Fallback, falls vf_konstanten nicht geladen wurde. **Nicht-interaktiver Betrieb**: `*vfl-headless*` (+ `vfl-headless-p`/`-abbruch`/`-notausgang`, Diagnose `*vfl-headless-fehler*`, optionaler Antwort-Hook `*vfl-headless-antwort-fn*`) verbietet jede Live-Eingabe - eine erschoepfte Replay-Queue ist damit ein harter Abbruch MIT Fundstelle (Art der Eingabe, Glied- und Eingabe-Nummer) statt eines stillen Rueckfalls auf `getpoint`/`getreal`; eingebaut in `vfl-in-value`/`-value-p`/`-selection`/`-abstand`. Die Bau-Pfade melden abgewiesene Sektionen ueber `vfl-meldung` (sammelt nach `*vfl-meldungen*` + `dbgmsg`, `alert` nur bei erlaubter GUI, sonst `princ`) statt per blockierendem `alert`; reine Interaktiv-Alerts (fehlendes DCL, "nicht editierbar", "kein Journal") bleiben `alert`. Genutzt von `tests/test_hm_recformat.lsp` (Replay der echten Aufzeichnungen) und von `vf_spec.lsp`; Fahrplan in `doc/todo/plan-vf-interactive.md`. **Zufuehrungsachse + "Parallel zum Kreisel"** (Modus 1, 2026-10-21): die AS-Praeambel fragt jetzt Winkel, Seite UND eine optionale Zufuehrungsachse (2. Punkt) - beide zusammen legen AS-Lage (KS_EIN auf der Achse) und Kettenrichtung (KS_AUS ueber die Seiten-Variante) fest, BEVOR eine Strecke geklickt wird; Journalfolge `[STR winkel][STR seite][PT p2 | NIL]`, welche Fragen gestellt wurden wird NICHT journalisiert, sondern beim Replay aus der Eintragsart erkannt (PT direkt nach dem Winkel = Alt-Achse ohne Seite 2026-10-14..10-20, PT/NIL nach der Seite = neues Format, alles andere = Altbestand ohne Achse). Darauf setzt die 5. Option der gf-laenge-modus-Frage auf, intern `"parallel"` (`vfl-gf-parallel-kreisel`): baut AS -> GF-Stueck -> GF-Bogen aus EINEM Abstandswert (senkrecht zur Zufuehrungsachse, AS-KS_EIN bis Bogen-KS_AUS), ohne Separator dazwischen, und stellt die Kettenende-Frage selbst NACH dem Bau. Nur am Kettenanfang mit AS UND Achse waehlbar (sonst Kachel deaktiviert). Bogenwahl nicht hartcodiert, sondern ueber den gemessenen `vf-element-plan-turn` - gewaehlt wird der Bogen, der den AS-Schwenk aufhebt (AS 30 -> 30-Grad-Bogen, AS 90 -> 90-Grad-Bogen, immer Gegenseite; die Zuordnung ist das ERGEBNIS der Messung, keine gepflegte Tabelle). Reine Kerne `vfl-par-bogen-waehlen`/`vfl-par-gf-laenge` in `tests/test_unit.lsp` (`tu-tests-vfl-parallel`) getestet; Ablauf in `doc/vf_linienzug_modus1_anleitung.md` Abschnitt 3a. Details/Entscheidungsbaum: `doc/variofoerderer.md` | +| `VarioFoerderer.lsp` (Wrapper fuer `vf_core.lsp`/`vf_standard.lsp`/`vf_etage.lsp`/`vf_linienzug.lsp`) | FOERDERANLAGE, VARIOFOERDERER_EDIT, VARIOFOERDERER_NACHRUESTEN, Vario_Kette_Merge, VF_SEKTION_RESTORE, VF_WIZARD_AN, VF_WIZARD_AUS | Vario-Foerderanlagen Generator (Typen Standard/Etage/Linienzug); Standard- UND Etage-Typ: Werteingabe per DCL-Dialog, inkl. der vorgelagerten Eingabemodus-Wahl 3D-Linie/Werte manuell (`vfc_eingabemodus`, `vfc-dialog-eingabemodus-waehlen`) - beide Modi laufen seitdem in denselben Basis-/Winkel-Dialog, der Konsolen-Pfad ist nur noch Rueckfall bei abgeschalteter GUI/anderer Sprache. Der Dialog-Ablauf ist zentral in vf_core (`vf-dialog-ablauf`/`vf-dialog-berechnen-einfuegen`, parametrisiert ueber Typ-Registry `*vf-typ-registry*` + Flag `horizontal-p`); `vfs-standard-dialog-ablauf`/`vfe-etage-dialog-ablauf` sind nur noch duenne Wrapper darauf. Beide nutzen dieselben Dialoge `vfs-dialog-eingabe-basis`/`vfs-dialog-winkel-verteilung` und den gemeinsamen L_GF/L_VF-Solve `vf-winkel-solve` (vf_core; berechne-alle-winkel/berechne-winkel-etage teilen ihn); Doppelklick auf VF_n-Block ruft VARIOFOERDERER_EDIT, das per SSG_VF_EDIT-XDATA-Marker ("standard"/"etage"/"linienzug") in den passenden Neuaufbau-Zweig dispatcht (`vfe-edit-ent` fuer Etage, `vfl-edit-ent` fuer Linienzug); Altbestand-Bloecke ohne Marker werden abgewiesen. Linienzug (Modus 1, `vf-linienzug-modus`) zeichnet jede interaktive Eingabe in einem Journal auf (`vfl-in-point`/`-string`/`-real`/`-int`) und schreibt es als XDATA auf den fertigen `VF_n`-Block; ein Abbruch (ESC) loescht dadurch nichts mehr, sondern wickelt die bis dahin gebaute Teil-Geometrie ebenso zu einem Block (`vfl-modus-abbruch-sichern`) - sie bleibt stehen und ist sofort per Doppelklick weiter editierbar/fortsetzbar. Der komplette Linienzug-Hauptstrang (Menue-Fragen von AS-Element bis Kettenende, inkl. GF-Bogen/Vario-Kurve/VF-Einheit-Fortsetzung) laeuft per Default ueber DCL-Dialoge statt Konsole (`*vfl-wizard-mode*`, Befehle VF_WIZARD_AN/VF_WIZARD_AUS): `vfl-in-string`/`-int`/`-real` zeigen bei aktivem Wizard-Modus generische Dialoge aus `dcl/vf_linienzug_wizard.dcl` (Zahl-Eingabe bzw. Mehrfachauswahl aus `vfl-menu`/`vfl-menu-int`) statt `getstring`/`getint`/`getreal` aufzurufen; die ORIGINALEN Konsolen-Fragen (princ + get*, de/en ueber ssg-text) bleiben unveraendert im Code (Fallback bei Fehlern via `vl-catch-all-apply`, siehe `doc/variofoerderer.md`). `vfl-edit-ent` liest das Journal, zeigt die Sektionen ueber einen DCL-Dialog (`vfl-dlg-position`, `dcl/vfl_edit.dcl`) an, kuerzt bei Bedarf auf eine gewaehlte Sektion (stummer Replay der behaltenen Eingaben, umgeht den Wizard-Zweig komplett) und baut danach interaktiv weiter. Linienzug Modus 2 (Pfad+Zielhoehe-Solver, `vf-linienzug-modus2`) nutzt dieselben Wrapper PLUS die neue Objektauswahl-Wrapper-Funktion `vfl-in-selection` (Pfad-Objekte als stabile Entity-Handles journalisiert, neue Journal-Art `"OBJS"`) und schreibt sein Journal unter dem eigenen XDATA-Marker `"linienzug2"`; Doppelklick baut hier NICHT abschnittsweise, sondern per vollem Reset 1:1 aus dem Journal neu auf (`vfl-edit-ent2`, dispatcht aus `vfl-edit-ent` per Marker) - Modus 3 (Vorwaerts-Nachbau) baut dieselbe Pfad-Geometrie VORWAERTS mit vorgegebenen Winkeln durch: die Endhoehe ist dort ein Ergebnis, kein Ziel (Anfangs- statt Randwertproblem) - genau das ist sein eigener Anwendungsfall, und er schreibt ein eigenes Journal (Marker `"linienzug3"`), ist also ebenso per Doppelklick editierbar. Seit 2026-10-22 fragt er wie Modus 2 "AS bauen?"/"ES bauen?" (je mit Winkel+Seite in EINEM Dialog, `vflw-gruppe-as-impl`), und die **ES-Frage steht VOR dem Bau** - erst damit traegt die Trimmung der letzten Geraden (`- Separator - ein-dx`) den echten ES-Fussabdruck statt eines Schaetzwerts bzw. des Werts der vorherigen Kette. Aeltere `"linienzug3"`-Journale erkennt `alt-journal` am WERT des ersten Antwort-Eintrags (`"30"`/`"90"` = alt vs. `"1"`/`"2"` = neu, disjunkte Mengen; Helfer `vfl-replay-peek-wert`) und spielt sie in der alten Reihenfolge ab. **Helfer-Namensschema**: die Rechenkerne heissen nach ihrer ROLLE, nicht nach der Modus-Nummer - `vfl-zsolve-*` (Hoehen-Solve, nur Modus 2) und `vfl-pfad-*` (Arbeit am gezeichneten Pfad, von Modus 2 UND 3 genutzt). Die frueheren Praefixe `vfl3-`/`vfl2-` stammten aus einer Planungsphase vor der endgueltigen Menue-Zuordnung und waren dazu vertauscht (umbenannt 2026-10-22). `Vario_Kette_Merge` (in vf_linienzug.lsp) fuehrt mehrere einzeln gebaute VF_n-Bloecke ab einem gewaehlten Start-Baustein ueber die reale KS_AUS->KS_EIN-Nachbarschaft zu einem Gesamt-Block zusammen (aggregierte Attribute, Luecken-Erkennung). Die interaktiven Editier-Pfade (`vfl-edit-ent` Sektions-Zweig, `vfl-edit-ent2`) rufen den Neuaufbau BEWUSST direkt auf, NICHT ueber `vl-catch-all-apply`: der alte Block ist beim Neuaufbau schon per `entdel` weg, und ein Catch faengt den Abbruch VOR `*error*` ab - der Abbruch-Wickler `vfl-modus-abbruch-sichern` kaeme nie zum Zug und die ganze Kette bliebe als lose Einzelteile ohne Block liegen (Fehlerbild "VF-Block aufgebrochen"). Nur der nicht-interaktive Batch-Konverter `vfl-konvertiere-ent` behaelt den Catch (die Batch-Schleife muss weiterlaufen) - er laeuft dafuer unter `*vfl-headless*`, laesst den ALTEN Block bis zum erfolgreichen Neubau stehen (Erfolg = neuer `VF_*`-INSERT nach der Startmarke; sonst raeumt `vfl-konvert-aufraeumen` die Teil-Geometrie weg) und sammelt die Gruende in `*vfl-konvert-fehler*`, die `SSG_DIM_ALL_2D`/`_3D` am Ende auflistet. Die Abbruch-Handler setzen zusaetzlich `*ssg-ils-dim*` zurueck, weil der Aufrufer, der das sonst tut, nach einem Abbruch nicht mehr erreicht wird. Recovery-Pfad fuer bereits aufgebrochene Ketten: `VF_SEKTION_RESTORE` (vf_linienzug.lsp) setzt das Ketten-Journal aus der XDATA der losen Objekte zusammen - `SSG_VF_EDIT_SEG` traegt pro Entity den Journal-Abschnitt DER ITERATION, in der es entstand (indiziert mit dem ersten Glied-Index darin; eine VF-Einheit mit eingebetteten Vario-Kurven erzeugt mehrere Glieder in einer Iteration), `SSG_VF_EDIT_PRE` auf den Entities des ersten Gliedes die Praeambel (Startpunkt/Starthoehe/AS). Die `.dbg`-Dateien sind reine AUSGABE und werden von keinem Befehl gelesen (dbgopen legt sie bei jedem Lauf neu an) - Wiederherstellungs-Daten gehoeren in die XDATA. `vf_konstanten.lsp` (von vf_core.lsp vor den drei Submodulen geladen) sammelt alle Laengen-/Winkel-/Toleranz-Magic-Numbers aus dem VarioFoerderer-Cluster als dokumentierte `*vfk-*`-Konstanten. Die Migration ist abgeschlossen: vf_core/vf_standard/vf_etage/vf_linienzug referenzieren durchgaengig die zentralen Konstanten statt roher Literale (Winkel, Stations-/Separator-Laengen, Mindestlaengen, AS/ES-Fallback-Versaetze, Text-/Label-Masse) - Ausnahmen sind in `vf_konstanten.lsp` selbst dokumentiert (Werte mit fuehrender Config-Anbindung via `ssg-cfg-or`, itoa-/Integer-Kontexte, Blocknamen-Strings, die 2000.0-mm/m-Umrechnung). `*vfk-gf-bogen-winkel*` (30/60/90, GF-Bogen + Vario-Kurve) und `*vfk-as-es-winkel*` ("30"/"90", AS/ES; bewusst STRING, da 2-wertig und im Journal als STR gefuehrt) sind Beispiele; vf_linienzug hat fuer beide einen Fallback, falls vf_konstanten nicht geladen wurde. **Nicht-interaktiver Betrieb**: `*vfl-headless*` (+ `vfl-headless-p`/`-abbruch`/`-notausgang`, Diagnose `*vfl-headless-fehler*`, optionaler Antwort-Hook `*vfl-headless-antwort-fn*`) verbietet jede Live-Eingabe - eine erschoepfte Replay-Queue ist damit ein harter Abbruch MIT Fundstelle (Art der Eingabe, Glied- und Eingabe-Nummer) statt eines stillen Rueckfalls auf `getpoint`/`getreal`; eingebaut in `vfl-in-value`/`-value-p`/`-selection`/`-abstand`. Die Bau-Pfade melden abgewiesene Sektionen ueber `vfl-meldung` (sammelt nach `*vfl-meldungen*` + `dbgmsg`, `alert` nur bei erlaubter GUI, sonst `princ`) statt per blockierendem `alert`; reine Interaktiv-Alerts (fehlendes DCL, "nicht editierbar", "kein Journal") bleiben `alert`. Genutzt von `tests/test_hm_recformat.lsp` (Replay der echten Aufzeichnungen) und von `vf_spec.lsp`; Fahrplan in `doc/todo/plan-vf-interactive.md`. **Zufuehrungsachse + "Parallel zum Kreisel"** (Modus 1, 2026-10-21): die AS-Praeambel fragt jetzt Winkel, Seite UND eine optionale Zufuehrungsachse (2. Punkt) - beide zusammen legen AS-Lage (KS_EIN auf der Achse) und Kettenrichtung (KS_AUS ueber die Seiten-Variante) fest, BEVOR eine Strecke geklickt wird; Journalfolge `[STR winkel][STR seite][PT p2 | NIL]`, welche Fragen gestellt wurden wird NICHT journalisiert, sondern beim Replay aus der Eintragsart erkannt (PT direkt nach dem Winkel = Alt-Achse ohne Seite 2026-10-14..10-20, PT/NIL nach der Seite = neues Format, alles andere = Altbestand ohne Achse). Darauf setzt die 5. Option der gf-laenge-modus-Frage auf, intern `"parallel"` (`vfl-gf-parallel-kreisel`): baut AS -> GF-Stueck -> GF-Bogen aus EINEM Abstandswert (senkrecht zur Zufuehrungsachse, AS-KS_EIN bis Bogen-KS_AUS), ohne Separator dazwischen, und stellt die Kettenende-Frage selbst NACH dem Bau. Nur am Kettenanfang mit AS UND Achse waehlbar (sonst Kachel deaktiviert). Bogenwahl nicht hartcodiert, sondern ueber den gemessenen `vf-element-plan-turn` - gewaehlt wird der Bogen, der den AS-Schwenk aufhebt (AS 30 -> 30-Grad-Bogen, AS 90 -> 90-Grad-Bogen, immer Gegenseite; die Zuordnung ist das ERGEBNIS der Messung, keine gepflegte Tabelle). Reine Kerne `vfl-par-bogen-waehlen`/`vfl-par-gf-laenge` in `tests/test_unit.lsp` (`tu-tests-vfl-parallel`) getestet; Ablauf in `doc/vf_linienzug_modus1_anleitung.md` Abschnitt 3a. Details/Entscheidungsbaum: `doc/variofoerderer.md` | | `vf_spec.lsp` (von vf_core.lsp NACH vf_linienzug.lsp geladen) | VF_SPEC_BAU | Linienzug-Ketten aus **Eingabedaten** bauen, ohne Dialog und ohne Konsolenfrage (Stufe 1 aus `doc/todo/plan-vf-interactive.md`). Eine **Spec** beschreibt eine Kette in Domaenenwerten (`"links"`, `"winkel"`, `"aussen"`, ja/nein) statt in Menue-Codes; `vsp-journal` uebersetzt sie in ein Eingabe-Journal, `vsp-bau-aus-spec` spielt es per `vfl-journal-replay-start` durch den UNVERAENDERTEN `vf-linienzug-modus` (Replay-Kern `vsp-bau-journal` - nimmt auch ein unveraendert uebernommenes, aufgezeichnetes Journal, z.B. aus `dxf_anlage_export.py`). Damit traegt der fertige Block dasselbe `SSG_VF_EDIT`-Journal wie eine handgebaute Kette und bleibt per Doppelklick editier- und 2D/3D-konvertierbar - kein Journal-Konsument muss etwas von Specs wissen. Wichtige Regeln, die der Uebersetzer kennt: der Menue-Code haengt am Frame (erste Sektion 4 Optionen ohne GF-Bogen, danach 5), `hz` steht nur beim ERSTEN Segment im Journal, und `erst-hor` unterscheidet den horizontalen Erstkoerper einer VF-Einheit (Separator-/Endpunktfragen vorab) vom gewinkelten (keine Frage). Fehlerverhalten: fail fast - `vsp-pruefen` sammelt ALLE Spec-Fehler, gebaut wird dann nichts (nichts wird geraten). Ergebnis-Record je Kette mit `status` (`executed`/`warnung`/`desync`/`abbruch`/`spec-fehler`), Block/Handle/Einfuegepunkt/Attributen, `prompts` (muss 0 sein), `glieder_soll` vs. `glieder_ist` (Desync-Detektor, der auch bei aufgehender Queue greift) und den gesammelten `meldungen`. Headless-Rahmen `vsp-headless-an`/`-aus` (Save/Restore von `*vfl-headless*`, `*vfl-wizard-mode*`, `*ssg-gui-aus*` + zaehlende Eingabe-Stubs). Spec-Datei flach als JSON (`ssg-load-json` liest zeilenweise), erzeugt von `lib/vf_spec_export.py`. Gegenstueck/Referenz in Python: derselbe Emitter, gegen die 5 echten HundM-Ketten rundlaufgeprueft | | `Gefaellestrecke.lsp` | GEFAELLESTRECKE, GEFAELLESTRECKE_EDIT | Gefaelle-Foerderanlage (AUS -> Staustrecke skaliert -> Separator -> EIN); Modus 1 per DCL-Dialog (Einfuegehoehe, Element-Winkel 30/90); Doppelklick auf GF_n-Block ruft GEFAELLESTRECKE_EDIT (Dialog vorbelegt, Neuaufbau; die Einfuegehoehe kommt aus der aktuellen Z des Einfuegepunkts statt aus XDATA/HOEHE_VON_mm, damit ein in Z verschobener Block per OK direkt auf der neuen Hoehe neu entsteht - gleiches gilt fuer die 2D/3D-Umschaltung `gf-konvertiere-ent`; der GF-Linienzug-Rebuild nutzt weiter die absoluten Segmentpunkte aus XDATA) | | `export.lsp` | EXPORTSIVAS, EXPORTCSV, OMNI_UPDATE_ATTRIBS, CSV_EXPORT_KONFIG | JSON-Sammlung und Python-Export (Omniflo-Merkmale/Sum-Zeile via lib/export_csv.py). **Gefrorene Layer**: `csv:collect-export-blocks` laesst Bloecke auf gefrorenen Layern aus (ausgeschaltete Layer zaehlen NICHT), Schalter `*csv-gefrorene-ausschliessen*` (Standard an, Toggle im Dialog CSV_EXPORT_KONFIG). Die Hilfsobjekte eines gefrorenen VF_n/GF_n (Separator-/Element-Kopien, Einheiten-/AS-ES-Marker) liegen auf eigenen Layern und werden darum ueber `*csv-ausschluss-enames*` mit ausgelassen (gesetzt in `csv:export-vorbereiten` per `csv:hilfskopien-ausschluss`); erzeugt und nummeriert werden sie trotzdem, damit IDs stabil bleiben. DrawPlanquadrate nutzt dieselbe Sammlung und folgt dem Filter. **Hoehen-Neuberechnung**: erster Schritt von `csv:export-vorbereiten` ist `csv:hoehen-aktualisieren` - in Z verschobene `KREISEL_*`/`ECKRAD_*`/`VF_*`/`GF_*` bekommen ihre Hoehen-Attribute aus der Einfuege-Z neu (reiner Kern `csv:hoehen-werte`, getestet; Formeln/Rundung wie beim Bau: Kreisel HOEHE + MONTAGEHOEHE_m=z/1000, Eckrad HOEHE, GF/VF HOEHE_VON_mm=(fix z), MONTAGEHOEHE_m GF=z/1000 bzw. VF=(VON+BIS)/2000). HOEHE_BIS_mm = VON - (VON_alt - BIS_alt), bewusst NICHT z - DELTA_H_mm (ohne Vorzeichen -> steigende VF falsch, separat abgeschnitten -> 1 mm Abweichung); DELTA_H_mm nur Rueckfall. Nicht verschobene Bloecke (Attribut passt zu z) bleiben unangetastet, damit Bau-Werte und Hand-Korrekturen (z.B. Buehnen-Abzug aus HOEHEN_CHECK) bit-genau erhalten bleiben | diff --git a/Lisp/SSG_LIB_Commands.lsp b/Lisp/SSG_LIB_Commands.lsp index a3da2bf..720d115 100644 --- a/Lisp/SSG_LIB_Commands.lsp +++ b/Lisp/SSG_LIB_Commands.lsp @@ -226,6 +226,7 @@ (if (car (atoms-family 1 '("SSG-ENSURE"))) (progn (ssg-ensure "Gefaellestrecke") (ssg-ensure "VarioFoerderer"))) (setq enames '() n-gf 0 n-vf 0 n-skip 0) + (setq *vfl-konvert-fehler* nil) ; Fehlschlaege der Linienzug-Konvertierung (ssg-start "SSG_DIM_BATCH" '(("OSMODE") ("ATTREQ") ("ATTDIA"))) (setvar "OSMODE" 0) ;; Erst alle enames sammeln (entdel veraendert die Zeichnung waehrend der Iteration) @@ -247,12 +248,12 @@ (if (gf-konvertiere-ent ent ziel-dim) (setq n-gf (1+ n-gf)))) ((wcmatch bname "VF_*") ;; VF_-Bloecke nach Edit-Marker unterscheiden: Standard/Etage - ;; ueber vf-konvertiere-ent, Linienzug (Modus 1/2) ueber den + ;; ueber vf-konvertiere-ent, Linienzug (Modus 1/2/3) ueber den ;; Journal-Replay-Konverter vfl-konvertiere-ent. Altbestand ohne ;; bekannten Marker wird uebersprungen. (setq marker (car (vfs-xdata-lesen ent))) (cond - ((member marker '("linienzug" "linienzug2")) + ((member marker '("linienzug" "linienzug2" "linienzug3")) (if (vfl-konvertiere-ent ent ziel-dim) (setq n-vf (1+ n-vf)) (setq n-skip (1+ n-skip)))) ((member marker '("standard" "etage")) @@ -264,6 +265,14 @@ (ssg-end) (princ (ssg-textf "dim-batch-fertig" (list ziel-dim (itoa n-gf) (itoa n-vf) (itoa n-skip)))) + ;; Fehlgeschlagene Linienzug-Bloecke gesammelt ausgeben (alter Block blieb + ;; jeweils unveraendert stehen, siehe vfl-konvertiere-ent) + (if *vfl-konvert-fehler* + (progn + (princ (ssg-textf "dim-batch-fehlerliste" + (list (itoa (length *vfl-konvert-fehler*))))) + (foreach f *vfl-konvert-fehler* + (princ (ssg-textf "dim-batch-fehler-zeile" (list (car f) (cdr f))))))) (princ) ) diff --git a/Lisp/vf_linienzug.lsp b/Lisp/vf_linienzug.lsp index f60cdb2..a514a13 100644 --- a/Lisp/vf_linienzug.lsp +++ b/Lisp/vf_linienzug.lsp @@ -9972,12 +9972,50 @@ ;; vl-catch-all-apply schuetzt vor (exit)/Fehlern im Bau (z.B. KS-Problem bei ;; einem 2D-Koerperblock ohne gueltiges KS), damit die Batch-Schleife weiterlaeuft ;; und der Override sicher zurueckgesetzt wird. Rueckgabe: T bei Erfolg, sonst nil. -;; Bekannte Grenze (nur Modus 2): das Replay von vfl-in-selection braucht die -;; Original-Pfadobjekte; wurden sie geloescht, schlaegt der Konverter fuer diesen -;; Block sauber fehl (sichtbar am nicht erhoehten Batch-Zaehler). Modus 3 -;; ("linienzug3") hat diese Grenze NICHT: es replayt die Segment-Essenz (SEGS) -;; aus dem Journal, nicht die Objekt-Handles - unabhaengig von den Original-LINE/ARC. -(defun vfl-konvertiere-ent (ent ziel-dim / bname xd marker journal ok) +;; +;; Headless + "alter Block erst nach Erfolg weg" (2026-10-26): +;; - Der Replay laeuft unter *vfl-headless* (Wizard aus, GUI aus): reicht das +;; Journal nicht (Bau-Dialog hat seit dem Bau des Blocks neue Fragen +;; bekommen), bricht der Bau mit Fundstelle ab, statt mitten im Batch live +;; nachzufragen. +;; - Der ALTE Block bleibt waehrend des Neubaus stehen und wird erst geloescht, +;; wenn ein neuer VF_n-INSERT entstanden ist. Scheitert der Neubau, wird +;; alles seit der Startmarke Erzeugte wieder entfernt - der alte Block bleibt +;; unveraendert, es entstehen keine losen Teile mehr. (Der neue Block bekommt +;; eine neue Nummer; das war schon vorher so, weil vf-next-number die +;; Definition des geloeschten VF_n ueberspringt.) +;; - Jede Fehlschlag-Ursache landet in *vfl-konvert-fehler* als +;; (blockname . text), der Batch-Aufrufer gibt die Liste am Ende aus. +;; Modus 2 UND 3 replayen die Segment-Essenz (SEGS) aus dem Journal, nicht +;; die Objekt-Handles - unabhaengig von den Original-LINE/ARC. Alte +;; OBJS-"linienzug2"-Bloecke werden uebersprungen (siehe unten). +(if (not (boundp '*vfl-konvert-fehler*)) (setq *vfl-konvert-fehler* nil)) + +;; Ersten VF_*-INSERT nach der Startmarke suchen (= der neu gebaute Wrapper). +(defun vfl-konvert-neuer-block (marke / e ed) + (setq e (if marke (entnext marke) (entnext))) + (while (and e + (not (and (setq ed (entget e)) + (= (cdr (assoc 0 ed)) "INSERT") + (wcmatch (cdr (assoc 2 ed)) "VF_*")))) + (setq e (entnext e))) + e) + +;; Alles nach der Startmarke Erzeugte loeschen (Teil-Geometrie eines +;; gescheiterten Neubaus). ATTRIB/SEQEND/VERTEX gehoeren zu ihrem Hauptobjekt +;; und verschwinden mit ihm. +(defun vfl-konvert-aufraeumen (marke / e naechste ed liste) + (setq e (if marke (entnext marke) (entnext))) + (while e + (setq ed (entget e)) + (if (and ed (not (member (cdr (assoc 0 ed)) '("ATTRIB" "SEQEND" "VERTEX")))) + (setq liste (cons e liste))) + (setq e (entnext e))) + (foreach e liste (if (entget e) (entdel e))) + (length liste)) + +(defun vfl-konvertiere-ent (ent ziel-dim / bname xd marker journal ok marke neu + alt-wizard alt-headless alt-gui grund) (setq bname (cdr (assoc 2 (entget ent)))) (setq xd (vfl-journal-xdata-lesen ent)) ; (marker . journal) oder nil (setq marker (car xd) journal (cdr xd)) @@ -9990,8 +10028,16 @@ ;; (nil zurueck), damit die Batch-Schleife sauber weiterlaeuft. (or (/= marker "linienzug2") (vfl-journal-hat-segs-p journal))) (progn + (setq marke (ssg-lastent-ohne-attribute)) ; Startmarke VOR dem Neubau + ;; Headless-Rahmen (wie vsp-headless-an, aber ohne Eingabe-Stubs: die + ;; vfl-in-*-Wrapper brechen bei leerer Queue selbst ab) + (setq alt-wizard (if (boundp '*vfl-wizard-mode*) *vfl-wizard-mode*) + alt-headless (if (boundp '*vfl-headless*) *vfl-headless*)) + (setq *vfl-wizard-mode* nil *vfl-headless* T + *vfl-headless-fehler* nil *vfl-meldungen* nil) + (setq alt-gui (if (car (atoms-family 1 '("SSG-GUI-P"))) (ssg-gui-p))) + (if alt-gui (ssg-gui-aus)) (setq *ssg-ils-dim* ziel-dim) ; Zieldim erzwingen - (entdel ent) ; alten Block weg (vfl-journal-replay-start journal) ; volle Queue, KEIN Truncate (setq *vfl-replay-kette* bname) ; Fundstelle fuer Replay-Meldungen (setq ok (vl-catch-all-apply @@ -9999,18 +10045,25 @@ ((= marker "linienzug3") 'vf-linienzug-modus3) (t 'vf-linienzug-modus)))) (setq *ssg-ils-dim* nil) ; Override zuruecksetzen - ;; Fehlgeschlagene Konvertierung NICHT stumm verschlucken: der alte Block - ;; ist per entdel schon weg, die Teil-Geometrie liegt frei in der - ;; Zeichnung (der *error*-Handler in vf-linienzug-modus kann hier nicht - ;; greifen, weil vl-catch-all-apply den Abbruch vorher abfaengt - das ist - ;; hier gewollt, damit die Batch-Schleife weiterlaeuft). Meldung mit - ;; Blockname, damit der betroffene Block auffindbar bleibt. - (if (vl-catch-all-error-p ok) + (setq *vfl-wizard-mode* alt-wizard *vfl-headless* alt-headless) + (if alt-gui (ssg-gui-an)) ; nur zurueck, wenn sie an war + (setq neu (vfl-konvert-neuer-block marke)) + (if (and (not (vl-catch-all-error-p ok)) neu) + (progn (entdel ent) T) ; Erfolg: erst jetzt alten weg (progn - (princ (ssg-textf "vfl-konvert-fehler" - (list bname (vl-catch-all-error-message ok)))) - nil) - T)) + ;; Grund: Headless-Fundstelle vor Fehlertext vor letzter Meldung + (setq grund + (cond ((cdr (assoc "ort" *vfl-headless-fehler*)) + (ssg-textf "vfl-konvert-grund-journal" + (list (cdr (assoc "ort" *vfl-headless-fehler*))))) + ((vl-catch-all-error-p ok) (vl-catch-all-error-message ok)) + (*vfl-meldungen* (last *vfl-meldungen*)) + (t (ssg-text "vfl-konvert-grund-kein-block")))) + (vfl-konvert-aufraeumen marke) + (setq *vfl-konvert-fehler* + (append *vfl-konvert-fehler* (list (cons bname grund)))) + (princ (ssg-textf "vfl-konvert-fehler" (list bname grund))) + nil))) nil)) (defun vfl-edit-ent (ent / xd marker journal glieder glieder-alle has-as n i pos trunc edit-modus dim) diff --git a/doc/todo.md b/doc/todo.md index 1f1c54a..230b1f5 100644 --- a/doc/todo.md +++ b/doc/todo.md @@ -16,17 +16,15 @@ Stand: 2026-10-26. Wird woechentlich (freitags) mit der Doku geprueft, siehe falsch), weil der Solver die festen Fussabdruecke skalar von EINER Spanne abzieht. Als Zwischenloesung zumindest gefaltete Laeufe mit Meldung abweisen. -> `doc/todo/modus2-achsenweise-bilanz.md` -- **VF-Linienzug ohne GUI/Konsole, Stufe 2** (Funktionstrennung): - Schritte 5c, 6, 8, 9, 10 offen (u.a. `vfl-spec-ausfuehren`, Daten-Pfad ohne - Replay-Umweg), Schritt 11 (Modus 2) zurueckgestellt. Bringt Architektur, - keine neue Funktion. -> `doc/todo/plan-vf-interactive.md` -- **Spec-Uebersetzer fuer Modus 2/3** (Stufe 1 Rest): `vsp-journal` kann nur - Modus-1-Ketten. Braucht erst 2-3 echte `linienzug2`/`linienzug3`-Journale - als Referenz; Abschnitt 4.4 des Plans auf das `SEGS`-Journalformat - anpassen. -> `doc/todo/plan-vf-interactive.md` -- **`vfl-konvertiere-ent` headless?** Die Batch-2D/3D-Konvertierung laeuft - ohne `*vfl-headless*` (Live-Rueckfrage bisher gewollt). Entscheiden, ob sie - auf den Ergebnis-Record umgestellt wird. +- **VF-Linienzug ohne GUI/Konsole, Stufe 2** (Funktionstrennung): eigener, + separat abzuarbeitender Auftrag mit Schritt-Tabelle. Schritte 5c, 6, 8, 9, + 10 offen (u.a. `vfl-spec-ausfuehren`), 11 zurueckgestellt. Niedrige + Prioritaet - Architektur, keine neue Funktion. + -> `doc/todo/linienzug-ohne-gui.md` +- **Spec-Uebersetzer fuer Modus 2/3** (Stufe 1 Rest): `VF_SPEC_BAU` kann nur + Modus-1-Ketten. Erster Schritt: 2-3 echte `linienzug2`/`linienzug3`- + Journale (SEGS-Format) als Referenz in BricsCAD erzeugen. + -> `doc/todo/spec-modus2-3.md` - **Stufe 3 Winkelwahl: "Ab"-Zweig** (`vf_standard.lsp`, Kommentar bei der Fuellstueck-Berechnung): nur "Auf" implementiert, "Ab" bleibt bewusst offen, bis ein konkreter Bedarfsfall vorliegt. Ebenso `schon-flach` in Stufe 3. diff --git a/doc/todo/linienzug-ohne-gui.md b/doc/todo/linienzug-ohne-gui.md new file mode 100644 index 0000000..a323123 --- /dev/null +++ b/doc/todo/linienzug-ohne-gui.md @@ -0,0 +1,98 @@ +# TODO: VF-Linienzug ohne GUI/Konsole - Stufe 2 (Funktionstrennung) + +**Stand:** 2026-10-26 · **Prioritaet:** niedrig - bringt Architektur, keine +neue Funktion. + +Herausgeloester Arbeitsauftrag aus dem Gesamtplan +[plan-vf-interactive.md](plan-vf-interactive.md) (Teil 5 "Stufe 2: echte +Funktionstrennung"). Dort stehen die ausfuehrliche Begruendung, die +Knotenform und die Risikoliste; diese Datei ist die Abarbeitungsliste. + +## Ausgangslage (Stufe 1, fertig) + +Linienzug-Ketten lassen sich bereits ohne Dialog bauen (`VF_SPEC_BAU`, +[vf_spec.lsp](../../Lisp/vf_spec.lsp)) - allerdings ueber einen Umweg: + +1. Die **Spec** (Kette in Domaenenwerten) wird von `vsp-journal` in ein + Eingabe-Journal uebersetzt - also in die Antworten, die ein Anwender + gegeben haette. +2. `vsp-bau-journal` startet per `vfl-journal-replay-start` den ganz normalen + interaktiven Bau `vf-linienzug-modus` ([vf_linienzug.lsp](../../Lisp/vf_linienzug.lsp)). +3. Jede Frage wird aus der Replay-Queue beantwortet. + +Das funktioniert und ist per `TEST_HUNDM05` im CAD verifiziert - der Bau +selbst "weiss" aber nichts von Daten, er fragt weiter, nur antwortet die Queue. + +## Ziel (Stufe 2) + +Die Funktionen in `vf_linienzug.lsp` mischen **Fragen** und **Geometrie +bauen**. Stufe 2 trennt das: + +- **reiner Bauteil** (Suffix `-bauen` bzw. `-setzen`): nimmt Parameter, + baut Geometrie, fragt nichts; +- die **Frage-Schale** behaelt den bisherigen Namen und ruft den Bauteil auf + - dadurch aendert sich keine Aufrufstelle in Modus 1/2/3. + +Am Ende ruft `vfl-spec-ausfuehren` die Bauteile direkt mit den Spec-Werten +auf, ohne Journal-Replay. + +## Stand der Schritte + +Zeilennummern Stand 2026-10-26 (die `:NNNN`-Angaben im Gesamtplan sind +veraltet). + +| Schritt | Inhalt | Stand | +|---|---|---| +| 0 | `vfl-ziel-report` (vf_linienzug.lsp:7864) aus zwei identischen Bloecken gezogen | erledigt | +| 1 | Winkelwahl `vfl-winkel-gueltige` (:3071) / `vfl-winkel-nach-index` + Kanal `*vfl-winkel-idx-vorgabe*` | erledigt | +| 2 | `vfl-es-masse-setzen` (:7557) | erledigt | +| 3 | `vfl-hor-koerper-bauen` (:5989), Schale `vfl-baue-horizontal-koerper` (:6152) | erledigt | +| 4 | `vfl-body-abschluss-bauen` (:6502) | erledigt | +| 5a/5b | VF-Einheit Eingang/Ausgang: `vfl-vf-eingang-bauen` (:6728), `vfl-vf-ausgang-bauen` (:6742) | erledigt | +| **5c** | Schleifenrumpf von `vfl-vf-einheit` (:6772) - die Sub-Stuecke der VF-Einheit als Bauteil | **offen** | +| **6** | Daten-Executor fuer die VF-Einheit (baut sie direkt aus Daten) | **offen** | +| 7 | Spec + Serializer + Assertion: `vsp-journal-diff` (vf_spec.lsp:900) prueft Spec-Journal gegen das beim Bau aufgezeichnete Token fuer Token | Assertion erledigt | +| **8** | Einheit-Abschluss: `vfl-vf-einheit-abschluss` (:7889) | **offen** | +| **9** | Kettenebene, ein Glied-Zweig pro Commit: GF-Bogen -> ES -> Horizontal-VF -> Linie-GF -> Linie-VF -> Linie | **offen** | +| **10** | `vfl-spec-ausfuehren` - der direkte Daten-Pfad (existiert noch nicht) | **offen** | +| 11 | Dasselbe fuer Modus 2 | zurueckgestellt, bis 2-3 echte Modus-2-Journale als Referenz vorliegen | + +## Warum es heikel ist + +Bei den offenen Schritten ist die **Reihenfolge selbst Geometrie** +(Gesamtplan, Abschnitt "Wo Geometrie still kippen kann"), u.a.: + +- die dL-Subtraktionskette ist je Schritt mit + `(max *vfk-restlaenge-min-clamp* ...)` geklammert, also + reihenfolgeabhaengig; +- die `vfl-acc-*`-Aufrufe muessen an derselben Stelle in derselben + Reihenfolge bleiben, sonst vertauschen sich `L_VF_m`/`L_GF_m`/`GF_WINKEL` + - in der Zeichnung unsichtbar, im Sivas-Export falsch; +- `*vfl-as-winkel*`/`*vfl-es-winkel*` werden lazy von den Blocknamen-Bauern + gelesen - spaeter gesetzt heisst falscher Block; +- `ziel-gf2` vs. `L_GF2-bau` im Ausgang - geht es verloren, entsteht still + die falsche GF2 hinter dem Motor. + +Ausdruecklich nicht anfassen: siehe Gesamtplan, Abschnitt "Ausdruecklich +nicht anfassen" (u.a. alle Journal-Konsumenten, `vfl-in-*`-Wrapper, +Wizard-Schicht, Abbruch-Pfad). + +## Ablauf je Schritt + +1. Umbauen (Frage-Schale behaelt Namen, Bauteil wortwoertlich umziehen, + keine Umsortierung). +2. CAD-Lauf: `TEST_HUNDM05` (save dxf), `TEST_VF_SPEC`, `TEST_LINIENZUG`. +3. `pytest tests/test_vf_geometrie.py` gegen + `tests/reference/hundm05_attribute.json` - nennt bei Abweichung Kette + und Feld. Referenz nur nach geprueftem Lauf auffrischen + (`lib/dxf_vf_abbild.py --schreibe-referenz`). +4. Nach Geometrie-Schritten (5c, 9) zusaetzlich DXF-Diff und + Sivas-Export-Vergleich. +5. Ein Schritt pro Commit - sonst ist ein Fehler keinem Schritt mehr + zuzuordnen. + +## Wann angehen + +Erst bei konkretem Bedarf: einzelne Bauteile ohne Journal aufrufen, oder der +Replay-Umweg wird zu langsam bzw. zu fehleranfaellig. Bis dahin genuegt +Stufe 1. diff --git a/doc/todo/plan-vf-interactive.md b/doc/todo/plan-vf-interactive.md index 9e4cdb4..6ed2477 100644 --- a/doc/todo/plan-vf-interactive.md +++ b/doc/todo/plan-vf-interactive.md @@ -7,9 +7,12 @@ Schritte 0-4 + 7-Assertion fertig, 5/6/8/9/10 offen, 11 zurueckgestellt. **Herkunft:** Planungslauf (Plan-Modus) vom 2026-09-02, hier eingecheckt zur Nachverfolgung. **Pruefung 2026-10-26:** Stand unveraendert - Stufe 2 Schritte 5c/6/8/9/10 (u.a. `vfl-spec-ausfuehren`) und die Spec-Uebersetzer fuer Modus 2/3 sind -weiterhin nicht gebaut. Hinweis: Modus 2/3 journalisieren inzwischen -Segment-Essenz (`SEGS`) statt Objekt-Handles (`OBJS`), Abschnitt 4.4 ist -darauf noch nicht angepasst. +weiterhin nicht gebaut. Die Spec-Uebersetzer fuer Modus 2/3 (auf +`SEGS`-Basis, Abschnitt 4.4 ersetzt) sind ausgelagert nach +[spec-modus2-3.md](spec-modus2-3.md). +**Abarbeitungsliste Stufe 2:** herausgeloest nach +[linienzug-ohne-gui.md](linienzug-ohne-gui.md) (aktuelle Zeilennummern, +Ablauf je Schritt); Teil 5 hier bleibt die ausfuehrliche Referenz. ## Fortschritt @@ -93,9 +96,9 @@ Doppelklick-Edit, `SSG_DIM_SWITCH`) ist unveraendert. Das `"disabled": true` der hundm05-Zeile in `tests/alltests.json` ist weg, der Test laeuft aktiv mit. -**Bewusst nicht umgestellt**: `vfl-konvertiere-ent` (Batch-2D/3D) laeuft -weiter ohne `*vfl-headless*` - eine Live-Rueckfrage ist dort bisher gewolltes -Verhalten. Kandidat fuer Stufe 1, wenn der Ergebnis-Record steht. +**Nachtrag 2026-10-26**: `vfl-konvertiere-ent` (Batch-2D/3D) laeuft jetzt +ebenfalls unter `*vfl-headless*`; der alte Block wird erst nach erfolgreichem +Neubau geloescht (Details `doc/variofoerderer.md`, Abschnitt Headless). ## Kontext @@ -347,6 +350,11 @@ gesammelten Meldungen aus P1. ### 4.4 Modus 2 und Modus 3 +> **Ueberholt (2026-10-26):** Modus 2/3 journalisieren seit 2026-09-18 +> `SEGS` statt `OBJS`, Modus 3 hat Journal + Doppelklick-Edit. Aktueller +> Entwurf und Schritte: [spec-modus2-3.md](spec-modus2-3.md). Der folgende +> Text bleibt nur als Historie. + Modus 2: Spec traegt `("pfad-handles" ...)` (Entity-Handles der LINE/ARC-Trasse) plus `("segmente" ...)` in Pfadreihenfolge. Vor dem Bau wird die Segmentzahl gegen die aufgeloesten Handles geprueft und bei Fehlbestand abgebrochen - die diff --git a/doc/todo/spec-modus2-3.md b/doc/todo/spec-modus2-3.md new file mode 100644 index 0000000..bdb1408 --- /dev/null +++ b/doc/todo/spec-modus2-3.md @@ -0,0 +1,63 @@ +# TODO: Spec-Uebersetzer fuer VF-Linienzug Modus 2 und 3 + +**Stand:** 2026-10-26 · **Prioritaet:** mittel - einzige fehlende +FUNKTION im Daten-Pfad (Modus-2/3-Ketten sind nur interaktiv baubar). + +Herausgeloester Rest von Stufe 1 aus [plan-vf-interactive.md](plan-vf-interactive.md) +(dort Abschnitt 4.4, der hiermit ersetzt ist). Schwester-Auftrag: +[linienzug-ohne-gui.md](linienzug-ohne-gui.md) (Stufe 2). + +## Ausgangslage + +Der Daten-Pfad `VF_SPEC_BAU` ([vf_spec.lsp](../../Lisp/vf_spec.lsp)) kann nur +Modus 1: + +- `vsp-journal` (vf_spec.lsp:568) kennt nur den Fragenfluss/die Menue-Codes + von `vf-linienzug-modus` (z.B. `*vsp-tab-gf-laenge-modus*`, :56). +- `vsp-bau-journal` (:939) ruft fest `vf-linienzug-modus` auf (:978). + +Modus 2 (`vf-linienzug-modus2`, Pfad + Zielhoehe, Marker `"linienzug2"`) und +Modus 3 (`vf-linienzug-modus3`, Vorwaerts-Nachbau, Marker `"linienzug3"`) +fragen grundlegend anders: erst Pfad-Auswahl (`vfl-in-segmente`), dann je +Segment ein Klassifizierungs-Dialog (`vflw_seg_linie_m2`/`_m3`, +`vflw_seg_bogen`). Dafuer gibt es weder Uebersetzer noch Bau-Aufruf. + +Doppelklick-Edit/Neuaufbau funktioniert fuer beide Modi bereits +(`vfl-edit-ent-voll`) - es fehlt nur der Bau aus einer Spec-Datei. + +## Korrektur des alten Entwurfs (Plan 4.4, Stand 2026-09-02) + +| alter Entwurf | heute (seit 2026-09-18) | +|---|---| +| Modus-2-Spec traegt `pfad-handles` (Entity-Handles, Journal-Art `OBJS`), vor dem Bau gegen die reale Zeichnung geprueft | Modus 2 UND 3 journalisieren die **Segment-Essenz** als Journal-Art `SEGS`: je Segment 9 Felder `typ hz laenge bwinkel bseite spx spy epx epy` (`vfl-segs->string`/`vfl-string->segs`, vf_linienzug.lsp). Die Kette ist selbst-enthalten, die Original-LINE/ARC werden nicht mehr gebraucht | +| Modus 3 ohne Journal-XDATA, kein Doppelklick-Edit, keine 2D/3D-Konvertierung; Nachruestung zurueckgestellt | Modus 3 schreibt Marker `"linienzug3"` und ist per Doppelklick editierbar | +| "Eine Gerade direkt nach einer Vario-Kurve wird nicht gefragt - der Uebersetzer leitet das ab" | gilt vermutlich weiter, am echten Journal pruefen | + +Folge fuer den Entwurf: Die Spec fuer Modus 2/3 traegt eine **Segmentliste** +statt Objekt-Handles plus die Klassifizierung je Segment (Typ, GF-Neigung +bzw. Wert, Bogen-Variante) und die Praeambel (Startpunkt, Starthoehe, +AS/ES). Sie ist damit wie Modus 1 **ohne Zeichnung** pruefbar. + +## Schritte + +| Schritt | Inhalt | Stand | +|---|---|---| +| 1 | Referenz-Journale erzeugen: in BricsCAD 2-3 typische Ketten je Modus (2 und 3) bauen, Zeichnung unter `tests/testdata/` ablegen. Abdecken: GF- und VF-Segmente, Bogen, AS/ES ja/nein, bei Modus 3 altes und neues AS/ES-Format | **offen** | +| 2 | Python-Lesepfad: `lib/vf_journal_export.py` (+ `vf_linienzug_grammatik.py`) lernen `linienzug2`/`linienzug3` mit `SEGS` (heute: "unbekannter Code") | **offen** | +| 3 | Spec-Form fuer Modus 2/3 festlegen (flaches JSON, lesbar von `ssg-load-json`, Segmente als Einzeiler) | **offen** | +| 4 | Python-Rundlauf `spec_aus_journal`/`journal_aus_spec` fuer Modus 2/3 in `lib/vf_spec_export.py`, Test in `tests/test_vf_spec.py`: Journal -> Spec -> Journal tokengleich | **offen** | +| 5 | LISP: `vsp-journal` je Modus (Dispatch ueber Spec-Feld `modus`), `vsp-pruefen` um Modus-2/3-Regeln erweitern | **offen** | +| 6 | `vsp-bau-journal`: Bau-Funktion nach Modus waehlen (`vf-linienzug-modus2`/`-modus3`), Ergebnis-Record wie Modus 1 (`prompts` = 0, `journal_diff` leer) | **offen** | +| 7 | CAD-Test analog `TEST_HUNDM05` + Eintrag in `tests/alltests.json`; file-freie Teile als `tu-*` in `tests/test_unit.lsp` | **offen** | + +## Hinweise + +- Korrektheitskriterium Modus 3 ist "gleiches rein, gleiches raus", NICHT + "trifft den Zielpunkt" - der Ist/Soll-Ende-Report weicht schon im + interaktiven Bau ab. +- Alte `"linienzug2"`-Bloecke mit `OBJS`-Journal (vor 2026-09-18) sind + nicht mehr editierbar und taugen NICHT als Referenz. +- Neue `vfl-in-*`-Wrapper mit `ssget`/`get*` im statischen Waechter + `tests/test_vf_headless_statisch.py` eintragen. +- Werte selbstbeschreibend in der Spec (Winkel 30/60/90, nicht Index) - + siehe CLAUDE.md, Konventionen. diff --git a/doc/variofoerderer.md b/doc/variofoerderer.md index e29e1f4..3d9ad60 100644 --- a/doc/variofoerderer.md +++ b/doc/variofoerderer.md @@ -636,9 +636,16 @@ Beispiel: `tests/test_hm_recformat.lsp` (5 echte Ketten aus `data/polylines.dxf` setzt alle drei Schalter mit Save/Restore, ersetzt `getpoint`/`getstring`/ `getint`/`getreal`/`alert` zusaetzlich durch **zaehlende** Stubs (Netz fuer Prompts ausserhalb der Wrapper) und schreibt `prompts`, `headless_fehler` und -`meldungen` in `tests/output/hm_recformat_results.json`. Noch nicht umgestellt: -`vfl-konvertiere-ent` (Batch-2D/3D-Konvertierung) laeuft weiter ohne -`*vfl-headless*` - dort ist eine Live-Rueckfrage bisher gewolltes Verhalten. +`meldungen` in `tests/output/hm_recformat_results.json`. + +Auch `vfl-konvertiere-ent` (Batch-2D/3D-Konvertierung `SSG_DIM_ALL_2D`/`_3D`, +Modus 1/2/3) laeuft seit 2026-10-26 unter `*vfl-headless*` (Wizard und GUI +aus, Save/Restore). Reicht ein Journal nicht, bricht der Neubau mit +Fundstelle ab statt mitten im Batch live zu fragen. Der ALTE Block bleibt +dabei stehen und wird erst geloescht, wenn ein neuer `VF_n`-INSERT entstanden +ist; bei einem Fehlschlag raeumt `vfl-konvert-aufraeumen` alles seit der +Startmarke Erzeugte wieder weg (keine losen Teile). Die Gruende sammelt +`*vfl-konvert-fehler*`, der Batch gibt sie am Ende als Liste aus. --- diff --git a/lang/de_DE.json b/lang/de_DE.json index d742073..08577d3 100644 --- a/lang/de_DE.json +++ b/lang/de_DE.json @@ -149,7 +149,9 @@ "vfl-edit-kette-header": "\n\nLinienzug mit %1 Glied(ern):", "vfl-edit-abgespielt": "\n>>> %1 Glied(er) werden abgespielt, %2 zurueckgenommen - danach interaktiv weiter.", "vfl-edit2-reset-info": "\n>>> Linienzug (Modus 2) wird mit den gespeicherten Angaben identisch neu aufgebaut...", - "vfl-konvert-fehler": "\n>>> FEHLER bei der Umwandlung von %1: %2 - der alte Block ist entfernt, die Teil-Geometrie liegt frei in der Zeichnung.", + "vfl-konvert-fehler": "\n>>> FEHLER bei der Umwandlung von %1: %2 - der alte Block bleibt unveraendert stehen.", + "vfl-konvert-grund-journal": "Journal reicht nicht aus (%1)", + "vfl-konvert-grund-kein-block": "kein Block erzeugt", "vfl-restore-prompt-auswahl": "\nLose Linienzug-Geometrie waehlen (die Sektions-XDATA der Objekte wird ausgelesen):", "vfl-restore-keine-sektionen": "\n>>> In der Auswahl steckt keine Sektions-XDATA (SSG_VF_EDIT_SEG) - daraus laesst sich keine Kette wiederherstellen.", "vfl-restore-luecke": "\n>>> WARNUNG: Sektion %1 fehlt in der Auswahl - nur die Glieder 1..%2 werden wiederhergestellt.", @@ -666,6 +668,8 @@ "dim-switch-blocks": "\n DXFM_BLOCKS = %1", "dim-switch-omniflo": "\n DXFM_OMNIFLO = %1", "dim-batch-fertig": "\nUmwandlung auf %1 abgeschlossen: %2 GF, %3 VF neu aufgebaut (%4 bereits in Zieldimension).", + "dim-batch-fehlerliste": "\n%1 Linienzug-Block/Bloecke NICHT umgewandelt (unveraendert stehen gelassen):", + "dim-batch-fehler-zeile": "\n - %1: %2", "sprache-gewechselt": "\nSprache umgeschaltet auf: %1", "cmd-block-auswaehlen": "\nBlock auswaehlen: ", "cmd-kein-block-ausgewaehlt": "\nKein Block ausgewaehlt.", diff --git a/lang/en_GB.json b/lang/en_GB.json index dfb6aae..3c58bf7 100644 --- a/lang/en_GB.json +++ b/lang/en_GB.json @@ -149,7 +149,9 @@ "vfl-edit-kette-header": "\n\nChain with %1 segment(s):", "vfl-edit-abgespielt": "\n>>> %1 segment(s) replayed, %2 undone - then continue interactively.", "vfl-edit2-reset-info": "\n>>> Rebuilding this Modus-2 chain identically from the saved inputs...", - "vfl-konvert-fehler": "\n>>> ERROR converting %1: %2 - the old block is gone, the partial geometry is loose in the drawing.", + "vfl-konvert-fehler": "\n>>> ERROR converting %1: %2 - the old block is left unchanged.", + "vfl-konvert-grund-journal": "journal is insufficient (%1)", + "vfl-konvert-grund-kein-block": "no block created", "vfl-restore-prompt-auswahl": "\nSelect the loose chain geometry (the section XDATA of the objects is read):", "vfl-restore-keine-sektionen": "\n>>> The selection carries no section XDATA (SSG_VF_EDIT_SEG) - no chain can be restored from it.", "vfl-restore-luecke": "\n>>> WARNING: section %1 is missing from the selection - only segments 1..%2 will be restored.", @@ -666,6 +668,8 @@ "dim-switch-blocks": "\n DXFM_BLOCKS = %1", "dim-switch-omniflo": "\n DXFM_OMNIFLO = %1", "dim-batch-fertig": "\nConversion to %1 complete: %2 GF, %3 VF rebuilt (%4 already in target dimension).", + "dim-batch-fehlerliste": "\n%1 polyline block(s) NOT converted (left unchanged):", + "dim-batch-fehler-zeile": "\n - %1: %2", "sprache-gewechselt": "\nLanguage switched to: %1", "cmd-block-auswaehlen": "\nSelect block: ", "cmd-kein-block-ausgewaehlt": "\nNo block selected.", diff --git a/tests/test_vf_headless_statisch.py b/tests/test_vf_headless_statisch.py index 60419fe..d17468b 100644 --- a/tests/test_vf_headless_statisch.py +++ b/tests/test_vf_headless_statisch.py @@ -175,10 +175,12 @@ EINGABE_ERLAUBT = { "vfl-in-selection": {"ssget": 1}, "vfl-in-segmente": {"ssget": 1}, # Modus-3-Wrapper: Live-Auswahl -> Segment-Essenz (SEGS), Replay aus Journal "vfl-winkel-live": {"getint": 1}, # livefn fuer vfl-in-value + "vfl-menu-strwert": {"getstring": 1}, # livefn fuer vfl-in-value (Wert statt Index) # --- Wizard-Schicht (DCL); bei ssg-gui-aus greift sie nicht --- "vflw-zahl": {"getreal": 1}, # Fallback ohne Dialog "vflw-zahl-impl": {"new_dialog": 1}, "vflw-wahl-impl": {"new_dialog": 1}, + "vflw-radio-wahl-impl": {"new_dialog": 1}, "vflw-gruppe-as-impl": {"new_dialog": 1}, "vflw-gruppe-gefaelle-impl": {"new_dialog": 1}, "vflw-gruppe-punkt-hoehe-impl": {"new_dialog": 1},