VF-Linienzug AS/ES-Praeambel + csv:run-export entduplizieren
vf_linienzug.lsp: die 5-6x wortgleich ausgeschriebene AS-/ES-Winkel+Seite- Praeambel (Winkel 30/90, Seite links/rechts, Masse setzen) in zwei parametrische Helfer ausgelagert (vfl-frage-as-winkel-seite, vfl-frage-es-winkel-seite - Seiten-Headerkey als Parameter, symmetrisch zum bestehenden vfl-frage-es-seite). Ersetzt in modus1-AS, modus2-AS, modus2-ES. modus3-AS und die QC-Nachfrage bleiben (kein echtes Duplikat, abweichende Prompt-/Wizard-Semantik). export.lsp: csv:run-export (181 Z.) in Phasen zerlegt - csv:export-vorbereiten (Proxies/IDs/Zuordnung/Attribut-Update/Sep-Scan/REGENALL/bbox-Reset) und csv:python-aufrufen (Python-Skript-Aufruf + Exitcode-Auswertung). Runner liest sich jetzt als klare Sequenz. Verhaltensneutrale Extraktionen; Klammerbalance unveraendert, Python-Testsuite ohne neue Fehler (16 failed baseline vor/nach identisch). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> @
This commit is contained in:
+82
-55
@@ -1222,16 +1222,18 @@
|
||||
;; --- Gemeinsame Export-Funktion ---
|
||||
;; Sammelt relevante Bloecke, schreibt JSON, ruft Python auf.
|
||||
;; label = Anzeigename (z.B. "EXPORTCSV")
|
||||
;; py-name = Python-Skript-Name (z.B. "export_csv.py")
|
||||
;; csv-name = Ergebnis-CSV-Name (z.B. "export.csv")
|
||||
;; include-bbox = T -> Bounding-Box je Block ermitteln und mit exportieren
|
||||
;; (siehe csv:block-to-json); fuer EXPORTSIVAS nil.
|
||||
(defun csv:run-export (label py-name csv-name include-bbox / ss i ename fh out-pfad
|
||||
py-skript ergebnis-pfad py-exe log-pfad rc first-block
|
||||
count out-dir sep-proxies)
|
||||
;; --- Export-Vorbereitung: Zeichnungszustand fuer den Export herrichten ---
|
||||
;; Aus csv:run-export ausgelagert: alle Schritte, die VOR dem Sammeln/Schreiben
|
||||
;; den Zeichnungszustand herrichten - Separator-Proxies einpacken, IDs
|
||||
;; sicherstellen, Proxy-Zuordnung setzen, Omniflo-Attribute (HOEHE/DREHUNG)
|
||||
;; aktualisieren, Separator-/Scanner-Zuordnung pruefen, global regenerieren und
|
||||
;; die bbox-Fehlerdiagnose zuruecksetzen. Rueckgabe: die Liste der erzeugten
|
||||
;; Separator-Proxies (der Aufrufer entfernt sie am Ende wieder). label dient
|
||||
;; nur den Meldungen.
|
||||
(defun csv:export-vorbereiten (label / sep-proxies)
|
||||
;; Verpackte Separator_SP-Symbole (siehe csv:sep-proxies-erzeugen) VOR der
|
||||
;; ID-Vergabe durch temporaere, echte Kopien ersetzen - sie werden am Ende
|
||||
;; dieser Funktion wieder entfernt (csv:sep-proxies-loeschen).
|
||||
;; von csv:run-export wieder entfernt (csv:sep-proxies-loeschen).
|
||||
;;
|
||||
;; HINWEIS: csv:sepliste-proxies-erzeugen (echte Kopien fuer die nur noch in
|
||||
;; der sepliste-XDATA gefuehrten SEP/AS/ES-Eintraege der VF_n/GF_n-Wrapper)
|
||||
@@ -1291,6 +1293,76 @@
|
||||
;; bbox-Fehlerdiagnose fuer diesen Lauf zuruecksetzen (siehe csv:get-bbox).
|
||||
(setq *csv-bbox-fail-count* 0)
|
||||
(setq *csv-bbox-fail-first* nil)
|
||||
sep-proxies)
|
||||
|
||||
;; --- Python-Export-Skript aufrufen und Ergebnis auswerten ---------------
|
||||
;; Aus csv:run-export ausgelagert: das fertige raw-JSON (out-pfad) an das
|
||||
;; Python-Skript py-name uebergeben, synchron ausfuehren und den Exitcode
|
||||
;; auswerten (kein stiller Fehlschlag). Arbeitet ausschliesslich ueber die
|
||||
;; uebergebenen Pfade/Namen und die Umgebung (DXFM_LIB/DXFM_DATA/DXFM_LOG) -
|
||||
;; keine Zeichnungs-/Sammel-Logik mehr, daher gut fuer sich testbar.
|
||||
;; label/out-dir dienen nur den Meldungen bzw. dem Ergebnis-Pfad.
|
||||
(defun csv:python-aufrufen (label out-dir out-pfad py-name csv-name
|
||||
/ py-skript ergebnis-pfad py-exe log-pfad rc)
|
||||
;; Python-Skript aufrufen. DXFM_LIB muss gesetzt sein - fehlt es
|
||||
;; (z.B. weil BricsCAD nicht ueber bin/start_briscad.bat gestartet
|
||||
;; wurde und die Umgebungsvariablen daher nie in diesen Prozess
|
||||
;; vererbt wurden), wuerde das folgende strcat sonst mit einem
|
||||
;; kryptischen Lisp-Fehler ("bad argument type <NIL>") abbrechen.
|
||||
(if (null (getenv "DXFM_LIB"))
|
||||
(princ (ssg-textf "exp-dxfm-lib-missing" (list label)))
|
||||
(progn
|
||||
(setq py-skript (strcat (getenv "DXFM_LIB") "/" py-name))
|
||||
(if (findfile py-skript)
|
||||
(progn
|
||||
(setq ergebnis-pfad (strcat out-dir "/" (export:dwg-praefix) csv-name))
|
||||
(setq py-exe (export:python-exe))
|
||||
(setq log-pfad (strcat (cond ((getenv "DXFM_LOG")) (out-dir))
|
||||
"/export_python.log"))
|
||||
(princ (ssg-textf "exp-python-exe" (list label py-exe)))
|
||||
(princ (ssg-textf "exp-calling-python" (list label)))
|
||||
;; Synchron ausfuehren und Exitcode auswerten - ein stiller
|
||||
;; Fehlschlag (z.B. WindowsApps-Platzhalter statt Interpreter)
|
||||
;; darf nicht mehr als "Export gestartet" durchgehen.
|
||||
(setq rc (export:run-python py-exe py-skript
|
||||
(list out-pfad (getenv "DXFM_DATA") ergebnis-pfad)
|
||||
log-pfad))
|
||||
(cond
|
||||
((null rc)
|
||||
(princ (ssg-textf "exp-python-call-failed" (list label))))
|
||||
((/= rc 0)
|
||||
(princ (ssg-textf "exp-python-error" (list label rc log-pfad)))
|
||||
(export:log-ausgeben log-pfad 12)
|
||||
;; Exitcode 49 (Store-Platzhalter direkt) bzw. 9009 (cmd.exe:
|
||||
;; "Befehl nicht gefunden") = kein brauchbarer Interpreter.
|
||||
;; Gezielter Hinweis, wie er korrekt gesetzt wird.
|
||||
(if (or (= rc 49) (= rc 9009)
|
||||
(export:python-store-stub-p py-exe))
|
||||
(princ (ssg-text "exp-python-store-hint"))
|
||||
))
|
||||
((not (findfile ergebnis-pfad))
|
||||
(princ (ssg-textf "exp-csv-missing" (list label ergebnis-pfad log-pfad)))
|
||||
(export:log-ausgeben log-pfad 12))
|
||||
(t
|
||||
(princ (ssg-textf "exp-export-done" (list label ergebnis-pfad))))
|
||||
)
|
||||
)
|
||||
(princ (ssg-textf "exp-python-not-found" (list label py-skript)))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; py-name = Python-Skript-Name (z.B. "export_csv.py")
|
||||
;; csv-name = Ergebnis-CSV-Name (z.B. "export.csv")
|
||||
;; include-bbox = T -> Bounding-Box je Block ermitteln und mit exportieren
|
||||
;; (siehe csv:block-to-json); fuer EXPORTSIVAS nil.
|
||||
(defun csv:run-export (label py-name csv-name include-bbox / ss i ename fh out-pfad
|
||||
first-block count out-dir sep-proxies)
|
||||
;; Zeichnungszustand fuer den Export herrichten (Proxies, IDs, Zuordnung,
|
||||
;; Attribut-Update, Sep/Scan-Zaehlung, REGENALL, bbox-Reset) - ausgelagert.
|
||||
;; Rueckgabe: die erzeugten Separator-Proxies (unten wieder zu entfernen).
|
||||
(setq sep-proxies (csv:export-vorbereiten label))
|
||||
(princ (ssg-textf "exp-collect-blocks" (list label)))
|
||||
|
||||
(setq ss (csv:collect-export-blocks))
|
||||
@@ -1350,53 +1422,8 @@
|
||||
(list (itoa *csv-bbox-fail-count*)
|
||||
(cond (*csv-bbox-fail-first*) ("?"))))))
|
||||
|
||||
;; Python-Skript aufrufen. DXFM_LIB muss gesetzt sein - fehlt es
|
||||
;; (z.B. weil BricsCAD nicht ueber bin/start_briscad.bat gestartet
|
||||
;; wurde und die Umgebungsvariablen daher nie in diesen Prozess
|
||||
;; vererbt wurden), wuerde das folgende strcat sonst mit einem
|
||||
;; kryptischen Lisp-Fehler ("bad argument type <NIL>") abbrechen.
|
||||
(if (null (getenv "DXFM_LIB"))
|
||||
(princ (ssg-textf "exp-dxfm-lib-missing" (list label)))
|
||||
(progn
|
||||
(setq py-skript (strcat (getenv "DXFM_LIB") "/" py-name))
|
||||
(if (findfile py-skript)
|
||||
(progn
|
||||
(setq ergebnis-pfad (strcat out-dir "/" (export:dwg-praefix) csv-name))
|
||||
(setq py-exe (export:python-exe))
|
||||
(setq log-pfad (strcat (cond ((getenv "DXFM_LOG")) (out-dir))
|
||||
"/export_python.log"))
|
||||
(princ (ssg-textf "exp-python-exe" (list label py-exe)))
|
||||
(princ (ssg-textf "exp-calling-python" (list label)))
|
||||
;; Synchron ausfuehren und Exitcode auswerten - ein stiller
|
||||
;; Fehlschlag (z.B. WindowsApps-Platzhalter statt Interpreter)
|
||||
;; darf nicht mehr als "Export gestartet" durchgehen.
|
||||
(setq rc (export:run-python py-exe py-skript
|
||||
(list out-pfad (getenv "DXFM_DATA") ergebnis-pfad)
|
||||
log-pfad))
|
||||
(cond
|
||||
((null rc)
|
||||
(princ (ssg-textf "exp-python-call-failed" (list label))))
|
||||
((/= rc 0)
|
||||
(princ (ssg-textf "exp-python-error" (list label rc log-pfad)))
|
||||
(export:log-ausgeben log-pfad 12)
|
||||
;; Exitcode 49 (Store-Platzhalter direkt) bzw. 9009 (cmd.exe:
|
||||
;; "Befehl nicht gefunden") = kein brauchbarer Interpreter.
|
||||
;; Gezielter Hinweis, wie er korrekt gesetzt wird.
|
||||
(if (or (= rc 49) (= rc 9009)
|
||||
(export:python-store-stub-p py-exe))
|
||||
(princ (ssg-text "exp-python-store-hint"))
|
||||
))
|
||||
((not (findfile ergebnis-pfad))
|
||||
(princ (ssg-textf "exp-csv-missing" (list label ergebnis-pfad log-pfad)))
|
||||
(export:log-ausgeben log-pfad 12))
|
||||
(t
|
||||
(princ (ssg-textf "exp-export-done" (list label ergebnis-pfad))))
|
||||
)
|
||||
)
|
||||
(princ (ssg-textf "exp-python-not-found" (list label py-skript)))
|
||||
)
|
||||
)
|
||||
)
|
||||
;; Python-Export-Skript aufrufen (ausgelagert, siehe oben).
|
||||
(csv:python-aufrufen label out-dir out-pfad py-name csv-name)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
+57
-48
@@ -5925,6 +5925,60 @@
|
||||
(vf-set-es-masse winkel seite)
|
||||
seite)
|
||||
|
||||
;; AS-Winkel (30/90) + Seite abfragen. Gemeinsame Schale fuer die frueher
|
||||
;; wortgleich in vf-linienzug-modus/-modus2/-modus3 UND vfl-qc-linie-mit-gf
|
||||
;; ausgeschriebene AS-Praeambel (Winkel-Frage 30/90, Seiten-Frage links/rechts,
|
||||
;; vf-set-as-masse) - Gegenstueck zu vfl-frage-es-seite. Setzt *vfl-as-winkel*
|
||||
;; und die AS-Masse (aus-dx/dz) fuer die Variante. Rueckgabe: Seite (links/rechts).
|
||||
;;
|
||||
;; seiten-headerkey ist der EINZIGE Unterschied zwischen den Aufrufstellen
|
||||
;; (modus1: "vfl-aus-seite-header", modus2: "gf-seite-aus-header") und daher
|
||||
;; Parameter. Die je Modus unterschiedliche VORANGEHENDE Wizard-Vorbereitung
|
||||
;; (vflw-gruppe-as-impl "AS setzen?" bzw. vflw-gruppe-winkel-seite-impl) bleibt
|
||||
;; bewusst an der Aufrufstelle - die abzudeckende Winkel/Seite-Frage selbst ist
|
||||
;; ueberall identisch. vf-frage-element-winkel/vflw-wahl zeigen den Wizard-
|
||||
;; Winkeldialog bei aktivem Wizard-Modus schon selbst.
|
||||
(defun vfl-frage-as-winkel-seite (seiten-headerkey / antwort as-seite)
|
||||
(princ (ssg-text "vf-winkel-aus-header"))
|
||||
(princ (ssg-text "vf-winkel-90"))
|
||||
(princ (ssg-text "vf-winkel-30"))
|
||||
(setq *vfl-as-winkel*
|
||||
(vfl-in-value "STR"
|
||||
(function (lambda () (vf-frage-element-winkel "vf-winkel-aus-header"))))) ; 30/90 vor Seite
|
||||
(princ (ssg-text seiten-headerkey))
|
||||
(princ (ssg-text "gf-seite-links"))
|
||||
(princ (ssg-text "gf-seite-rechts"))
|
||||
(setq antwort (vfl-menu (ssg-text "prompt-wahl-1-2")
|
||||
(list (ssg-text "gf-seite-links") (ssg-text "gf-seite-rechts")) 1
|
||||
seiten-headerkey))
|
||||
(setq as-seite (if (= antwort "2") "rechts" "links"))
|
||||
(vf-set-as-masse *vfl-as-winkel* as-seite) ; Masse fuer Variante
|
||||
as-seite)
|
||||
|
||||
;; ES-Winkel (30/90) + Seite abfragen - MARKER-FREIE Schale fuer die Modi 2/3,
|
||||
;; die das ES-Element als eigene Praeambel (Start/Ziel bereits fest) abfragen
|
||||
;; und ihr eigenes Journal-/Masse-Schema fuehren. Unterscheidet sich bewusst
|
||||
;; von vfl-frage-es-seite (Modus 1), das zusaetzlich einen Journal-Marker "ES"
|
||||
;; setzt und ueber vfl-es-masse-setzen laeuft - das ist Teil des Modus-1-
|
||||
;; Kettenglied-Replays und darf hier NICHT feuern. Setzt *vfl-es-winkel* und
|
||||
;; die ES-Masse (ein-dx/dz). Rueckgabe: Seite (links/rechts).
|
||||
(defun vfl-frage-es-winkel-seite (seiten-headerkey / antwort es-seite)
|
||||
(princ (ssg-text "vf-winkel-ein-header"))
|
||||
(princ (ssg-text "vf-winkel-90"))
|
||||
(princ (ssg-text "vf-winkel-30"))
|
||||
(setq *vfl-es-winkel*
|
||||
(vfl-in-value "STR"
|
||||
(function (lambda () (vf-frage-element-winkel "vf-winkel-ein-header"))))) ; 30/90 vor Seite
|
||||
(princ (ssg-text seiten-headerkey))
|
||||
(princ (ssg-text "gf-seite-links"))
|
||||
(princ (ssg-text "gf-seite-rechts"))
|
||||
(setq antwort (vfl-menu (ssg-text "prompt-wahl-1-2")
|
||||
(list (ssg-text "gf-seite-links") (ssg-text "gf-seite-rechts")) 1
|
||||
seiten-headerkey))
|
||||
(setq es-seite (if (= antwort "2") "rechts" "links"))
|
||||
(vf-set-es-masse *vfl-es-winkel* es-seite) ; Masse fuer Variante
|
||||
es-seite)
|
||||
|
||||
;; dialog-schon-gezeigt: T, wenn Winkel+Seite BEREITS ueber einen vorherigen
|
||||
;; kombinierten Dialog (vflw-gruppe-as-impl, "ES-Element setzen?" + Winkel +
|
||||
;; Seite in einem Bildschirm) abgefragt und in die Pending-Queue gelegt
|
||||
@@ -6372,22 +6426,7 @@
|
||||
;; tragen, wenn diesmal kein AS gewaehlt wird.
|
||||
(setq *vfl-as-winkel* nil *vfl-es-winkel* nil)
|
||||
(if as-vorhanden
|
||||
(progn
|
||||
(princ (ssg-text "vf-winkel-aus-header"))
|
||||
(princ (ssg-text "vf-winkel-90"))
|
||||
(princ (ssg-text "vf-winkel-30"))
|
||||
(setq *vfl-as-winkel*
|
||||
(vfl-in-value "STR"
|
||||
(function (lambda () (vf-frage-element-winkel "vf-winkel-aus-header"))))) ; 30/90 vor Seite
|
||||
(princ (ssg-text "vfl-aus-seite-header"))
|
||||
(princ (ssg-text "gf-seite-links"))
|
||||
(princ (ssg-text "gf-seite-rechts"))
|
||||
(setq antwort (vfl-menu (ssg-text "prompt-wahl-1-2")
|
||||
(list (ssg-text "gf-seite-links") (ssg-text "gf-seite-rechts")) 1
|
||||
"vfl-aus-seite-header"))
|
||||
(setq as-seite (if (= antwort "2") "rechts" "links"))
|
||||
(vf-set-as-masse *vfl-as-winkel* as-seite) ; Masse fuer Variante
|
||||
)
|
||||
(setq as-seite (vfl-frage-as-winkel-seite "vfl-aus-seite-header"))
|
||||
)
|
||||
;; ES-Seite wird erst am Kettenende abgefragt (siehe vfl-frage-es-seite),
|
||||
;; da das ES-Element erst dort eingefuegt wird.
|
||||
@@ -9231,22 +9270,7 @@
|
||||
;; Globals pro Lauf zuruecksetzen (siehe Kommentar in vf-linienzug-modus).
|
||||
(setq *vfl-as-winkel* nil *vfl-es-winkel* nil)
|
||||
(if as-vorhanden
|
||||
(progn
|
||||
(princ (ssg-text "vf-winkel-aus-header"))
|
||||
(princ (ssg-text "vf-winkel-90"))
|
||||
(princ (ssg-text "vf-winkel-30"))
|
||||
(setq *vfl-as-winkel*
|
||||
(vfl-in-value "STR"
|
||||
(function (lambda () (vf-frage-element-winkel "vf-winkel-aus-header"))))) ; 30/90 vor Seite
|
||||
(princ (ssg-text "gf-seite-aus-header"))
|
||||
(princ (ssg-text "gf-seite-links"))
|
||||
(princ (ssg-text "gf-seite-rechts"))
|
||||
(setq antwort (vfl-menu (ssg-text "prompt-wahl-1-2")
|
||||
(list (ssg-text "gf-seite-links") (ssg-text "gf-seite-rechts")) 1
|
||||
"gf-seite-aus-header"))
|
||||
(setq as-seite (if (= antwort "2") "rechts" "links"))
|
||||
(vf-set-as-masse *vfl-as-winkel* as-seite) ; Masse fuer Variante
|
||||
)
|
||||
(setq as-seite (vfl-frage-as-winkel-seite "gf-seite-aus-header"))
|
||||
)
|
||||
|
||||
;; --- 3. Endpunkt + Z + ES-Seite (NEU in Modus 3) ---
|
||||
@@ -9269,22 +9293,7 @@
|
||||
"vfl-es-setzen-frage"))
|
||||
(setq es-vorhanden (/= antwort "2"))
|
||||
(if es-vorhanden
|
||||
(progn
|
||||
(princ (ssg-text "vf-winkel-ein-header"))
|
||||
(princ (ssg-text "vf-winkel-90"))
|
||||
(princ (ssg-text "vf-winkel-30"))
|
||||
(setq *vfl-es-winkel*
|
||||
(vfl-in-value "STR"
|
||||
(function (lambda () (vf-frage-element-winkel "vf-winkel-ein-header"))))) ; 30/90 vor Seite
|
||||
(princ (ssg-text "gf-seite-ein-header"))
|
||||
(princ (ssg-text "gf-seite-links"))
|
||||
(princ (ssg-text "gf-seite-rechts"))
|
||||
(setq antwort (vfl-menu (ssg-text "prompt-wahl-1-2")
|
||||
(list (ssg-text "gf-seite-links") (ssg-text "gf-seite-rechts")) 1
|
||||
"gf-seite-ein-header"))
|
||||
(setq es-seite (if (= antwort "2") "rechts" "links"))
|
||||
(vf-set-es-masse *vfl-es-winkel* es-seite) ; Masse fuer Variante
|
||||
)
|
||||
(setq es-seite (vfl-frage-es-winkel-seite "gf-seite-ein-header"))
|
||||
)
|
||||
|
||||
;; --- 4. Sortieren + Analysieren + Eck-Vorpruefung ---
|
||||
|
||||
Reference in New Issue
Block a user