This commit is contained in:
2026-07-22 12:48:12 +02:00
8 changed files with 188 additions and 84 deletions
+8 -1
View File
@@ -2089,6 +2089,10 @@
hoehe-bis)) hoehe-bis))
(setq hz-vf (rem (+ hz 180.0) 360.0)) (setq hz-vf (rem (+ hz 180.0) 360.0))
(setq vf-seite as-seite) ; VF-AS/ES-Seite: Default = GF-AS-Seite (setq vf-seite as-seite) ; VF-AS/ES-Seite: Default = GF-AS-Seite
(princ (strcat "\n[DEBUG-VFPAR] GF-hz=" (rtos hz 2 1) " -> VF-hz=" (rtos hz-vf 2 1)
" | as-seite=" as-seite
" | gf-start=" (vl-princ-to-string gf-start)
" | vf-start=" (vl-princ-to-string vf-start)))
(vfs-standard-dialog-berechnen-einfuegen (vfs-standard-dialog-berechnen-einfuegen
(vf-next-number) deltaL deltaH "Auf" vf-start hz-vf vf-seite nil) (vf-next-number) deltaL deltaH "Auf" vf-start hz-vf vf-seite nil)
(princ (ssg-text "gf-vf-gebaut")) (princ (ssg-text "gf-vf-gebaut"))
@@ -2171,7 +2175,10 @@
(setq as-seite (cond ((cdr (assoc "SEITE_AS" attribs))) ("links"))) (setq as-seite (cond ((cdr (assoc "SEITE_AS" attribs))) ("links")))
(setq hoehe-bis (atof (cond ((cdr (assoc "HOEHE_BIS_mm" attribs))) ("0")))) (setq hoehe-bis (atof (cond ((cdr (assoc "HOEHE_BIS_mm" attribs))) ("0"))))
(setq dlg-werte (gf-dialog-eingabe prefill)) ;; 2. Argument (hoehe-vorbelegung) explizit nil: BricsCAD verlangt die exakte
;; Argumentzahl (setzt fehlende NICHT automatisch auf nil). Im Edit kommt die
;; Einfuegehoehe aus prefill, keine separate Punkt-Vorbelegung noetig.
(setq dlg-werte (gf-dialog-eingabe prefill nil))
(cond (cond
((null dlg-werte) ((null dlg-werte)
(princ (ssg-text "gf-status-abgebrochen"))) (princ (ssg-text "gf-status-abgebrochen")))
+10 -3
View File
@@ -72,13 +72,13 @@
;; Attribut-Definitionen: ((TAG DEFAULT) ...) ;; Attribut-Definitionen: ((TAG DEFAULT) ...)
;; Anzeige-/Attributreihenfolge im Block (ID zuerst, dann Bezeichnung, ;; Anzeige-/Attributreihenfolge im Block (ID zuerst, dann Bezeichnung,
;; Artinr. fest 6200, Montage-/Hoehendaten, dann Ausstattung). ;; ARTINR fest 6200, Montage-/Hoehendaten, dann Ausstattung).
;; NUMMER steht am Ende (wird intern fuer Nummerierung/Blockname ;; NUMMER steht am Ende (wird intern fuer Nummerierung/Blockname
;; benoetigt; Entfernen erfordert Refactor der Nummernvergabe). ;; benoetigt; Entfernen erfordert Refactor der Nummernvergabe).
(setq *kreisel-attrib-defs* (setq *kreisel-attrib-defs*
'(("ID" "") '(("ID" "")
("Bezeichnung" "") ("Bezeichnung" "")
("Artinr." "6200") ("ARTINR" "6200")
("MONTAGEHOEHE_m" "0.000") ("MONTAGEHOEHE_m" "0.000")
("HOEHE" "0") ("HOEHE" "0")
("KREISELART" "STANDARD") ("KREISELART" "STANDARD")
@@ -86,6 +86,7 @@
("ANZAHL_SEPARATOR" "2") ("ANZAHL_SEPARATOR" "2")
("ANZAHL_SCANNER" "0") ("ANZAHL_SCANNER" "0")
("ANZAHL_RAMPEN" "0") ("ANZAHL_RAMPEN" "0")
("GERUEST_EINZELMODUL" "0")
("DREHRICHTUNG" "UZS") ("DREHRICHTUNG" "UZS")
("DREHUNG" "0") ("DREHUNG" "0")
("NUMMER" "0")) ("NUMMER" "0"))
@@ -867,7 +868,7 @@
(defun c:KreiselEdit ( / sel ss ent ed attribs basePoint rotation (defun c:KreiselEdit ( / sel ss ent ed attribs basePoint rotation
dcl-pfad dat ergebnis dcl-pfad dat ergebnis
dlg-name dlg-abstand dlg-hoehe dlg-ausrichtung dlg-name dlg-abstand dlg-hoehe dlg-ausrichtung
dlg-drehrichtung dlg-kreiselart dlg-drehrichtung dlg-kreiselart dlg-geruest-einzelmodul
newAbstand newRotation ausrichtLabels) newAbstand newRotation ausrichtLabels)
;; Implied Selection VOR ssg-start pruefen (ssg-start hebt Selektion auf) ;; Implied Selection VOR ssg-start pruefen (ssg-start hebt Selektion auf)
@@ -962,6 +963,9 @@
(end_list) (end_list)
(set_tile "kreiselart" (if (equal (cdr (assoc "KREISELART" attribs)) "PIN") "1" "0")) (set_tile "kreiselart" (if (equal (cdr (assoc "KREISELART" attribs)) "PIN") "1" "0"))
(set_tile "geruest_einzelmodul"
(if (equal (cdr (assoc "GERUEST_EINZELMODUL" attribs)) "1") "1" "0"))
;; Actions ;; Actions
(action_tile "accept" (action_tile "accept"
(strcat (strcat
@@ -971,6 +975,7 @@
"(setq dlg-ausrichtung (get_tile \"ausrichtung\"))" "(setq dlg-ausrichtung (get_tile \"ausrichtung\"))"
"(setq dlg-drehrichtung (get_tile \"drehrichtung\"))" "(setq dlg-drehrichtung (get_tile \"drehrichtung\"))"
"(setq dlg-kreiselart (get_tile \"kreiselart\"))" "(setq dlg-kreiselart (get_tile \"kreiselart\"))"
"(setq dlg-geruest-einzelmodul (get_tile \"geruest_einzelmodul\"))"
"(done_dialog 1)" "(done_dialog 1)"
) )
) )
@@ -997,6 +1002,8 @@
(setq attribs (subst (cons "DREHRICHTUNG" (setq attribs (subst (cons "DREHRICHTUNG"
(if (= dlg-drehrichtung "1") "GUZ" "UZS")) (if (= dlg-drehrichtung "1") "GUZ" "UZS"))
(assoc "DREHRICHTUNG" attribs) attribs)) (assoc "DREHRICHTUNG" attribs) attribs))
(setq attribs (subst (cons "GERUEST_EINZELMODUL" dlg-geruest-einzelmodul)
(assoc "GERUEST_EINZELMODUL" attribs) attribs))
;; Alten Block loeschen ;; Alten Block loeschen
(command "_.ERASE" ent "") (command "_.ERASE" ent "")
+2 -2
View File
@@ -440,13 +440,13 @@
;; (Gefaellestrecke + VarioFoerderer, feste Reihenfolge) ;; (Gefaellestrecke + VarioFoerderer, feste Reihenfolge)
;; ============================================================ ;; ============================================================
;; Vorderteil (immer vorhanden). Bezeichnung = Blockname (GF_n/VF_n), ;; Vorderteil (immer vorhanden). Bezeichnung = Blockname (GF_n/VF_n),
;; Artinr. fest 6220 (alle GF/VF). TYP-Wert wird zur Laufzeit gesetzt. ;; ARTINR fest 6220 (alle GF/VF). TYP-Wert wird zur Laufzeit gesetzt.
;; ID zuerst (global, jeder eingefuegte Baustein - Kreisel/GF/VF - erhaelt eine ;; ID zuerst (global, jeder eingefuegte Baustein - Kreisel/GF/VF - erhaelt eine
;; neue ID), danach Bezeichnung (= Blockname). Hoehen/Delta mit Einheit _mm. ;; neue ID), danach Bezeichnung (= Blockname). Hoehen/Delta mit Einheit _mm.
(setq *strecke-attr-front* (setq *strecke-attr-front*
'(("ID" "") '(("ID" "")
("Bezeichnung" "") ("Bezeichnung" "")
("Artinr." "6220") ("ARTINR" "6220")
("MONTAGEHOEHE_m" "0.000") ("MONTAGEHOEHE_m" "0.000")
("HOEHE_VON_mm" "0") ("HOEHE_VON_mm" "0")
("HOEHE_BIS_mm" "0") ("HOEHE_BIS_mm" "0")
+1 -1
View File
@@ -1116,7 +1116,7 @@
(ssg-attrib-set-on vf-insert (ssg-attrib-set-on vf-insert
(list (list
(cons "Bezeichnung" vf-bname) (cons "Bezeichnung" vf-bname)
;; Artinr. bleibt auf Schema-Vorgabe "6220" ;; ARTINR bleibt auf Schema-Vorgabe "6220"
(cons "MONTAGEHOEHE_m" (rtos montagehoehe-m 2 3)) (cons "MONTAGEHOEHE_m" (rtos montagehoehe-m 2 3))
(cons "HOEHE_VON_mm" (itoa (fix hoehe-von))) (cons "HOEHE_VON_mm" (itoa (fix hoehe-von)))
(cons "HOEHE_BIS_mm" (itoa (fix hoehe-bis))) (cons "HOEHE_BIS_mm" (itoa (fix hoehe-bis)))
+107 -57
View File
@@ -40,7 +40,11 @@
(setq FESTE_ETAGE_MITTE 1000) (setq FESTE_ETAGE_MITTE 1000)
(setq ETAGE_SCHRAEG_LAENGE 700) (setq ETAGE_SCHRAEG_LAENGE 700)
(setq ETAGE_HZ_WINKEL 60) ;; Schwenkwinkel der Ein-/Auslauf-Schraegsektionen: 30 Grad (AS_30/ES_30 +
;; 30-Grad-Gefaellebogen). War frueher 60. Nur noch im Laengen-/Hoehen-Budget
;; berechne-winkel-etage (schraeg-cos) verwendet; die fruehere absolute
;; hz-Platzierung wurde durch Frame-Verkettung (cur-hz) ersetzt.
(setq ETAGE_HZ_WINKEL 30)
;; ============================================================ ;; ============================================================
;; TEIL 2: BIBLIOTHEK INITIALISIEREN (ETAGE-SPEZIFISCH) ;; TEIL 2: BIBLIOTHEK INITIALISIEREN (ETAGE-SPEZIFISCH)
@@ -127,8 +131,8 @@
) )
) )
;; Gefaellebogen_links_60 Masse extrahieren ;; Gefaellebogen_links_30 Masse extrahieren
(setq gefaelle-blockname "Gefaellebogen_links_60_R500") (setq gefaelle-blockname "Gefaellebogen_links_30_R500")
(princ (ssg-textf "vfe-extrahiere-block-mass" (list gefaelle-blockname))) (princ (ssg-textf "vfe-extrahiere-block-mass" (list gefaelle-blockname)))
(ensure-block-loaded gefaelle-blockname) (ensure-block-loaded gefaelle-blockname)
(if (tblsearch "BLOCK" gefaelle-blockname) (if (tblsearch "BLOCK" gefaelle-blockname)
@@ -160,8 +164,8 @@
) )
(princ (ssg-textf "vfe-gefaellebogen-links-mass" (list (rtos etage-gef-dx-links 2 2) (rtos etage-gef-dz-links 2 2)))) (princ (ssg-textf "vfe-gefaellebogen-links-mass" (list (rtos etage-gef-dx-links 2 2) (rtos etage-gef-dz-links 2 2))))
;; Gefaellebogen_rechts_60 Masse extrahieren ;; Gefaellebogen_rechts_30 Masse extrahieren
(setq gefaelle-blockname "Gefaellebogen_rechts_60_R500") (setq gefaelle-blockname "Gefaellebogen_rechts_30_R500")
(princ (ssg-textf "vfe-extrahiere-block-mass" (list gefaelle-blockname))) (princ (ssg-textf "vfe-extrahiere-block-mass" (list gefaelle-blockname)))
(ensure-block-loaded gefaelle-blockname) (ensure-block-loaded gefaelle-blockname)
(if (tblsearch "BLOCK" gefaelle-blockname) (if (tblsearch "BLOCK" gefaelle-blockname)
@@ -597,64 +601,83 @@
;; ============================================================ ;; ============================================================
;; Gibt endpunkt zurueck. ;; Gibt endpunkt zurueck.
;; VF_*-Block-Erstellung erfolgt zentral im Dispatcher (vf_core.lsp). ;; VF_*-Block-Erstellung erfolgt zentral im Dispatcher (vf_core.lsp).
;; hz: Parameter fuer Registry-Kompatibilitaet mit variofoerderer-einfuegen ;; hz: Richtung der Hauptlinie (Default 0 = horizontal/X). AS-KS_EIN und
;; (siehe c:VarioFoerderer) - wird hier NICHT verwendet: die Etage-Anlage hat ;; ES-KS_AUS liegen koaxial auf dieser Linie; die Kette wird frame-verkettet
;; bereits eine eigene, fest verdrahtete horizontale Geometrie (hz-anfang/ ;; aufgebaut (cur-hz laeuft durch, Boegen drehen um ihren gemessenen Schwenk).
;; hz-ende fuer den 60-Grad-Uebereinander-Versatz) und unterstuetzt aktuell
;; keine zusaetzliche globale Fahrtrichtung.
(defun etage-foerderanlage-einfuegen (deltaL deltaH richtung (defun etage-foerderanlage-einfuegen (deltaL deltaH richtung
best-winkel L_GF1 L_GF2 L_VF best-winkel L_GF1 L_GF2 L_VF
startpunkt seite hz startpunkt seite hz
/ aktueller-punkt bogen-name endpunkt / aktueller-punkt bogen-name endpunkt
bogen-mass bogen-dx bogen-dz bogen-mass bogen-dx bogen-dz
as-block es-block gefaelle-blockname as-block es-block gefaelle-blockname
hz-vorzeichen hz-anfang hz-ende) as-hz as-ksinfo
cur-hz bogen-info es-info
perp-sin perp-cos p2b-perp es-place-rad
es-wx es-wy es-perp perp-rate L-exit)
(setq aktueller-punkt startpunkt) (setq aktueller-punkt startpunkt)
;; Horizontalwinkel-Vorzeichen je nach Seite: ;; hz = Richtung der Hauptlinie (AS-KS_EIN / ES-KS_AUS liegen darauf).
;; rechts: Anfang +60 Grad (links), Ende -60 Grad (rechts) ;; Default 0 (horizontal), falls der Aufrufer nichts uebergibt.
;; links: Anfang -60 Grad, Ende +60 Grad (if (null hz) (setq hz 0.0))
(setq hz-vorzeichen (if (= seite "rechts") 1 -1)) (setq hz (float hz))
(setq hz-anfang (* hz-vorzeichen ETAGE_HZ_WINKEL))
(setq hz-ende (* (- hz-vorzeichen) ETAGE_HZ_WINKEL))
(setq as-block (strcat "AS_Element_30_" seite)) (setq as-block (strcat "AS_Element_30_" seite))
(setq es-block (strcat "ES_Element_30_" seite)) (setq es-block (strcat "ES_Element_30_" seite))
;; Gefaellebogen auf der GEGENSEITE des AS-Elements (Nutzer-Vorgabe
;; 2026-07-21): AS links -> Boegen rechts, AS rechts -> Boegen links.
;; Beide Etage-Boegen nutzen dieselbe (Gegen-)Seite.
(setq gefaelle-blockname (setq gefaelle-blockname
(if (= seite "rechts") (if (= seite "rechts")
"Gefaellebogen_rechts_60_R500" "Gefaellebogen_links_30_R500"
"Gefaellebogen_links_60_R500" "Gefaellebogen_rechts_30_R500"
)) ))
;; Sentinel: Bibliothek neu initialisieren wenn Bloecke fehlen ;; Sentinel: Bibliothek neu initialisieren wenn Bloecke fehlen
(if (and *etage-lib-initialized* (not (tblsearch "BLOCK" "AS_Element_30_rechts"))) (if (and *etage-lib-initialized* (not (tblsearch "BLOCK" "AS_Element_30_rechts")))
(setq *etage-lib-initialized* nil)) (setq *etage-lib-initialized* nil))
(if (not *etage-lib-initialized*) (init-bibliothek-etage)) (if (not *etage-lib-initialized*) (init-bibliothek-etage))
;; 1. AS_30 ;; 1. AS_30 - KS_EIN koaxial zur Hauptlinie (hz) ausrichten.
;; vf-element-ks-info liefert (ein-ang aus-ang vx vy): ein-ang/aus-ang sind die
;; Ebenen-Winkel der KS_EIN- bzw. KS_AUS-Achse IM BLOCK (bei Einbau-Rotation 0).
;; Platzierungs-hz = (hz - ein-ang) dreht die KS_EIN-Achse von ein-ang auf hz
;; -> KS_EIN liegt koaxial auf der Hauptlinie (Abnahmekriterium).
(princ (ssg-textf "vfe-step1-as30" (list as-block))) (princ (ssg-textf "vfe-step1-as30" (list as-block)))
(setq aktueller-punkt (insert-block-by-ks as-block aktueller-punkt 0.0)) (setq as-ksinfo (vf-element-ks-info as-block))
(setq aktueller-punkt
(insert-block-by-ks as-block aktueller-punkt (- hz (car as-ksinfo))))
;; KS_AUS-Richtung (absolut) = hz + Schwenk (aus-ang - ein-ang); die folgende
;; GF laeuft in dieser Richtung weiter (Frame-Verkettung wie im Linienzug).
(setq as-hz (+ hz (- (cadr as-ksinfo) (car as-ksinfo))))
;; 2. Staustrecke 400mm (hz-anfang, 3 Grad vert, KS_EIN) ;; 2. Staustrecke 400mm (folgt der AS-Richtung as-hz, 3 Grad vert, KS_EIN)
(princ (ssg-textf "vfe-step2" (list (itoa hz-anfang)))) (princ (ssg-textf "vfe-step2" (list (rtos as-hz 2 1))))
(setq aktueller-punkt (setq aktueller-punkt
(insert-hz-scaled-block-by-ks "Staustrecke_SP_1000_mm" aktueller-punkt (insert-hz-scaled-block-by-ks "Staustrecke_SP_1000_mm" aktueller-punkt
400 hz-anfang 3)) 400 as-hz 3))
;; 3. Separator (hz-anfang, 3 Grad vert) ;; 3. Separator (folgt der AS-Richtung as-hz, 3 Grad vert)
(princ (ssg-textf "vfe-step3" (list (itoa hz-anfang)))) (princ (ssg-textf "vfe-step3" (list (rtos as-hz 2 1))))
(setq aktueller-punkt (setq aktueller-punkt
(insert-hz-rotated-block-with-ks "Staustrecke_Separator_SP_300_mm" aktueller-punkt (insert-hz-rotated-block-with-ks "Staustrecke_Separator_SP_300_mm" aktueller-punkt
hz-anfang 3 300 0)) as-hz 3 300 0))
;; 4. Gefaellebogen Anfang (hz-anfang, 0 Grad vert, KS_EIN) ;; Ab hier laufende Richtung cur-hz mitfuehren (frame-verkettet). Start =
(princ (ssg-textf "vfe-step4" (list gefaelle-blockname (itoa hz-anfang)))) ;; KS_AUS-Richtung des AS (as-hz). Jeder Gefaellebogen dreht cur-hz um seinen
;; gemessenen Schwenk (Vorzeichen/Seite kommen aus dem Block).
(setq cur-hz as-hz)
;; 4. Gefaellebogen Anfang (verkettet: KS_EIN auf cur-hz, dann cur-hz drehen)
(setq bogen-info (vf-element-ks-info gefaelle-blockname))
(princ (ssg-textf "vfe-step4" (list gefaelle-blockname (rtos cur-hz 2 1))))
(setq aktueller-punkt (setq aktueller-punkt
(insert-hz-rotated-block-by-ks gefaelle-blockname aktueller-punkt hz-anfang 0)) (insert-hz-rotated-block-by-ks gefaelle-blockname aktueller-punkt
(- cur-hz (car bogen-info)) 0))
(setq cur-hz (+ cur-hz (- (cadr bogen-info) (car bogen-info))))
;; 5. L_GF1 (3 Grad geneigt) ;; 5. L_GF1 (3 Grad geneigt)
(if (> L_GF1 0.1) (if (> L_GF1 0.1)
(progn (progn
(princ (ssg-textf "vfe-step5-strecke" (list (rtos L_GF1 2 2)))) (princ (ssg-textf "vfe-step5-strecke" (list (rtos L_GF1 2 2))))
(setq aktueller-punkt (setq aktueller-punkt
(insert-inclined-scaled-block "Staustrecke_SP_1000_mm" aktueller-punkt L_GF1 3 0.0)) (insert-inclined-scaled-block "Staustrecke_SP_1000_mm" aktueller-punkt L_GF1 3 cur-hz))
) )
(princ (ssg-text "vfe-step5-skip")) (princ (ssg-text "vfe-step5-skip"))
) )
@@ -662,7 +685,7 @@
;; 6. Umlenkstation (3 Grad geneigt) ;; 6. Umlenkstation (3 Grad geneigt)
(princ (ssg-text "vfe-step6")) (princ (ssg-text "vfe-step6"))
(setq aktueller-punkt (setq aktueller-punkt
(insert-rotated-block-with-ks "Vario_Umlenkstation_500mm" aktueller-punkt 3 500 0 0.0)) (insert-rotated-block-with-ks "Vario_Umlenkstation_500mm" aktueller-punkt 3 500 0 cur-hz))
;; 7. 1. Vertikalbogen (3 Grad geneigt) ;; 7. 1. Vertikalbogen (3 Grad geneigt)
(if (= richtung "Auf") (if (= richtung "Auf")
@@ -678,7 +701,7 @@
(setq bogen-dx (car bogen-mass) bogen-dz (caddr bogen-mass)) (setq bogen-dx (car bogen-mass) bogen-dz (caddr bogen-mass))
(princ (ssg-textf "vfe-step7" (list bogen-name))) (princ (ssg-textf "vfe-step7" (list bogen-name)))
(setq aktueller-punkt (setq aktueller-punkt
(insert-rotated-block-with-ks bogen-name aktueller-punkt 3 bogen-dx bogen-dz 0.0)) (insert-rotated-block-with-ks bogen-name aktueller-punkt 3 bogen-dx bogen-dz cur-hz))
;; 8. Variable Strecke L_VF ;; 8. Variable Strecke L_VF
(if (> L_VF 0.1) (if (> L_VF 0.1)
@@ -688,13 +711,13 @@
(princ (ssg-textf "vfe-step8-auf" (list (itoa (- (- best-winkel 3))) (rtos L_VF 2 2)))) (princ (ssg-textf "vfe-step8-auf" (list (itoa (- (- best-winkel 3))) (rtos L_VF 2 2))))
(setq aktueller-punkt (setq aktueller-punkt
(insert-inclined-scaled-block "Staustrecke_SP_1000_mm" aktueller-punkt (insert-inclined-scaled-block "Staustrecke_SP_1000_mm" aktueller-punkt
L_VF (- (- best-winkel 3)) 0.0)) L_VF (- (- best-winkel 3)) cur-hz))
) )
(progn (progn
(princ (ssg-textf "vfe-step8-ab" (list (itoa (+ best-winkel 3)) (rtos L_VF 2 2)))) (princ (ssg-textf "vfe-step8-ab" (list (itoa (+ best-winkel 3)) (rtos L_VF 2 2))))
(setq aktueller-punkt (setq aktueller-punkt
(insert-inclined-scaled-block "Staustrecke_SP_1000_mm" aktueller-punkt (insert-inclined-scaled-block "Staustrecke_SP_1000_mm" aktueller-punkt
L_VF (+ best-winkel 3) 0.0)) L_VF (+ best-winkel 3) cur-hz))
) )
) )
) )
@@ -719,56 +742,83 @@
" (" (itoa (- 3 best-winkel)) " Grad geneigt)")) " (" (itoa (- 3 best-winkel)) " Grad geneigt)"))
(setq aktueller-punkt (setq aktueller-punkt
(insert-rotated-block-with-ks bogen-name aktueller-punkt (insert-rotated-block-with-ks bogen-name aktueller-punkt
(- 3 best-winkel) bogen-dx bogen-dz 0.0)) (- 3 best-winkel) bogen-dx bogen-dz cur-hz))
) )
(progn (progn
(princ (strcat "\n\n9/15: " bogen-name (princ (strcat "\n\n9/15: " bogen-name
" (" (itoa (+ best-winkel 3)) " Grad geneigt)")) " (" (itoa (+ best-winkel 3)) " Grad geneigt)"))
(setq aktueller-punkt (setq aktueller-punkt
(insert-rotated-block-with-ks bogen-name aktueller-punkt (insert-rotated-block-with-ks bogen-name aktueller-punkt
(+ best-winkel 3) bogen-dx bogen-dz 0.0)) (+ best-winkel 3) bogen-dx bogen-dz cur-hz))
) )
) )
;; 10. Motorstation (3 Grad geneigt) ;; 10. Motorstation (3 Grad geneigt)
(princ "\n\n10/15: Motorstation (500mm, 3 Grad geneigt)") (princ "\n\n10/15: Motorstation (500mm, 3 Grad geneigt)")
(setq aktueller-punkt (setq aktueller-punkt
(insert-rotated-block-with-ks "Vario_Motorstation_500mm" aktueller-punkt 3 500 0 0.0)) (insert-rotated-block-with-ks "Vario_Motorstation_500mm" aktueller-punkt 3 500 0 cur-hz))
;; 11. L_GF2 (3 Grad geneigt) ;; 11. L_GF2 (3 Grad geneigt)
(if (> L_GF2 0.1) (if (> L_GF2 0.1)
(progn (progn
(princ (strcat "\n\n11/15: Gefaellestrecke (3 Grad, L=" (rtos L_GF2 2 2) " mm)")) (princ (strcat "\n\n11/15: Gefaellestrecke (3 Grad, L=" (rtos L_GF2 2 2) " mm)"))
(setq aktueller-punkt (setq aktueller-punkt
(insert-inclined-scaled-block "Staustrecke_SP_1000_mm" aktueller-punkt L_GF2 3 0.0)) (insert-inclined-scaled-block "Staustrecke_SP_1000_mm" aktueller-punkt L_GF2 3 cur-hz))
) )
(princ "\n\n11/15: L_GF2 (uebersprungen)") (princ "\n\n11/15: L_GF2 (uebersprungen)")
) )
;; 12. Gefaellebogen Ende (via KS_EIN, 0 Grad vert) ;; 12. Gefaellebogen Ende (verkettet: KS_EIN auf cur-hz, dann cur-hz drehen)
(princ (strcat "\n\n12/15: " gefaelle-blockname " (Ende, KS_EIN)")) (setq bogen-info (vf-element-ks-info gefaelle-blockname))
(setq aktueller-punkt (insert-block-by-ks gefaelle-blockname aktueller-punkt 0.0)) (princ (strcat "\n\n12/15: " gefaelle-blockname
" (Ende, verkettet cur-hz=" (rtos cur-hz 2 1) ")"))
;; 13. Separator Ende (hz-ende, 3 Grad vert)
(princ (strcat "\n\n13/15: Separator (300mm, "
(itoa hz-ende) " Grad hz, 3 Grad vert)"))
(setq aktueller-punkt (setq aktueller-punkt
(insert-hz-rotated-block-with-ks "Staustrecke_Separator_SP_300_mm" aktueller-punkt (insert-block-by-ks gefaelle-blockname aktueller-punkt (- cur-hz (car bogen-info))))
hz-ende 3 300 0)) (setq cur-hz (+ cur-hz (- (cadr bogen-info) (car bogen-info))))
;; 14. Staustrecke 400mm Ende (hz-ende, 3 Grad vert, KS_EIN) ;; --- Auslauf RUECKWAERTS vom ES gerechnet (analog Linienzug Modus 2):
(princ (strcat "\n\n14/15: Staustrecke 400mm (" ;; die Auslauf-Staustrecke wird variabel, sodass das ES-KS_AUS OHNE
(itoa hz-ende) " Grad hz, 3 Grad vert, KS_EIN)")) ;; seitlichen Versatz auf der Hauptachse landet. Reihenfolge (Nutzer-Vorgabe):
;; Staustrecke -> Separator -> ES.
(setq es-info (vf-element-ks-info es-block))
;; perp = Einheitsvektor senkrecht zur Hauptlinie hz: (-sin hz, cos hz)
(setq perp-sin (sin (* hz (/ pi 180.0)))
perp-cos (cos (* hz (/ pi 180.0))))
;; seitliche Lage nach Bogen2 (perp-Abstand des aktuellen Punkts zu startpunkt)
(setq p2b-perp (+ (* (- (car aktueller-punkt) (car startpunkt)) (- perp-sin))
(* (- (cadr aktueller-punkt) (cadr startpunkt)) perp-cos)))
;; ES-Eigenversatz KS_EIN->KS_AUS (Block vx/vy) in Auslaufrichtung gedreht -> perp
(setq es-place-rad (* (- cur-hz (car es-info)) (/ pi 180.0)))
(setq es-wx (- (* (caddr es-info) (cos es-place-rad)) (* (cadddr es-info) (sin es-place-rad))))
(setq es-wy (+ (* (caddr es-info) (sin es-place-rad)) (* (cadddr es-info) (cos es-place-rad))))
(setq es-perp (+ (* es-wx (- perp-sin)) (* es-wy perp-cos)))
;; perp-Auslenkung pro Laengeneinheit bei cur-hz (Neigung 3 Grad)
(setq perp-rate (* (cos (* 3.0 (/ pi 180.0)))
(sin (* (- cur-hz hz) (/ pi 180.0)))))
;; Loesen: p2b-perp + (L_exit + 300)*perp-rate + es-perp = 0
(setq L-exit
(if (> (abs perp-rate) 1e-6)
(- (/ (- (+ p2b-perp es-perp)) perp-rate) 300.0)
400.0))
(if (< L-exit 50.0) (setq L-exit 50.0)) ; Schutz gegen negative/zu kurze GF
;; 13. Auslauf-Staustrecke (variabel, folgt cur-hz, 3 Grad vert, KS_EIN)
(princ (strcat "\n\n13/15: Staustrecke (variabel L=" (rtos L-exit 2 1)
", cur-hz=" (rtos cur-hz 2 1) ")"))
(setq aktueller-punkt (setq aktueller-punkt
(insert-hz-scaled-block-by-ks "Staustrecke_SP_1000_mm" aktueller-punkt (insert-hz-scaled-block-by-ks "Staustrecke_SP_1000_mm" aktueller-punkt
400 hz-ende 3)) L-exit cur-hz 3))
;; 15. ES_30 (hz-ende, 0 Grad vert) ;; 14. Separator (verkettet, folgt cur-hz, 3 Grad vert)
(princ (strcat "\n\n15/15: " es-block (princ (strcat "\n\n14/15: Separator (300mm, cur-hz=" (rtos cur-hz 2 1) ")"))
" (Ende, " (itoa hz-ende) " Grad hz, 0 Grad vert)")) (setq aktueller-punkt
(insert-hz-rotated-block-with-ks "Staustrecke_Separator_SP_300_mm" aktueller-punkt
cur-hz 3 300 0))
;; 15. ES_30 (verkettet: KS_EIN auf cur-hz; KS_AUS auf der Hauptlinie)
(princ (strcat "\n\n15/15: " es-block " (Ende, verkettet cur-hz=" (rtos cur-hz 2 1) ")"))
(setq endpunkt (setq endpunkt
(insert-hz-rotated-block-with-ks es-block aktueller-punkt (insert-block-by-ks es-block aktueller-punkt (- cur-hz (car es-info))))
hz-ende 0 etage-ein-dx etage-ein-dz))
(princ "\n\n=========================================") (princ "\n\n=========================================")
(princ "\n>>> Etage-VarioFoerderer eingefuegt! <<<") (princ "\n>>> Etage-VarioFoerderer eingefuegt! <<<")
+5
View File
@@ -47,6 +47,11 @@ kreisel_edit : dialog {
} }
} }
: toggle {
key = "geruest_einzelmodul";
label = "Geruest fuer Einzelmodul";
}
} }
ok_cancel; ok_cancel;
+1
View File
@@ -215,6 +215,7 @@ def build_kreisel_merkmale(block):
"Drehrichtung": attribs.get("DREHRICHTUNG", "UZS"), "Drehrichtung": attribs.get("DREHRICHTUNG", "UZS"),
"Drehung": block.get("rotation", 0.0), "Drehung": block.get("rotation", 0.0),
"Name": attribs.get("Bezeichnung", ""), "Name": attribs.get("Bezeichnung", ""),
"Geruest fuer Einzelmodul": attribs.get("GERUEST_EINZELMODUL", "0") == "1",
} }
+54 -20
View File
@@ -4,16 +4,20 @@
export_sivas.py - Erzeugt Sivas-Export-CSV mit gruppierten Zeilen und Summierungszeilen. export_sivas.py - Erzeugt Sivas-Export-CSV mit gruppierten Zeilen und Summierungszeilen.
Neues CSV-Format: Neues CSV-Format:
Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];details Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];IDs;details
- Bezeichnung: Wert des Attributs "Bezeichnung" (Kreisel/Eckrad/VF/GF/Strecke). - Bezeichnung: Wert des Attributs "Bezeichnung" (Kreisel/Eckrad/VF/GF/Strecke).
Bei gruppierten Zeilen (mehrere Bloecke je Zeile) kommasepariert. Bei gruppierten Zeilen (mehrere Bloecke je Zeile) kommasepariert.
Bei Omniflo-Zeilen (Bogen/Weiche/Gerade) und der Automation-Summenzeile Bei Omniflo-Zeilen (Bogen/Weiche/Gerade) und der Automation-Summenzeile
bleibt das Feld leer, da es sich um Sammlungen gleichartiger Objekte handelt. bleibt das Feld leer, da es sich um Sammlungen gleichartiger Objekte handelt.
- IDs: kommaseparierte Liste der ID-Attribute aller Bloecke der Zeile
(eigene Spalte, nicht mehr Teil des details-JSON).
- Omniflo Bogen/Weiche: gruppiert nach SivasNummer, Anzahl summiert - Omniflo Bogen/Weiche: gruppiert nach SivasNummer, Anzahl summiert
- Omniflo Gerade: gruppiert nach ARTINR-Attribut, Laenge[mm] summiert - Omniflo Gerade: gruppiert nach ARTINR-Attribut, Laenge[mm] summiert
- ILS 2.0 Kreisel: je Kreisel eine Zeile, details = JSON mit Parametern - ILS 2.0 Kreisel: gruppiert nach Kreiselart+Abstand+Anzahl Separatoren/
Scanner/Rampen, Anzahl summiert
- ILS 2.0 Automation: Summierungszeile (nur wenn ILS-Elemente vorhanden) - ILS 2.0 Automation: Summierungszeile (nur wenn ILS-Elemente vorhanden)
Aufruf: Aufruf:
@@ -119,8 +123,6 @@ def build_gefaellestrecke_details(block):
return "0" return "0"
return { return {
"IDs": [get_id(block)],
"Bezeichnung": attribs.get("Bezeichnung", block.get("block_name", "")),
"Hoehe oben": mm_to_m("HOEHE_VON_mm"), "Hoehe oben": mm_to_m("HOEHE_VON_mm"),
"Hoehe unten": mm_to_m("HOEHE_BIS_mm"), "Hoehe unten": mm_to_m("HOEHE_BIS_mm"),
"Laenge in Meter": attribs.get("L_GF_m", ""), "Laenge in Meter": attribs.get("L_GF_m", ""),
@@ -131,6 +133,23 @@ def build_gefaellestrecke_details(block):
} }
def kreisel_signature(block):
"""
Schluessel zur Gruppierung gleichartiger Kreisel: Kreiselart, Abstand,
Anzahl der Separatoren, Anzahl der Scanner und Anzahl der Rampen
entscheiden, ob Kreisel in derselben Sivas-Zeile summiert werden.
"""
attribs = block.get("attribs", {})
return (
attribs.get("KREISELART", "STANDARD"),
attribs.get("ABSTAND", "2300"),
attribs.get("ANZAHL_SEPARATOR", attribs.get("N_SEPARATOREN", "2")),
attribs.get("ANZAHL_SCANNER", attribs.get("N_SCANNER", "0")),
attribs.get("ANZAHL_RAMPEN", attribs.get("N_RAMPEN", "0")),
attribs.get("GERUEST_EINZELMODUL", "0"),
)
def gefaellestrecke_signature(block): def gefaellestrecke_signature(block):
""" """
Schluessel zur Gruppierung gleichartiger Gefaellestrecken: Bloecke mit Schluessel zur Gruppierung gleichartiger Gefaellestrecken: Bloecke mit
@@ -182,7 +201,6 @@ def build_variofoerderer_details(block):
return 0 return 0
return { return {
"IDs": [get_id(block)],
"Anzahl Foerdergruppen": to_int("ANZAHL_VF"), "Anzahl Foerdergruppen": to_int("ANZAHL_VF"),
"Anzahl Gefaellegruppen": to_int("ANZAHL_GF"), "Anzahl Gefaellegruppen": to_int("ANZAHL_GF"),
"Hoehe in m": attribs.get("MONTAGEHOEHE_m", "0"), "Hoehe in m": attribs.get("MONTAGEHOEHE_m", "0"),
@@ -235,8 +253,7 @@ def build_kreisel_details(block):
"Anzahl der Separatoren": attribs.get("ANZAHL_SEPARATOR", attribs.get("N_SEPARATOREN", "2")), "Anzahl der Separatoren": attribs.get("ANZAHL_SEPARATOR", attribs.get("N_SEPARATOREN", "2")),
"Anzahl der Scanner": attribs.get("ANZAHL_SCANNER", attribs.get("N_SCANNER", "0")), "Anzahl der Scanner": attribs.get("ANZAHL_SCANNER", attribs.get("N_SCANNER", "0")),
"Anzahl der Rampen": attribs.get("ANZAHL_RAMPEN", attribs.get("N_RAMPEN", "0")), "Anzahl der Rampen": attribs.get("ANZAHL_RAMPEN", attribs.get("N_RAMPEN", "0")),
"Drehrichtung": attribs.get("DREHRICHTUNG", "UZS"), "Geruest fuer Einzelmodul": attribs.get("GERUEST_EINZELMODUL", "0") == "1",
"Drehung": block.get("rotation", 0.0),
} }
@@ -468,7 +485,8 @@ def process_blocks(blocks, lookup):
"anzahl": g["anzahl"], "anzahl": g["anzahl"],
"laenge_mm": "", "laenge_mm": "",
"hoehe_m": format_hoehe_m(g["hoehe_mm"]), "hoehe_m": format_hoehe_m(g["hoehe_mm"]),
"details": {"IDs": g["ids"]}, "ids": g["ids"],
"details": {},
}) })
nr += 1 nr += 1
@@ -483,7 +501,8 @@ def process_blocks(blocks, lookup):
"anzahl": g["anzahl"], "anzahl": g["anzahl"],
"laenge_mm": "", "laenge_mm": "",
"hoehe_m": format_hoehe_m(g["hoehe_mm"]), "hoehe_m": format_hoehe_m(g["hoehe_mm"]),
"details": {"IDs": g["ids"]}, "ids": g["ids"],
"details": {},
}) })
nr += 1 nr += 1
@@ -498,25 +517,36 @@ def process_blocks(blocks, lookup):
"anzahl": g["anzahl"], "anzahl": g["anzahl"],
"laenge_mm": int(g["laenge_mm"]), "laenge_mm": int(g["laenge_mm"]),
"hoehe_m": format_hoehe_m(g["hoehe_mm"]), "hoehe_m": format_hoehe_m(g["hoehe_mm"]),
"details": {"IDs": g["ids"]}, "ids": g["ids"],
"details": {},
}) })
nr += 1 nr += 1
# Gleichartige Kreisel (gleiche Kreiselart und gleicher Abstand) zu einer
# Zeile zusammenfassen - nur IDs/Bezeichnung bleiben je Block unterschiedlich.
kreisel_groups = {}
for block in kreisel_list: for block in kreisel_list:
sig = kreisel_signature(block)
if sig not in kreisel_groups:
kreisel_groups[sig] = {"ids": [], "bezeichnungen": [], "block": block}
kreisel_groups[sig]["ids"].append(get_id(block))
kreisel_groups[sig]["bezeichnungen"].append(
block.get("attribs", {}).get("Bezeichnung", ""))
for group in kreisel_groups.values():
sivasnr, teileart = ILS_SIVASNR["kreisel"] sivasnr, teileart = ILS_SIVASNR["kreisel"]
details = build_kreisel_details(block)
details["ID"] = get_id(block)
items.append({ items.append({
"nr": nr, "nr": nr,
"teileart": teileart, "teileart": teileart,
"sivasnr": sivasnr, "sivasnr": sivasnr,
"sivasnr_quoted": True, "sivasnr_quoted": True,
"bezeichnung": block.get("attribs", {}).get("Bezeichnung", ""), "bezeichnung": ", ".join(b for b in group["bezeichnungen"] if b),
"dispgruppe": 20, "dispgruppe": 20,
"anzahl": 1, "anzahl": len(group["ids"]),
"laenge_mm": "", "laenge_mm": "",
"hoehe_m": "", "hoehe_m": "",
"details": details, "ids": group["ids"],
"details": build_kreisel_details(group["block"]),
}) })
nr += 1 nr += 1
@@ -532,7 +562,8 @@ def process_blocks(blocks, lookup):
"anzahl": counters["anzahl_eckraeder"], "anzahl": counters["anzahl_eckraeder"],
"laenge_mm": "", "laenge_mm": "",
"hoehe_m": "", "hoehe_m": "",
"details": {"IDs": eckrad_ids}, "ids": eckrad_ids,
"details": {},
}) })
nr += 1 nr += 1
@@ -551,7 +582,8 @@ def process_blocks(blocks, lookup):
"anzahl": len(strecke_ids), "anzahl": len(strecke_ids),
"laenge_mm": "", "laenge_mm": "",
"hoehe_m": "", "hoehe_m": "",
"details": {"IDs": strecke_ids}, "ids": strecke_ids,
"details": {},
}) })
nr += 1 nr += 1
@@ -569,6 +601,7 @@ def process_blocks(blocks, lookup):
"anzahl": 1, "anzahl": 1,
"laenge_mm": "", "laenge_mm": "",
"hoehe_m": "", "hoehe_m": "",
"ids": [get_id(block)],
"details": build_variofoerderer_details(block), "details": build_variofoerderer_details(block),
}) })
nr += 1 nr += 1
@@ -587,8 +620,6 @@ def process_blocks(blocks, lookup):
for group in gefaelle_groups.values(): for group in gefaelle_groups.values():
sivasnr, teileart = ILS_SIVASNR["gefaellestrecke"] sivasnr, teileart = ILS_SIVASNR["gefaellestrecke"]
details = build_gefaellestrecke_details(group["block"]) details = build_gefaellestrecke_details(group["block"])
details["IDs"] = group["ids"]
details["Bezeichnung"] = group["bezeichnungen"]
items.append({ items.append({
"nr": nr, "nr": nr,
"teileart": teileart, "teileart": teileart,
@@ -599,6 +630,7 @@ def process_blocks(blocks, lookup):
"anzahl": len(group["ids"]), "anzahl": len(group["ids"]),
"laenge_mm": "", "laenge_mm": "",
"hoehe_m": "", "hoehe_m": "",
"ids": group["ids"],
"details": details, "details": details,
}) })
nr += 1 nr += 1
@@ -652,6 +684,7 @@ def format_csv_line(item):
"""Formatiert eine CSV-Zeile im neuen Sivas-Format.""" """Formatiert eine CSV-Zeile im neuen Sivas-Format."""
details_json = json.dumps(item["details"], ensure_ascii=False) details_json = json.dumps(item["details"], ensure_ascii=False)
sivasnr = f'"{item["sivasnr"]}"' if item["sivasnr_quoted"] else item["sivasnr"] sivasnr = f'"{item["sivasnr"]}"' if item["sivasnr_quoted"] else item["sivasnr"]
ids_str = ", ".join(str(i) for i in item.get("ids", []) if i)
return ( return (
f'{item["nr"]}' f'{item["nr"]}'
f';"{item["teileart"]}"' f';"{item["teileart"]}"'
@@ -661,6 +694,7 @@ def format_csv_line(item):
f';{item["anzahl"]}' f';{item["anzahl"]}'
f';{item["laenge_mm"]}' f';{item["laenge_mm"]}'
f';{item["hoehe_m"]}' f';{item["hoehe_m"]}'
f';"{ids_str}"'
f';{details_json}' f';{details_json}'
) )
@@ -688,7 +722,7 @@ def main():
items, _ = process_blocks(blocks, lookup) items, _ = process_blocks(blocks, lookup)
header = "Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];details" header = "Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];IDs;details"
with open(output_csv, "w", encoding="utf-8") as f: with open(output_csv, "w", encoding="utf-8") as f:
f.write(header + "\n") f.write(header + "\n")
for item in items: for item in items: