feat: Linienzug-Batch-Konvertierung headless, alter Block bleibt bis zum Erfolg

- vfl-konvertiere-ent laeuft unter *vfl-headless* (Wizard/GUI aus): reicht
  ein Journal nicht, Abbruch mit Fundstelle statt Live-Rueckfrage im Batch
- alter VF_n-Block wird erst nach erfolgreichem Neubau geloescht; bei
  Fehlschlag raeumt vfl-konvert-aufraeumen die Teil-Geometrie weg
- SSG_DIM_ALL_2D/_3D listet fehlgeschlagene Bloecke am Ende auf und
  konvertiert jetzt auch Modus-3-Bloecke (linienzug3 wurde uebersprungen)
- statischer Headless-Test: vfl-menu-strwert/vflw-radio-wahl-impl erlaubt
- TODO: Stufe 2 und Spec-Uebersetzer Modus 2/3 in eigene Dateien ausgelagert

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-26 10:22:30 +01:00
parent 7242d95411
commit 8db446ce0f
11 changed files with 289 additions and 43 deletions
+71 -18
View File
@@ -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)