diff --git a/Lisp/vf_core.lsp b/Lisp/vf_core.lsp index b17af32..7bdc3d6 100644 --- a/Lisp/vf_core.lsp +++ b/Lisp/vf_core.lsp @@ -862,74 +862,87 @@ ent ) +;; --- Gemeinsamer VF_n-Wrapper-Rumpf (Standard/Etage UND Linienzug) ---------- +;; Der frueher in vf-block-erstellen (vf_core) und vfl-block-erstellen +;; (vf_linienzug) wortgleiche Rumpf: unsichtbare ATTDEFs am Startpunkt nach dem +;; gemeinsamen Strecken-Schema erzeugen, alle seit lastEnt neu entstandenen +;; Entities einsammeln, die Sepliste sichern, per ssg-block-wrap-welt zu einem +;; Block VF_n wickeln, auf den Baugruppen-Layer legen, Sepliste-XDATA + die +;; uebergebene Attributliste + ID + Dimensions-XDATA schreiben. +;; +;; typ-str = "Streckengruppe"/"Gefaellestrecke" (steuert nur ssg-strecke-attrib- +;; defs, das Attribut-Schema). attrib-liste = FERTIGE (tag . wert)-Liste, die +;; der Aufrufer baut (feste Werte bei Standard/Etage, *vfl-acc-*-Komma-Listen +;; beim Linienzug) - der gemeinsame Rumpf kennt die Semantik NICHT. +;; ATTDEF-Format: kanonisch (wie vfl-block-erstellen/Gefaellestrecke/ +;; Vario_Kette_Merge - 3 von 4 Bauern nutzten es schon; vf-block-erstellen war +;; der Ausreisser mit Layer-0/Model-Space-Zwang + y-Dekrementierung ohne +;; belegbaren Zweck bei unsichtbaren ATTDEFs). +;; Rueckgabe: die Block-Referenz (vf-insert) oder nil, wenn seit lastEnt nichts +;; entstand (Leere-Menge-Schutz, frueher nur in vf-block-erstellen). +(defun vf-wrapper-bauen (vf-nummer typ-str startpunkt lastEnt attrib-liste + / vf-bname vf-ss vf-e vf-insert vf-sepliste) + (setq vf-bname (strcat "VF_" (itoa vf-nummer))) + ;; Unsichtbare ATTDEFs (kanonisches Format) am Startpunkt. + (foreach def (ssg-strecke-attrib-defs typ-str) + (entmake + (list '(0 . "ATTDEF") + (cons 10 startpunkt) + (cons 11 startpunkt) + (cons 40 *vfk-attdef-texthoehe*) + (cons 1 (cadr def)) + (cons 2 (car def)) + (cons 3 (car def)) + '(70 . 1) + '(72 . 0) + '(74 . 0))) + ) + ;; Alle neuen Entities seit lastEnt sammeln. + (setq vf-ss (ssadd)) + (setq vf-e (if lastEnt (entnext lastEnt) (entnext))) + (while vf-e (ssadd vf-e vf-ss) (setq vf-e (entnext vf-e))) + ;; Sepliste VOR dem Sweep sichern (danach existieren die Sub-Entities nicht + ;; mehr einzeln). + (setq vf-sepliste (ssg-sepliste-sammeln lastEnt)) + (if (> (sslength vf-ss) 0) + (progn + (setq vf-insert (ssg-block-wrap-welt vf-bname startpunkt vf-ss)) + (ssg-layer-setzen vf-insert "variofoerderer") + (ssg-sepliste-xdata-schreiben vf-insert "SSG_VF_SEP" vf-sepliste) + (ssg-attrib-set-on vf-insert attrib-liste) + (if (car (atoms-family 1 '("SSG-ID-GENERATE"))) + (ssg-id-generate vf-insert)) + (if (car (atoms-family 1 '("SSG-DIM-XDATA-SCHREIBEN"))) + (ssg-dim-xdata-schreiben vf-insert (ssg-ils-dim-aktuell))) + vf-insert) + (progn (princ (ssg-text "vfc-fehler-keine-entities")) nil))) + ;; Erstellt VF_N-Block aus allen seit lastEnt erzeugten Entities. ;; Setzt Attributwerte entsprechend Typ, Seite und Geometrieparametern. (defun vf-block-erstellen (anlage-typ seite vf-nummer n-scanner hoehe-von hoehe-bis deltaH deltaL L_VF L_GF1 L_GF2 richtung best-winkel startpunkt lastEnt hz geruest-einzelmodul geruest-typ - / vf-bname vf-ss vf-e vf-insert montagehoehe-m attdef-ypos L_GF_m-str - vf-sepliste) + / vf-insert montagehoehe-m L_GF_m-str) (if (null hz) (setq hz 0.0)) (if (null geruest-einzelmodul) (setq geruest-einzelmodul "1")) (if (null geruest-typ) (setq geruest-typ (ssg-geruest-idx-to-typ (ssg-geruest-typ-to-idx nil)))) - ;; Beschriftungstext erzeugen + ;; Beschriftungstext erzeugen (VOR dem Wrapper-Bau, damit er mit eingesammelt + ;; wird - Standard/Etage-spezifisch, der Linienzug hat kein solches Label). (vf-make-label vf-nummer hoehe-von hoehe-bis deltaH deltaL L_VF L_GF1 L_GF2 richtung best-winkel 2 n-scanner startpunkt hz) - - ;; Unsichtbare ATTDEFs am Startpunkt erzeugen (gemeinsames Strecken-Schema; - ;; VarioFoerderer ist immer TYP "Streckengruppe" -> voller Attributsatz). - (setq attdef-ypos (cadr startpunkt)) - (foreach def (ssg-strecke-attrib-defs "Streckengruppe") - (entmake (list - '(0 . "ATTDEF") - '(8 . "0") - '(67 . 0) - (cons 10 (list (car startpunkt) attdef-ypos (caddr startpunkt))) - (cons 40 *vfk-attdef-texthoehe*) - (cons 1 (cadr def)) - (cons 3 (car def)) - (cons 2 (car def)) - '(70 . 1) - )) - (setq attdef-ypos (- attdef-ypos *vfk-attdef-zeilenabstand*)) - ) - - ;; Alle neuen Entities seit lastEnt sammeln - (setq vf-ss (ssadd)) - (if lastEnt - (setq vf-e (entnext lastEnt)) - (setq vf-e (entnext)) - ) - (while vf-e - (ssadd vf-e vf-ss) - (setq vf-e (entnext vf-e)) - ) - - ;; Sepliste (Separator/AS/ES-Reihenfolge, siehe ssg_ks_insert.lsp) VOR dem - ;; Sweep sammeln - danach existieren die Sub-Entities nicht mehr einzeln. - (setq vf-sepliste (ssg-sepliste-sammeln lastEnt)) - - ;; Block erstellen, einfuegen, Attribute setzen - (setq vf-bname (strcat "VF_" (itoa vf-nummer))) - (if (> (sslength vf-ss) 0) - (progn - ;; Block definieren und einfuegen mit garantiert weltparallelem BKS. - ;; startpunkt ist ein Welt-Punkt; ssg-block-wrap-welt setzt das BKS - ;; temporaer auf Welt (verhindert den 31.95mm-Z-Versatz bei - ;; abweichendem BKS) und stellt es danach wieder her. - (setq vf-insert (ssg-block-wrap-welt vf-bname startpunkt vf-ss)) - ;; Ziel-Layer der Baugruppe aus cfg/layer.cfg (ohne Eintrag bleibt die - ;; Referenz auf dem aktuellen Layer, wie vor der Umstellung). - (ssg-layer-setzen vf-insert "variofoerderer") - (ssg-sepliste-xdata-schreiben vf-insert "SSG_VF_SEP" vf-sepliste) - (setq montagehoehe-m (/ (+ hoehe-von hoehe-bis) 2000.0)) - ;; L_GF_m: kommagetrennte Segmentlaengen in Metern (vorne,hinten), - ;; analog L_GF_m in Gefaellestrecke.lsp. - (setq L_GF_m-str (strcat (rtos (/ L_GF1 1000.0) 2 3) "," (rtos (/ L_GF2 1000.0) 2 3))) - (ssg-attrib-set-on vf-insert + (setq montagehoehe-m (/ (+ hoehe-von hoehe-bis) 2000.0)) + ;; L_GF_m: kommagetrennte Segmentlaengen in Metern (vorne,hinten), + ;; analog L_GF_m in Gefaellestrecke.lsp. + (setq L_GF_m-str (strcat (rtos (/ L_GF1 1000.0) 2 3) "," (rtos (/ L_GF2 1000.0) 2 3))) + ;; Standard/Etage-Attributsatz (feste Werte). VarioFoerderer ist immer TYP + ;; "Streckengruppe" -> voller Attributsatz. Etage-Sonderfall (2x Gefaellebogen + ;; je Seite) direkt in die Liste, statt als zweiter ssg-attrib-set-on-Aufruf. + (setq vf-insert + (vf-wrapper-bauen vf-nummer "Streckengruppe" startpunkt lastEnt + (append (list - (cons "Bezeichnung" vf-bname) + (cons "Bezeichnung" (strcat "VF_" (itoa vf-nummer))) ;; ARTINR bleibt auf Schema-Vorgabe "6220" (cons "MONTAGEHOEHE_m" (rtos montagehoehe-m 2 3)) (cons "HOEHE_VON_mm" (itoa (fix hoehe-von))) @@ -954,27 +967,16 @@ (cons "ANZAHL_SEPARATOR" "2") (cons "ANZAHL_SCANNER" (itoa n-scanner)) (cons "GERUEST_EINZELMODUL" geruest-einzelmodul) - (cons "GERUEST_TYP" geruest-typ) - ) - ) - ;; Typ-spezifische Bogen-Zaehler (Etage: 2x Gefaellebogen je Seite) - (if (= anlage-typ "etage") - (if (= seite "rechts") - (ssg-attrib-set-on vf-insert (list (cons "GF_Bogen_R_60" "2"))) - (ssg-attrib-set-on vf-insert (list (cons "GF_Bogen_L_60" "2"))) - ) - ) - ;; Aufsteigende, eindeutige ID vergeben (wie beim Kreisel), falls verfuegbar. - (if (car (atoms-family 1 '("SSG-ID-GENERATE"))) - (ssg-id-generate vf-insert)) - ;; Dimension (2D/3D) merken -> Doppelklick-Edit erkennt sie automatisch. - (if (car (atoms-family 1 '("SSG-DIM-XDATA-SCHREIBEN"))) - (ssg-dim-xdata-schreiben vf-insert (ssg-ils-dim-aktuell))) - (princ (ssg-textf "vfc-block-erstellt-eingefuegt" (list vf-bname))) - vf-insert - ) - (progn (princ (ssg-text "vfc-fehler-keine-entities")) nil) - ) + (cons "GERUEST_TYP" geruest-typ)) + ;; Typ-spezifische Bogen-Zaehler (Etage: 2x Gefaellebogen je Seite) + (if (= anlage-typ "etage") + (if (= seite "rechts") + (list (cons "GF_Bogen_R_60" "2")) + (list (cons "GF_Bogen_L_60" "2"))) + '())))) + (if vf-insert + (princ (ssg-textf "vfc-block-erstellt-eingefuegt" (list (strcat "VF_" (itoa vf-nummer)))))) + vf-insert ) ;; ============================================================ diff --git a/Lisp/vf_konstanten.lsp b/Lisp/vf_konstanten.lsp index a2c1811..52fbacc 100644 --- a/Lisp/vf_konstanten.lsp +++ b/Lisp/vf_konstanten.lsp @@ -238,13 +238,13 @@ ;; vf_core.lsp). Aktiv referenziert. (if (null *vfk-label-texthoehe*) (setq *vfk-label-texthoehe* 100.0)) -;; Texthoehe (mm) der unsichtbaren ATTDEFs (vf-block-erstellen, -;; vf_core.lsp). Aktiv referenziert. +;; Texthoehe (mm) der unsichtbaren ATTDEFs (vf-wrapper-bauen, vf_core.lsp - +;; gemeinsamer Wrapper-Rumpf fuer Standard/Etage UND Linienzug). Aktiv referenziert. (if (null *vfk-attdef-texthoehe*) (setq *vfk-attdef-texthoehe* 50.0)) - -;; Y-Versatz (mm) zwischen aufeinanderfolgenden ATTDEF-Zeilen -;; (vf_core.lsp). Aktiv referenziert. -(if (null *vfk-attdef-zeilenabstand*) (setq *vfk-attdef-zeilenabstand* 100.0)) +;; (*vfk-attdef-zeilenabstand* entfernt 2026-09-18: die einzige Nutzung war die +;; y-Dekrementierung der ATTDEF-Zeilen im alten vf-block-erstellen - historischer +;; Drift ohne Effekt bei unsichtbaren ATTDEFs; der kanonische Wrapper setzt alle +;; ATTDEFs an denselben Startpunkt.) ;; Beschriftungsversatz (mm) senkrecht zur Fahrtrichtung (vf-make-label, ;; vf_core.lsp). Aktiv referenziert. diff --git a/Lisp/vf_linienzug.lsp b/Lisp/vf_linienzug.lsp index 1cef46b..447fffa 100644 --- a/Lisp/vf_linienzug.lsp +++ b/Lisp/vf_linienzug.lsp @@ -6231,7 +6231,7 @@ ;; ============================================================ (defun vfl-block-erstellen (vfl-nummer anzahl-gf anzahl-vf hoehe-von hoehe-bis delta-l-total as-seite es-seite startpunkt lastEnt / - vfl-bname vfl-ss ent vfl-insert typ-str vfl-sepliste) + vfl-bname vfl-insert typ-str) ;; TYP: einsegmentige Gefaellestrecke ohne Bogen -> "Gefaellestrecke"; ;; mit VF, Bogen oder mehreren GF-Segmenten -> "Streckengruppe". (setq typ-str @@ -6242,90 +6242,49 @@ "Streckengruppe" "Gefaellestrecke")) (setq vfl-bname (strcat "VF_" (itoa vfl-nummer))) - ;; ATTDEFs nach gemeinsamem Strecken-Schema (Reihenfolge!) - (foreach def (ssg-strecke-attrib-defs typ-str) - (entmake - (list '(0 . "ATTDEF") - (cons 10 startpunkt) - (cons 11 startpunkt) - '(40 . 50.0) - (cons 1 (cadr def)) - (cons 2 (car def)) - (cons 3 (car def)) - '(70 . 1) - '(72 . 0) - '(74 . 0))) - ) - (setq vfl-ss (ssadd)) - (setq ent (if lastEnt (entnext lastEnt) (entnext))) - (while ent - (ssadd ent vfl-ss) - (setq ent (entnext ent)) - ) - ;; Sepliste (Separator/AS/ES-Reihenfolge, siehe ssg_ks_insert.lsp) VOR dem - ;; Sweep sammeln - danach existieren die Sub-Entities nicht mehr einzeln. - (setq vfl-sepliste (ssg-sepliste-sammeln lastEnt)) - ;; Block definieren und einfuegen mit garantiert weltparallelem BKS. - ;; startpunkt ist ein Welt-Punkt; ssg-block-wrap-welt setzt das BKS - ;; temporaer auf Welt (verhindert den 31.95mm-Z-Versatz bei abweichendem - ;; BKS, siehe Kommentar dort) und stellt es danach wieder her. - (setq vfl-insert (ssg-block-wrap-welt vfl-bname startpunkt vfl-ss)) - ;; Ziel-Layer der Baugruppe aus cfg/layer.cfg (ohne Eintrag bleibt die - ;; Referenz auf dem aktuellen Layer, wie vor der Umstellung). - (ssg-layer-setzen vfl-insert "variofoerderer") - (ssg-sepliste-xdata-schreiben vfl-insert "SSG_VF_SEP" vfl-sepliste) - ;; Werte (volle Liste; nicht vorhandene Tags ignoriert ssg-attrib-set-on) - (ssg-attrib-set-on vfl-insert - (list - (cons "Bezeichnung" vfl-bname) - (cons "MONTAGEHOEHE_m" (rtos (/ (+ hoehe-von hoehe-bis) 2000.0) 2 3)) - (cons "HOEHE_VON_mm" (itoa (fix hoehe-von))) - (cons "HOEHE_BIS_mm" (itoa (fix hoehe-bis))) - (cons "DELTA_H_mm" (itoa (fix (abs (- hoehe-bis hoehe-von))))) - (cons "DELTA_L_mm" (itoa (fix delta-l-total))) - (cons "TYP" typ-str) - (cons "SEITE_AS" as-seite) - (cons "WINKEL_AS" (if (boundp '*vfl-as-winkel*) *vfl-as-winkel* "")) - (cons "SEITE_ES" es-seite) - (cons "WINKEL_ES" (if (boundp '*vfl-es-winkel*) *vfl-es-winkel* "")) - ;; ANZAHL_GF = alle GF-Stuecke: eigenstaendige GF-Segmente UND die GF1/GF2 - ;; jeder VF-Einheit (alle ueber vfl-acc-gf-seg in *vfl-acc-lgf* gesammelt). - (cons "ANZAHL_GF" (itoa (length *vfl-acc-lgf*))) - (cons "L_GF_m" (vfl-join-komma *vfl-acc-lgf*)) - (cons "GF_WINKEL" (vfl-join-komma *vfl-acc-gfwinkel*)) - ;; GF-Boegen (Richtungswechsel im GF-Teil), gezaehlt nach Seite+Winkel - (cons "GF_Bogen_L_90" (itoa (vfl-get-count *vfl-acc-gfbogen* "L_90"))) - (cons "GF_Bogen_L_60" (itoa (vfl-get-count *vfl-acc-gfbogen* "L_60"))) - (cons "GF_Bogen_L_30" (itoa (vfl-get-count *vfl-acc-gfbogen* "L_30"))) - (cons "GF_Bogen_R_90" (itoa (vfl-get-count *vfl-acc-gfbogen* "R_90"))) - (cons "GF_Bogen_R_60" (itoa (vfl-get-count *vfl-acc-gfbogen* "R_60"))) - (cons "GF_Bogen_R_30" (itoa (vfl-get-count *vfl-acc-gfbogen* "R_30"))) - (cons "ANZAHL_VF" (itoa anzahl-vf)) - (cons "MOTORSEITE" (vfl-join-komma *vfl-acc-motorseite*)) - (cons "L_VF_m" (vfl-join-komma *vfl-acc-lvf*)) - (cons "ANTRIEBFAHRTRICHTUNG" (vfl-join-komma *vfl-acc-richtung*)) - (cons "VF_WINKEL" (vfl-join-komma *vfl-acc-winkel*)) - ;; Vario-Kurven (Richtungswechsel im VF-Teil), A=aussen / I=innen - (cons "VF_Bogen_A_90" (itoa (vfl-get-count *vfl-acc-variokurve* "A_90"))) - (cons "VF_Bogen_A_60" (itoa (vfl-get-count *vfl-acc-variokurve* "A_60"))) - (cons "VF_Bogen_A_30" (itoa (vfl-get-count *vfl-acc-variokurve* "A_30"))) - (cons "VF_Bogen_I_90" (itoa (vfl-get-count *vfl-acc-variokurve* "I_90"))) - (cons "VF_Bogen_I_60" (itoa (vfl-get-count *vfl-acc-variokurve* "I_60"))) - (cons "VF_Bogen_I_30" (itoa (vfl-get-count *vfl-acc-variokurve* "I_30"))) - (cons "ANZAHL_SEPARATOR" (itoa *vfl-acc-separator*)) - ) - ) - ;; Aufsteigende, eindeutige ID vergeben (wie beim Kreisel), falls verfuegbar. - (if (car (atoms-family 1 '("SSG-ID-GENERATE"))) - (ssg-id-generate vfl-insert)) - ;; Dimension (2D/3D), in der gebaut wurde, als eigenes SSG_DIM-XDATA merken - ;; (analog vf-block-erstellen). Deckt alle Bau-Pfade ab, da Modus 1/2/3 UND - ;; die Abbruch-Sicherung ueber vfl-block-erstellen laufen. Erst dadurch kann - ;; die Batch-Umschaltung (ssg-dim-alle-umwandeln) Linienzug-Bloecke korrekt - ;; als 2D bzw. 3D erkennen statt sie pauschal als "3D" zu behandeln. - (if (and vfl-insert (car (atoms-family 1 '("SSG-DIM-XDATA-SCHREIBEN")))) - (ssg-dim-xdata-schreiben vfl-insert (ssg-ils-dim-aktuell))) - (princ (ssg-textf "vfl-block-erstellt" (list vfl-bname typ-str))) + ;; Gemeinsamer Wrapper-Rumpf (ATTDEF/Sweep/Sepliste/Wrap/Layer/ID/Dim, siehe + ;; vf-wrapper-bauen in vf_core). Die *vfl-acc-*-Attributliste baut hier der + ;; Aufrufer (linienzug-spezifische Komma-Listen), der Rumpf kennt sie nicht. + (setq vfl-insert + (vf-wrapper-bauen vfl-nummer typ-str startpunkt lastEnt + (list + (cons "Bezeichnung" vfl-bname) + (cons "MONTAGEHOEHE_m" (rtos (/ (+ hoehe-von hoehe-bis) 2000.0) 2 3)) + (cons "HOEHE_VON_mm" (itoa (fix hoehe-von))) + (cons "HOEHE_BIS_mm" (itoa (fix hoehe-bis))) + (cons "DELTA_H_mm" (itoa (fix (abs (- hoehe-bis hoehe-von))))) + (cons "DELTA_L_mm" (itoa (fix delta-l-total))) + (cons "TYP" typ-str) + (cons "SEITE_AS" as-seite) + (cons "WINKEL_AS" (if (boundp '*vfl-as-winkel*) *vfl-as-winkel* "")) + (cons "SEITE_ES" es-seite) + (cons "WINKEL_ES" (if (boundp '*vfl-es-winkel*) *vfl-es-winkel* "")) + ;; ANZAHL_GF = alle GF-Stuecke: eigenstaendige GF-Segmente UND die GF1/GF2 + ;; jeder VF-Einheit (alle ueber vfl-acc-gf-seg in *vfl-acc-lgf* gesammelt). + (cons "ANZAHL_GF" (itoa (length *vfl-acc-lgf*))) + (cons "L_GF_m" (vfl-join-komma *vfl-acc-lgf*)) + (cons "GF_WINKEL" (vfl-join-komma *vfl-acc-gfwinkel*)) + ;; GF-Boegen (Richtungswechsel im GF-Teil), gezaehlt nach Seite+Winkel + (cons "GF_Bogen_L_90" (itoa (vfl-get-count *vfl-acc-gfbogen* "L_90"))) + (cons "GF_Bogen_L_60" (itoa (vfl-get-count *vfl-acc-gfbogen* "L_60"))) + (cons "GF_Bogen_L_30" (itoa (vfl-get-count *vfl-acc-gfbogen* "L_30"))) + (cons "GF_Bogen_R_90" (itoa (vfl-get-count *vfl-acc-gfbogen* "R_90"))) + (cons "GF_Bogen_R_60" (itoa (vfl-get-count *vfl-acc-gfbogen* "R_60"))) + (cons "GF_Bogen_R_30" (itoa (vfl-get-count *vfl-acc-gfbogen* "R_30"))) + (cons "ANZAHL_VF" (itoa anzahl-vf)) + (cons "MOTORSEITE" (vfl-join-komma *vfl-acc-motorseite*)) + (cons "L_VF_m" (vfl-join-komma *vfl-acc-lvf*)) + (cons "ANTRIEBFAHRTRICHTUNG" (vfl-join-komma *vfl-acc-richtung*)) + (cons "VF_WINKEL" (vfl-join-komma *vfl-acc-winkel*)) + ;; Vario-Kurven (Richtungswechsel im VF-Teil), A=aussen / I=innen + (cons "VF_Bogen_A_90" (itoa (vfl-get-count *vfl-acc-variokurve* "A_90"))) + (cons "VF_Bogen_A_60" (itoa (vfl-get-count *vfl-acc-variokurve* "A_60"))) + (cons "VF_Bogen_A_30" (itoa (vfl-get-count *vfl-acc-variokurve* "A_30"))) + (cons "VF_Bogen_I_90" (itoa (vfl-get-count *vfl-acc-variokurve* "I_90"))) + (cons "VF_Bogen_I_60" (itoa (vfl-get-count *vfl-acc-variokurve* "I_60"))) + (cons "VF_Bogen_I_30" (itoa (vfl-get-count *vfl-acc-variokurve* "I_30"))) + (cons "ANZAHL_SEPARATOR" (itoa *vfl-acc-separator*))))) + (if vfl-insert (princ (ssg-textf "vfl-block-erstellt" (list vfl-bname typ-str)))) vfl-insert )