This commit is contained in:
2026-07-21 09:11:21 +02:00
24 changed files with 1630 additions and 277 deletions
+7 -5
View File
@@ -67,12 +67,12 @@ Die `start_briscad.bat` ruft `setenv.bat` auf und startet BricsCAD.
|---|---|---|
| Kreisel-Module | `KreiselInsert` | KreiselInsert, KreiselConnect, KreiselEdit, ILS_Eckrad |
| Zusatzmodul/Foerderer/Kurven | `SSG_LIB_Commands` | ILS_BTMT_*, ILS_ETF_*, ILS_K*_*, ILS_GK*_* |
| VarioFoerderer | `VarioFoerderer` | FOERDERANLAGE |
| Gefaellestrecke | `Gefaellestrecke` | GEFAELLESTRECKE |
| VarioFoerderer | `VarioFoerderer` | FOERDERANLAGE, VARIOFOERDERER_EDIT |
| Gefaellestrecke | `Gefaellestrecke` | GEFAELLESTRECKE, GEFAELLESTRECKE_EDIT |
| Omniflo (komplett) | `OmniModulInsert` | OMNI_APB_*, OMNI_W*_*, OMNI_AP*, OMNI_TEF_*, OMNI_TV_*, OMNI_EDIT |
| Export | `export` | EXPORTSIVAS, EXPORTCSV, CALLPYTHON |
| Konfiguration | `SSG_LIB_Commands` | SSG_DIM_SWITCH, SSG_SPRACHE |
| Doppelklick/Kontextmenue | `SSG_LIB_Commands` | SSG_BLOCKEDIT |
| Doppelklick/Kontextmenue | `SSG_LIB_Commands` | SSG_BLOCKEDIT (dispatcht Kreisel->KreiselEdit, Omniflo->OMNI_EDIT, GF_*->GEFAELLESTRECKE_EDIT, VF_*->VARIOFOERDERER_EDIT) |
### Entfernte Legacy-Dateien
@@ -92,8 +92,8 @@ Detaillierte Dokumentation aller Funktionen und Befehle: siehe `Lisp/README.md`.
| `ssg_dialog.lsp` | - | DCL-Dialog-Vorlagen und Hilfsfunktionen |
| `ssg_layer.lsp` | - | Layer-Verwaltung |
| `KreiselInsert.lsp` | KreiselInsert, KreiselConnect, KreiselRedraw, KreiselQuick, KreiselEdit, KreiselParams, KreiselLabelSetup, KreiselLabelPos, KreiselLabelHoehe, ILS_Eckrad | ILS Kreisel und Eckrad komplett in AutoLISP |
| `VarioFoerderer.lsp` | FOERDERANLAGE | Vario-Foerderanlagen Generator |
| `Gefaellestrecke.lsp` | GEFAELLESTRECKE | Gefaelle-Foerderanlage (AUS -> Staustrecke skaliert -> Separator -> EIN) |
| `VarioFoerderer.lsp` (Wrapper fuer `vf_core.lsp`/`vf_standard.lsp`/`vf_etage.lsp`/`vf_linienzug.lsp`) | FOERDERANLAGE, VARIOFOERDERER_EDIT | Vario-Foerderanlagen Generator (Typen Standard/Etage/Linienzug); Standardfall + Werteingabe per DCL-Dialog (`vfs-standard-dialog-ablauf` in vf_standard.lsp); Doppelklick auf VF_n-Block ruft VARIOFOERDERER_EDIT (nur fuer per Dialog erstellte Standard-Bloecke, erkannt an XDATA) |
| `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) |
| `export.lsp` | EXPORTSIVAS, EXPORTCSV, OMNI_UPDATE_ATTRIBS | JSON-Sammlung und Python-Export (Omniflo-Merkmale/Sum-Zeile via lib/export_csv.py) |
| `OmniModulInsert.lsp` | OMNI_LOAD, OMNI_APB_*, OMNI_W*_*, OMNI_AP60/AP110, OMNI_TEF_*, OMNI_TV_*, OMNI_APBW_*, OMNI_EDIT | Omniflo-Komponenten: Boegen, Weichen, Verbinder, Transferwagen, Edit-Dialog |
| `SSG_LIB_Commands.lsp` | ILS_BTMT_*, ILS_ETF_*, ILS_K*_*, ILS_GK*_*, SSG_BLOCKEDIT, SSG_DIM_SWITCH, SSG_SPRACHE | Dummy-Befehle fuer Menue + Doppelklick/Kontextmenue-Dispatcher + Konfiguration (2D/3D, Sprache) |
@@ -104,6 +104,8 @@ Detaillierte Dokumentation aller Funktionen und Befehle: siehe `Lisp/README.md`.
| Datei | Verwendet von |
|---|---|
| `kreisel_edit.dcl` | KreiselEdit (KreiselInsert.lsp) |
| `gefaellestrecke.dcl` | GEFAELLESTRECKE Modus 1 (Gefaellestrecke.lsp, `gf-dialog-eingabe`) |
| `variofoerderer.dcl` | FOERDERANLAGE Standardfall + Werteingabe (vf_standard.lsp, `vfs-dialog-eingabe-basis`/`vfs-dialog-winkel-verteilung`) |
| `omniflo_boegen.dcl` | OMNI_APB_* (OmniModulInsert.lsp) |
| `omniflo_weichen.dcl` | OMNI_W*_* (OmniModulInsert.lsp) |
| `sprache.dcl` | SSG_SPRACHE (SSG_LIB_Commands.lsp) |
+401 -99
View File
@@ -1611,6 +1611,12 @@
startpunkt last-ent nach-aus-pt (float hz) (float L_stau)
es-seite))
;; Edit-Metadaten (Fahrtrichtung, Gefaellewinkel, Element-Winkel) als XDATA
;; auf das GF_N-INSERT schreiben, damit GEFAELLESTRECKE_EDIT die Strecke
;; verlustfrei nachbauen kann. Nicht Teil des Sivas-Attributsatzes.
(gf-xdata-schreiben gf-insert hz winkel as-winkel es-winkel
(caddr startpunkt) deltaL-total)
(princ "\n\n=========================================")
(princ (ssg-text "gf-status-erfolgreich-eingefuegt"))
(princ "\n=========================================")
@@ -1620,14 +1626,246 @@
(list gf-insert gf-deltaH (float deltaL-total))
)
;; ============================================================
;; TEIL 5b: DCL-DIALOG (Modus 1 - parametrische Eingabe)
;; ============================================================
;; Parametrische Eingabe fuer Modus 1 / Edit ueber DCL-Dialog
;; (dcl/gefaellestrecke.dcl). Analog zum Kreisel-Dialog, ergaenzt
;; um die Angabe der Einfuegehoehe (Z).
;; prefill: Assoziationsliste zur Vorbelegung (fuer GEFAELLESTRECKE_EDIT) mit
;; Schluesseln "deltaL" "winkel" "hz" "as-seite" "es-seite" "einfuegehoehe"
;; "as-winkel" "es-winkel" - oder nil fuer Neuanlage (Modus 1) mit Defaults.
;; Rueckgabe: (deltaL winkel hz-winkel as-seite es-seite einfuegehoehe
;; as-winkel es-winkel)
;; oder nil bei Abbruch / fehlendem Dialog.
(defun gf-dialog-eingabe ( prefill / dcl-pfad dat ergebnis
dlg-deltal dlg-hoehe dlg-winkel
dlg-richtung dlg-aus dlg-ein
dlg-aus-winkel dlg-ein-winkel
hz-winkel as-seite es-seite as-winkel es-winkel)
(setq dcl-pfad (strcat (getenv "DXFM_DCL") "/gefaellestrecke.dcl"))
(setq dat (load_dialog dcl-pfad))
(if (not (new_dialog "gefaellestrecke" dat))
(progn
(if (>= dat 0) (unload_dialog dat))
(alert (ssg-textf "gf-alert-dialog-fehlt" (list dcl-pfad)))
nil
)
(progn
;; Vorbelegung: aus prefill (Edit) oder Defaults (Neuanlage)
(set_tile "deltal"
(if prefill (rtos (cdr (assoc "deltaL" prefill)) 2 0)
(rtos (ssg-cfg-or "gefaelle" "default_delta_l" 5000.0) 2 0)))
(set_tile "einfuegehoehe"
(if prefill (rtos (cdr (assoc "einfuegehoehe" prefill)) 2 1) "0"))
(set_tile "winkel"
(if prefill (rtos (cdr (assoc "winkel" prefill)) 2 1)
(rtos (ssg-cfg-or "gefaelle" "default_winkel" 3.0) 2 1)))
;; Fahrtrichtung
(start_list "fahrtrichtung")
(add_list (ssg-textf "gf-dlg-richtung-0" (list grad-zeichen)))
(add_list (ssg-textf "gf-dlg-richtung-90" (list grad-zeichen)))
(add_list (ssg-textf "gf-dlg-richtung-180" (list grad-zeichen)))
(add_list (ssg-textf "gf-dlg-richtung-270" (list grad-zeichen)))
(end_list)
(set_tile "fahrtrichtung"
(if prefill
(cond ((equal (cdr (assoc "hz" prefill)) 90.0 0.1) "1")
((equal (cdr (assoc "hz" prefill)) 180.0 0.1) "2")
((equal (cdr (assoc "hz" prefill)) 270.0 0.1) "3")
(t "0"))
"0"))
;; AUS-Element: Winkel (90/30) + Seite
(start_list "aus_winkel")
(add_list "90")
(add_list "30")
(end_list)
(set_tile "aus_winkel"
(if (and prefill (equal (cdr (assoc "as-winkel" prefill)) "30")) "1" "0"))
(start_list "aus_seite")
(add_list (ssg-text "gf-dlg-links"))
(add_list (ssg-text "gf-dlg-rechts"))
(end_list)
(set_tile "aus_seite"
(if (and prefill (equal (cdr (assoc "as-seite" prefill)) "rechts")) "1" "0"))
;; EIN-Element: Winkel (90/30) + Seite
(start_list "ein_winkel")
(add_list "90")
(add_list "30")
(end_list)
(set_tile "ein_winkel"
(if (and prefill (equal (cdr (assoc "es-winkel" prefill)) "30")) "1" "0"))
(start_list "ein_seite")
(add_list (ssg-text "gf-dlg-links"))
(add_list (ssg-text "gf-dlg-rechts"))
(end_list)
(set_tile "ein_seite"
(if (and prefill (equal (cdr (assoc "es-seite" prefill)) "rechts")) "1" "0"))
;; Actions
(action_tile "accept"
(strcat
"(setq dlg-deltal (get_tile \"deltal\"))"
"(setq dlg-hoehe (get_tile \"einfuegehoehe\"))"
"(setq dlg-winkel (get_tile \"winkel\"))"
"(setq dlg-richtung (get_tile \"fahrtrichtung\"))"
"(setq dlg-aus-winkel (get_tile \"aus_winkel\"))"
"(setq dlg-aus (get_tile \"aus_seite\"))"
"(setq dlg-ein-winkel (get_tile \"ein_winkel\"))"
"(setq dlg-ein (get_tile \"ein_seite\"))"
"(done_dialog 1)"
)
)
(action_tile "cancel" "(done_dialog 0)")
(setq ergebnis (start_dialog))
(unload_dialog dat)
(if (= ergebnis 1)
(progn
(setq hz-winkel
(cond ((= dlg-richtung "1") 90.0)
((= dlg-richtung "2") 180.0)
((= dlg-richtung "3") 270.0)
(t 0.0)))
(setq as-seite (if (= dlg-aus "1") "rechts" "links"))
(setq es-seite (if (= dlg-ein "1") "rechts" "links"))
(setq as-winkel (if (= dlg-aus-winkel "1") "30" "90"))
(setq es-winkel (if (= dlg-ein-winkel "1") "30" "90"))
(list
(atof dlg-deltal)
(atof dlg-winkel)
hz-winkel
as-seite
es-seite
(atof dlg-hoehe)
as-winkel
es-winkel)
)
nil
)
)
)
)
;; Gemeinsamer Abschluss fuer Modus 1 + 2: Laengenberechnung,
;; Zusammenfassung, Bestaetigung und Einfuegen.
;; startpunkt: Einfuegepunkt AUS-Element (inkl. Z aus Einfuegehoehe)
;; as-winkel/es-winkel: "30" oder "90" (Element-Variante)
(defun gf-modus12-abschluss (deltaL winkel hz-winkel as-seite es-seite startpunkt
as-winkel es-winkel /
rad sep-x L_stau antwort)
(if (null as-winkel) (setq as-winkel "90"))
(if (null es-winkel) (setq es-winkel "90"))
(setq winkel (float winkel))
(setq rad (* winkel (/ pi 180.0)))
(princ (ssg-textf "gf-status-winkel" (list (rtos winkel 2 1) grad-zeichen)))
;; AS-/ES-Masse fuer die gewaehlte Winkel-/Seiten-Variante setzen
;; (aktualisiert aus-dx/ein-dx vor der Laengenberechnung)
(vf-set-as-masse as-winkel as-seite)
(vf-set-es-masse es-winkel es-seite)
;; Laengenberechnung
;; deltaL = aus_dx + L_stau*cos(rad) + sep*cos(rad) + ein_dx
(setq sep-x (* (ssg-cfg-or "gefaelle" "separator_breite" 300.0) (cos rad)))
(setq L_stau (/ (- deltaL aus-dx ein-dx sep-x) (cos rad)))
;; Validierung
(if (<= L_stau 0.1)
(progn
(alert (ssg-textf "gf-alert-staustrecke-ungueltig" (list (rtos L_stau 2 2))))
(exit)
)
)
;; Zusammenfassung
(princ "\n\n=========================================")
(princ (ssg-textf "gf-status-fahrtrichtung" (list (rtos hz-winkel 2 1) grad-zeichen)))
(princ (ssg-textf "gf-status-zus2-winkel" (list (rtos winkel 2 1) grad-zeichen)))
(princ (ssg-textf "gf-status-zus2-aus-seite" (list as-seite)))
(princ (ssg-textf "gf-status-zus2-ein-seite" (list es-seite)))
(princ (ssg-textf "gf-status-zus2-lstau" (list (rtos L_stau 2 2))))
(princ "\n=========================================")
;; Bestaetigung
(setq antwort (getstring (ssg-text "gf-prompt-einfuegen")))
(if (not (= antwort "2"))
(gefaellestrecke-einfuegen L_stau (fix winkel) startpunkt as-seite es-seite hz-winkel deltaL as-winkel es-winkel)
(princ (ssg-text "gf-status-abgebrochen"))
)
)
;; Nicht-interaktiver Neuaufbau (fuer GEFAELLESTRECKE_EDIT): Element-Masse
;; setzen, L_stau berechnen und einfuegen - ohne Zusammenfassung/Rueckfrage.
;; Rueckgabe: (ename deltaH deltaL) von gefaellestrecke-einfuegen oder nil.
(defun gf-rebuild (deltaL winkel hz-winkel as-seite es-seite startpunkt
as-winkel es-winkel /
rad sep-x L_stau)
(if (null as-winkel) (setq as-winkel "90"))
(if (null es-winkel) (setq es-winkel "90"))
(setq winkel (float winkel))
(setq rad (* winkel (/ pi 180.0)))
(vf-set-as-masse as-winkel as-seite)
(vf-set-es-masse es-winkel es-seite)
(setq sep-x (* (ssg-cfg-or "gefaelle" "separator_breite" 300.0) (cos rad)))
(setq L_stau (/ (- deltaL aus-dx ein-dx sep-x) (cos rad)))
(if (<= L_stau 0.1)
(progn
(alert (ssg-textf "gf-alert-staustrecke-ungueltig" (list (rtos L_stau 2 2))))
nil
)
(gefaellestrecke-einfuegen
L_stau (fix winkel) startpunkt as-seite es-seite hz-winkel deltaL as-winkel es-winkel)
)
)
;; ============================================================
;; XDATA-Metadaten fuer den Edit-Nachbau (App "SSG_GF_EDIT").
;; Bewusst NICHT im Sivas-Attributsatz, damit der Export unveraendert bleibt.
;; ============================================================
(if (null *gf-xdata-app*) (setq *gf-xdata-app* "SSG_GF_EDIT"))
;; Fahrtrichtung/Winkel/Element-Varianten als XDATA auf das GF_N-INSERT schreiben.
(defun gf-xdata-schreiben (ent hz winkel as-winkel es-winkel z-start deltaL /)
(regapp *gf-xdata-app*)
(entmod
(append (entget ent)
(list
(list -3
(list *gf-xdata-app*
(cons 1000 (rtos (float hz) 2 4))
(cons 1000 (rtos (float winkel) 2 4))
(cons 1000 (if as-winkel as-winkel "90"))
(cons 1000 (if es-winkel es-winkel "90"))
(cons 1000 (rtos (float z-start) 2 4))
(cons 1000 (rtos (float deltaL) 2 4)))))))
ent
)
;; XDATA lesen -> (hz-str winkel-str as-winkel es-winkel z-str deltaL-str) oder nil.
(defun gf-xdata-lesen (ent / xd app-data)
(setq xd (entget ent (list *gf-xdata-app*)))
(setq app-data (cdr (assoc -3 xd)))
(if app-data
(mapcar 'cdr (cdr (car app-data)))
nil
)
)
;; ============================================================
;; TEIL 6: HAUPTBEFEHL
;; ============================================================
(defun c:GEFAELLESTRECKE ( / antwort eingabe-modus deltaL winkel rad L_stau sep-x
(defun c:GEFAELLESTRECKE ( / antwort deltaL winkel
as-seite es-seite gf-as-winkel gf-es-winkel
line-points startpunkt endpunkt differenz
deltaX deltaY startpunkt-fuer-einfuegen hz-winkel)
deltaX deltaY startpunkt-fuer-einfuegen hz-winkel
dlg-werte)
(princ "\n=========================================")
(princ (ssg-text "gf-banner-titel"))
@@ -1655,95 +1893,52 @@
(gf-linienzug-modus)
)
;; Modus 1+2: einfache Gefaellestrecke
(t
(if (= antwort "2")
(setq eingabe-modus "Linie")
(setq eingabe-modus "Manuell")
;; Modus 2: 3D-Linie (Konsoleneingabe)
((= antwort "2")
(princ (ssg-text "gf-modus2-header"))
(command "BKS" "W")
(princ (ssg-text "gf-status-bks-welt"))
(setq line-points
(get-line-start-end-points
(ssg-text "gf-prompt-3dlinie-richtung")))
(if (null line-points)
(progn (alert (ssg-text "gf-alert-keine-linie")) (exit))
)
;; Modus 1: Manuelle Eingabe
(if (= eingabe-modus "Manuell")
(progn
(princ (ssg-text "gf-modus1-header"))
(setq startpunkt-fuer-einfuegen
(getpoint (ssg-text "gf-prompt-startpunkt-aus")))
(if (null startpunkt-fuer-einfuegen)
(setq startpunkt-fuer-einfuegen '(0 0 0)))
(setq deltaL (getreal (ssg-textf "gf-prompt-deltal-abstand" (list delta-sym))))
(if (or (null deltaL) (<= deltaL 0))
(setq deltaL (ssg-cfg-or "gefaelle" "default_delta_l" 5000.0)))
)
;; Modus 2: 3D-Linie
(progn
(princ (ssg-text "gf-modus2-header"))
(command "BKS" "W")
(princ (ssg-text "gf-status-bks-welt"))
(setq line-points
(get-line-start-end-points
(ssg-text "gf-prompt-3dlinie-richtung")))
(if (null line-points)
(progn (alert (ssg-text "gf-alert-keine-linie")) (exit))
)
(setq startpunkt (car line-points)
endpunkt (cadr line-points))
(setq differenz (punkt-differenz startpunkt endpunkt))
(setq deltaX (car differenz)
deltaY (cadr differenz))
;; deltaL: horizontale 2D-Projektion entlang Fahrtrichtung
(setq deltaL (sqrt (+ (* deltaX deltaX) (* deltaY deltaY))))
;; hz-Winkel: Fahrtrichtung aus Linienpunkten (in Grad, 0=Ost)
(setq hz-winkel (* (angle '(0.0 0.0) (list deltaX deltaY)) (/ 180.0 pi)))
(princ (ssg-textf "gf-status-fahrtrichtung-linie" (list (rtos hz-winkel 2 1) grad-zeichen)))
(princ (ssg-textf "gf-status-deltal-mm" (list delta-sym (rtos deltaL 2 2))))
;; Startpunkt separat waehlen (unabhaengig von Linie)
(setq startpunkt-fuer-einfuegen
(getpoint (ssg-text "gf-prompt-startpunkt-aus")))
(if (null startpunkt-fuer-einfuegen)
(progn (princ (ssg-text "gf-fehler-kein-startpunkt")) (exit))
)
)
(setq startpunkt (car line-points)
endpunkt (cadr line-points))
(setq differenz (punkt-differenz startpunkt endpunkt))
(setq deltaX (car differenz)
deltaY (cadr differenz))
;; deltaL: horizontale 2D-Projektion entlang Fahrtrichtung
(setq deltaL (sqrt (+ (* deltaX deltaX) (* deltaY deltaY))))
;; hz-Winkel: Fahrtrichtung aus Linienpunkten (in Grad, 0=Ost)
(setq hz-winkel (* (angle '(0.0 0.0) (list deltaX deltaY)) (/ 180.0 pi)))
(princ (ssg-textf "gf-status-fahrtrichtung-linie" (list (rtos hz-winkel 2 1) grad-zeichen)))
(princ (ssg-textf "gf-status-deltal-mm" (list delta-sym (rtos deltaL 2 2))))
;; Startpunkt separat waehlen (unabhaengig von Linie)
(setq startpunkt-fuer-einfuegen
(getpoint (ssg-text "gf-prompt-startpunkt-aus")))
(if (null startpunkt-fuer-einfuegen)
(progn (princ (ssg-text "gf-fehler-kein-startpunkt")) (exit))
)
(princ "\n\n=========================================")
(princ (ssg-textf "gf-status-deltal-mm" (list delta-sym (rtos deltaL 2 2))))
(princ "\n=========================================")
;; Winkelabfrage (beide Modi: manuell)
;; Winkelabfrage
(setq winkel (getreal (ssg-text "gf-prompt-gefaellewinkel-def3")))
(if (or (null winkel) (<= winkel 0))
(setq winkel (ssg-cfg-or "gefaelle" "default_winkel" 3.0)))
(setq winkel (float winkel))
(setq rad (* winkel (/ pi 180.0)))
(princ (ssg-textf "gf-status-winkel" (list (rtos winkel 2 1) grad-zeichen)))
;; Fahrtrichtung waehlen (nur Modus 1; Modus 2 berechnet hz aus Linie)
(if (= eingabe-modus "Manuell")
(progn
(princ (ssg-text "vfc-fahrtrichtung-header"))
(princ (ssg-textf "vfc-fahrtrichtung-0" (list grad-zeichen)))
(princ (ssg-textf "vfc-fahrtrichtung-90" (list grad-zeichen)))
(princ (ssg-textf "vfc-fahrtrichtung-180" (list grad-zeichen)))
(princ (ssg-textf "vfc-fahrtrichtung-270" (list grad-zeichen)))
(setq antwort (getstring (ssg-text "prompt-wahl-1-2-3-4")))
(cond
((= antwort "2") (setq hz-winkel 90.0))
((= antwort "3") (setq hz-winkel 180.0))
((= antwort "4") (setq hz-winkel 270.0))
(t (setq hz-winkel 0.0))
)
(princ (ssg-textf "gf-status-fahrtrichtung" (list (rtos hz-winkel 2 1) grad-zeichen)))
)
)
;; AUS-Element: 30/90 (vor Seite) + Seite, dann Masse fuer Variante setzen
;; AUS-Element: 30/90 + Seite
(setq gf-as-winkel (vf-frage-element-winkel "vf-winkel-aus-header"))
(princ (ssg-text "gf-seite-aus-header"))
(princ (ssg-text "gf-seite-links"))
(princ (ssg-text "gf-seite-rechts"))
(setq antwort (getstring (ssg-text "prompt-wahl-1-2")))
(setq as-seite (if (= antwort "2") "rechts" "links"))
(vf-set-as-masse gf-as-winkel as-seite)
;; EIN-Element: 30/90 + Seite
(setq gf-es-winkel (vf-frage-element-winkel "vf-winkel-ein-header"))
@@ -1752,41 +1947,148 @@
(princ (ssg-text "gf-seite-rechts"))
(setq antwort (getstring (ssg-text "prompt-wahl-1-2")))
(setq es-seite (if (= antwort "2") "rechts" "links"))
(vf-set-es-masse gf-es-winkel es-seite)
;; Laengenberechnung (aus-dx/ein-dx jetzt fuer die gewaehlte Variante)
;; deltaL = aus_dx + L_stau*cos(rad) + sep*cos(rad) + ein_dx
(setq sep-x (* (ssg-cfg-or "gefaelle" "separator_breite" 300.0) (cos rad)))
(setq L_stau (/ (- deltaL aus-dx ein-dx sep-x) (cos rad)))
;; Gemeinsamer Abschluss (Masse, Laenge, Zusammenfassung, Einfuegen)
(gf-modus12-abschluss deltaL winkel hz-winkel as-seite es-seite
startpunkt-fuer-einfuegen gf-as-winkel gf-es-winkel)
)
;; Validierung
(if (<= L_stau 0.1)
(progn
(alert (ssg-textf "gf-alert-staustrecke-ungueltig" (list (rtos L_stau 2 2))))
(exit)
)
)
;; Zusammenfassung
(princ "\n\n=========================================")
(princ (ssg-textf "gf-status-fahrtrichtung" (list (rtos hz-winkel 2 1) grad-zeichen)))
(princ (ssg-textf "gf-status-zus2-winkel" (list (rtos winkel 2 1) grad-zeichen)))
(princ (ssg-textf "gf-status-zus2-aus-seite" (list as-seite)))
(princ (ssg-textf "gf-status-zus2-ein-seite" (list es-seite)))
(princ (ssg-textf "gf-status-zus2-lstau" (list (rtos L_stau 2 2))))
(princ "\n=========================================")
;; Bestaetigung
(setq antwort (getstring (ssg-text "gf-prompt-einfuegen")))
(if (not (= antwort "2"))
(gefaellestrecke-einfuegen L_stau (fix winkel) startpunkt-fuer-einfuegen as-seite es-seite hz-winkel deltaL gf-as-winkel gf-es-winkel)
;; Modus 1: Manuelle Eingabe via DCL-Dialog
(t
(princ (ssg-text "gf-modus1-header"))
;; Startpunkt (X/Y) in der Zeichnung waehlen; Z kommt aus dem Dialog
(setq startpunkt-fuer-einfuegen
(getpoint (ssg-text "gf-prompt-startpunkt-aus")))
(if (null startpunkt-fuer-einfuegen)
(setq startpunkt-fuer-einfuegen '(0 0 0)))
(setq dlg-werte (gf-dialog-eingabe nil))
(if (null dlg-werte)
(princ (ssg-text "gf-status-abgebrochen"))
(progn
(setq deltaL (nth 0 dlg-werte)
winkel (nth 1 dlg-werte)
hz-winkel (nth 2 dlg-werte)
as-seite (nth 3 dlg-werte)
es-seite (nth 4 dlg-werte)
gf-as-winkel (nth 6 dlg-werte)
gf-es-winkel (nth 7 dlg-werte))
;; Einfuegehoehe (Z) aus Dialog auf gewaehlten Startpunkt anwenden
(setq startpunkt-fuer-einfuegen
(list (car startpunkt-fuer-einfuegen)
(cadr startpunkt-fuer-einfuegen)
(nth 5 dlg-werte)))
(if (or (null deltaL) (<= deltaL 0))
(setq deltaL (ssg-cfg-or "gefaelle" "default_delta_l" 5000.0)))
(if (or (null winkel) (<= winkel 0))
(setq winkel (ssg-cfg-or "gefaelle" "default_winkel" 3.0)))
(gf-modus12-abschluss deltaL winkel hz-winkel as-seite es-seite
startpunkt-fuer-einfuegen gf-as-winkel gf-es-winkel)
)
)
)
)
nil
)
;; ============================================================
;; TEIL 7: GEFAELLESTRECKE_EDIT - Doppelklick/Kontextmenue-Bearbeitung
;; ============================================================
;; Bearbeitet eine bestehende Gefaellestrecke (GF_n-Block) ueber den
;; DCL-Dialog: liest die aktuellen Parameter (XDATA, sonst Attribute),
;; zeigt sie vorbelegt im Dialog und baut die Strecke bei OK am selben
;; Startpunkt neu auf. Wird vom Doppelklick-Dispatcher SSG_BLOCKEDIT
;; fuer Blocknamen "GF_*" aufgerufen.
(defun c:GEFAELLESTRECKE_EDIT ( / ss ent ed bname startpunkt attribs xd
hz winkel as-winkel es-winkel z-start deltaL
prefill dlg-werte)
;; Implied Selection VOR ssg-start pruefen (ssg-start hebt Selektion auf)
(setq ss (ssget "I"))
(if (and ss (= (sslength ss) 1)
(= (cdr (assoc 0 (entget (ssname ss 0)))) "INSERT"))
(setq ent (ssname ss 0))
)
(ssg-start "GEFAELLESTRECKE_EDIT" '(("OSMODE") ("ATTREQ") ("ATTDIA")))
(setvar "OSMODE" 0)
;; Block auswaehlen (falls nicht vorselektiert)
(if (null ent)
(progn
(setq ss (ssget ":S" '((0 . "INSERT"))))
(if ss (setq ent (ssname ss 0)))
)
)
(if (null ent) (progn (ssg-end) (exit)))
(setq ed (entget ent))
(setq bname (cdr (assoc 2 ed)))
(if (not (wcmatch bname "GF_*"))
(progn (alert (ssg-textf "gf-edit-kein-gf" (list bname))) (ssg-end) (exit)))
(setq startpunkt (cdr (assoc 10 ed)))
(setq attribs (ssg-attrib-read ent))
;; Nur einfache Gefaellestrecken (TYP "Gefaellestrecke") lassen sich ueber den
;; Dialog verlustfrei nachbauen. Streckengruppen (mit Bogen / Linienzug / VF)
;; wuerden beim Neuaufbau ihre Bogengeometrie verlieren -> abbrechen.
(if (/= (cond ((cdr (assoc "TYP" attribs))) ("")) "Gefaellestrecke")
(progn
(alert (ssg-textf "gf-edit-nur-einfach"
(list (cond ((cdr (assoc "TYP" attribs))) ("?")))))
(ssg-end)
(exit)
)
)
;; Parameter bestimmen: bevorzugt aus XDATA (verlustfrei), sonst aus Attributen.
;; Aus Attributen sind Fahrtrichtung (hz) und Element-Winkel nicht ableitbar
;; -> Default 0 Grad / 90 Grad; der Nutzer kann sie im Dialog korrigieren.
(setq xd (gf-xdata-lesen ent))
(if xd
(setq hz (atof (nth 0 xd))
winkel (atof (nth 1 xd))
as-winkel (nth 2 xd)
es-winkel (nth 3 xd)
z-start (atof (nth 4 xd))
deltaL (atof (nth 5 xd)))
(setq hz 0.0
winkel (atof (cond ((cdr (assoc "GF_WINKEL" attribs))) ("3.0")))
as-winkel "90"
es-winkel "90"
z-start (atof (cond ((cdr (assoc "HOEHE_VON_mm" attribs))) ("0")))
deltaL (atof (cond ((cdr (assoc "DELTA_L_mm" attribs))) ("0"))))
)
(setq prefill
(list (cons "deltaL" deltaL)
(cons "winkel" winkel)
(cons "hz" hz)
(cons "as-seite" (cond ((cdr (assoc "SEITE_AS" attribs))) ("links")))
(cons "es-seite" (cond ((cdr (assoc "SEITE_ES" attribs))) ("links")))
(cons "einfuegehoehe" z-start)
(cons "as-winkel" as-winkel)
(cons "es-winkel" es-winkel)))
(setq dlg-werte (gf-dialog-eingabe prefill))
(if (null dlg-werte)
(princ (ssg-text "gf-status-abgebrochen"))
(progn
;; Alten GF-Verbund loeschen und am selben Startpunkt (X/Y) mit der
;; im Dialog gewaehlten Einfuegehoehe (Z) neu aufbauen.
(entdel ent)
(gf-rebuild
(nth 0 dlg-werte) (nth 1 dlg-werte) (nth 2 dlg-werte)
(nth 3 dlg-werte) (nth 4 dlg-werte)
(list (car startpunkt) (cadr startpunkt) (nth 5 dlg-werte))
(nth 6 dlg-werte) (nth 7 dlg-werte))
(princ (ssg-textf "gf-edit-neu-aufgebaut" (list bname)))
)
)
(ssg-end)
(princ)
)
;; ============================================================
;; START
;; ============================================================
+8 -8
View File
@@ -72,7 +72,7 @@
;; Attribut-Definitionen: ((TAG DEFAULT) ...)
(setq *kreisel-attrib-defs*
'(("NAME" "")
'(("Bezeichnung" "")
("DREHRICHTUNG" "UZS")
("ANZAHL_SEPARATOR" "2")
("KREISELART" "STANDARD")
@@ -90,7 +90,7 @@
;; Eckrad Attribut-Definitionen: ((TAG DEFAULT) ...)
(setq *eckrad-attrib-defs*
'(("NAME" "")
'(("Bezeichnung" "")
("DREHRICHTUNG" "UZS")
("DREHUNG" "0")
("NUMMER" "0")
@@ -325,9 +325,9 @@
)
)
;; NAME automatisch setzen: "KreiselN"
(setq attribs (subst (cons "NAME" (strcat "Kreisel" (itoa kreisel-nummer)))
(assoc "NAME" attribs) attribs))
;; Bezeichnung automatisch setzen: "KreiselN"
(setq attribs (subst (cons "Bezeichnung" (strcat "Kreisel" (itoa kreisel-nummer)))
(assoc "Bezeichnung" attribs) attribs))
;; --- HÖHE BESTIMMEN ---
;; Priorität 1: Aus basePoint (wenn 3D Punkt mit Z > 0)
@@ -928,7 +928,7 @@
)
;; Tiles initialisieren
(set_tile "name" (cdr (assoc "NAME" attribs)))
(set_tile "name" (cdr (assoc "Bezeichnung" attribs)))
(set_tile "abstand" (cdr (assoc "ABSTAND" attribs)))
(set_tile "hoehe" (cdr (assoc "HOEHE" attribs)))
@@ -976,8 +976,8 @@
(setq newRotation (kreisel-idx-to-rotation (atoi dlg-ausrichtung)))
;; Attribute aktualisieren
(setq attribs (subst (cons "NAME" dlg-name)
(assoc "NAME" attribs) attribs))
(setq attribs (subst (cons "Bezeichnung" dlg-name)
(assoc "Bezeichnung" attribs) attribs))
(setq attribs (subst (cons "HOEHE" dlg-hoehe)
(assoc "HOEHE" attribs) attribs))
(setq attribs (subst (cons "KREISELART"
+52 -5
View File
@@ -233,9 +233,30 @@ Lädt alle Module in der richtigen Reihenfolge. Ermittelt den Pfad automatisch
### `VarioFoerderer.lsp` Vario-Förderer
Parametrischer Generator für ILS Vario-Förderanlagen. Liest Block-Geometrie aus einer DWG-Bibliothek (`DXFM_BLOCKS`). Alle Konstanten (Abstände, Winkel, Skalierung) werden via `ssg-cfg-or` aus `component_defaults.json` (Sektion `vario`) gelesen.
Kompatibilitäts-Wrapper, der `vf_core.lsp` lädt (Plugin-Dispatcher-Architektur; lädt seinerseits `vf_standard.lsp`, `vf_etage.lsp`, `vf_linienzug.lsp`). Parametrischer Generator für ILS Vario-Förderanlagen. Liest Block-Geometrie aus einer DWG-Bibliothek (`DXFM_BLOCKS`). Alle Konstanten (Abstände, Winkel, Skalierung) werden via `ssg-cfg-or` aus `component_defaults.json` (Sektion `vario`) gelesen.
**Befehl:** `c:FOERDERANLAGE`
**Befehl:** `c:FOERDERANLAGE` / `c:VarioFoerderer` wählt zuerst den Anlagen-Typ (Standard/Etage/Linienzug):
- **Typ „standard“ + Werteingabe:** läuft über den DCL-Dialog
[`dcl/variofoerderer.dcl`](../dcl/variofoerderer.dcl) (zwei Dialoge, `vfs-standard-dialog-ablauf`
in `vf_standard.lsp`): Dialog 1 (`vfs-dialog-eingabe-basis`) erfasst deltaL, deltaH,
Förderrichtung (Auf/Ab), Einfügehöhe, Fahrtrichtung und Seite; anschließend berechnet
`berechne-standard` die gültigen Winkel-Varianten, und Dialog 2
(`vfs-dialog-winkel-verteilung`) lässt Winkel und L_GF-Verteilung (vorne/hinten) wählen.
Startpunkt (X/Y) wird wie bei der Gefällestrecke vorher in der Zeichnung gepickt.
- **Typ „standard“ + 3D-Linie**, sowie **Typ „etage“** und **„linienzug“** bleiben
vollständig interaktiv (Kommandozeile), unverändert gegenüber dem bisherigen Ablauf.
**Bearbeiten (`c:VARIOFOERDERER_EDIT`):** Doppelklick auf einen `VF_n`-Block bzw.
Rechtsklick-Kontextmenü/`SSG_BLOCKEDIT` öffnet dieselben Dialoge, vorbelegt mit den
aktuellen Parametern, und baut die Strecke bei OK am selben Startpunkt neu auf (neue
`VF_n`-Nummer). Da `VF_n`-Blöcke auch von Etage- und Linienzug-Anlagen erzeugt werden
(deren komplexere Geometrie ein einfacher Neuaufbau zerstören würde), markiert
`vfs-xdata-schreiben` nur per Standard-Dialog erstellte Blöcke mit XDATA (App
`SSG_VF_EDIT`, Fahrtrichtung `hz`); Blöcke ohne diese Markierung weist
`c:VARIOFOERDERER_EDIT` mit einer Meldung ab, statt sie zu verändern. Winkel und L_GF1
werden aus den Sivas-Attributen (`VF_WINKEL`, `L_GF_m`) vorbelegt (Verteilung stets als
„Eigene Werte“ mit dem exakten aktuellen L_GF1).
**Wichtige interne Funktionen** (werden auch von `Gefaellestrecke.lsp` genutzt):
@@ -260,10 +281,36 @@ Setzt `VarioFoerderer.lsp` voraus (nutzt dessen `init-bibliothek`, `insert-block
**Befehl:** `c:GEFAELLESTRECKE`
Zwei Modi:
Drei Modi:
- **Modus 1:** Startpunkt + ΔL (Horizontalabstand) interaktiv abfragen
- **Modus 2:** Bestehende 3D-Linie wählen (ΔL und Winkel werden daraus berechnet)
- **Modus 1:** Startpunkt (X/Y) picken, restliche Parameter über den DCL-Dialog
[`dcl/gefaellestrecke.dcl`](../dcl/gefaellestrecke.dcl) eingeben (ΔL, Einfügehöhe Z,
Gefällewinkel, Fahrtrichtung, AUS-/EIN-Element je Winkel 30/90 und Seite links/rechts).
Die Einfügehöhe aus dem Dialog setzt die Z-Koordinate des Startpunkts.
- **Modus 2:** Bestehende 3D-Linie wählen (ΔL und Fahrtrichtung werden daraus berechnet),
restliche Parameter interaktiv über die Kommandozeile.
- **Modus 3:** Linienzug aus LINE-/ARC-Objekten; ARC-Segmente werden durch
Gefällebogen-Blöcke ersetzt, Winkel aus ΔH und Geometrie berechnet.
**Dialog-Hilfsfunktionen:** `gf-dialog-eingabe` (lädt/liest den DCL-Dialog, liefert
`(deltaL winkel hz-winkel as-seite es-seite einfuegehoehe as-winkel es-winkel)` oder `nil`
bei Abbruch) und `gf-modus12-abschluss` (gemeinsamer Abschluss für Modus 1+2: setzt die
Element-Masse per `vf-set-as-masse`/`vf-set-es-masse`, berechnet die Staustreckenlänge,
zeigt die Zusammenfassung und ruft `gefaellestrecke-einfuegen`).
Die AUS-/EIN-Element-Varianten (30/90 Grad, links/rechts) liegen als DWG-Blöcke
`AS_Element_<30|90>_<links|rechts>` bzw. `ES_Element_…` in `data/ils/2D|3D/`; ihre Maße
werden direkt aus dem Block gemessen (`vf-element-masse`), es gibt dafür keine JSON-Tabelle.
**Bearbeiten (`c:GEFAELLESTRECKE_EDIT`):** Doppelklick auf einen Gefällestrecken-Block
(`GF_n`) bzw. Rechtsklick-Kontextmenü/`SSG_BLOCKEDIT` öffnet denselben DCL-Dialog,
vorbelegt mit den aktuellen Parametern, und baut die Strecke bei OK am selben Startpunkt
neu auf. Damit Fahrtrichtung und Element-Winkel (30/90) verlustfrei rekonstruiert werden,
schreibt `gefaellestrecke-einfuegen` diese beim Erstellen als XDATA (App `SSG_GF_EDIT`,
Helfer `gf-xdata-schreiben`/`gf-xdata-lesen`) auf das `GF_n`-INSERT bewusst **nicht** in
den Sivas-Attributsatz, damit der Export unverändert bleibt. Ältere Blöcke ohne XDATA
werden aus den Attributen vorbelegt (Fahrtrichtung 0°, Element-Winkel 90° als Vorgabe).
Der Neuaufbau läuft über `gf-rebuild` (nicht-interaktiv, ohne Konsolen-Rückfrage).
---
+63
View File
@@ -15,6 +15,55 @@
(princ)
)
;; --- ILS / Zusatzmodul: Sensoren (Scanner / Separator) einfuegen ---
;; Ermittelt den Pfad zu einer Sensor-Blockdatei. Die Sensor-Bloecke
;; werden fest aus data/ils/3D geladen (unabhaengig von der
;; 2D/3D-Umschaltung).
(defun ils-sensor-pfad (fname / p)
(setq p (strcat (getenv "DXFMAKRO") "\\data\\ils\\3D\\" fname ".dwg"))
(if (findfile p) p nil)
)
;; Fuegt einen Sensor-Block wiederholt ein, bis der Benutzer mit
;; ENTER oder ESC abbricht. Rotation je Einfuegung interaktiv.
(defun ils-insert-sensor (fname / pfad pt oldattreq n res)
(setq pfad (ils-sensor-pfad fname))
(if (null pfad)
(princ (strcat "\n>>> FEHLER: Blockdatei '" fname ".dwg' nicht gefunden."
" (in data/ils/3D pruefen)"))
(progn
(setq oldattreq (getvar "ATTREQ"))
(setvar "ATTREQ" 0)
(setq n 0)
;; Punkt abfragen; ENTER liefert nil, ESC einen abgefangenen Fehler -
;; beides beendet die Schleife sauber (ATTREQ wird wiederhergestellt).
(while
(progn
(setq res (vl-catch-all-apply
'getpoint
(list (strcat "\nEinfuegepunkt fuer " fname " [ENTER=Ende]: "))))
(and (not (vl-catch-all-error-p res)) res)
)
(setq pt res)
(command "_.INSERT" pfad pt "" "" pause)
(setq n (1+ n))
)
(setvar "ATTREQ" oldattreq)
(princ (strcat "\n>>> " (itoa n) " x " fname " eingefuegt."))
)
)
(princ)
)
(defun c:ILS_SCANNER_INSERT ()
(ils-insert-sensor "Scanner")
)
(defun c:ILS_SEPARATOR_INSERT ()
(ils-insert-sensor "Separator_SP")
)
;; --- ILS / Foerderer ---
(defun c:ILS_TEF_Strecke ()
(princ "\n[DUMMY] ILS_TEF_Strecke aufgerufen")
@@ -219,6 +268,20 @@
(command "_.BEDIT" bname)
)
;; Gefaellestrecke-Bloecke (GF_n) -> GEFAELLESTRECKE_EDIT (DCL-Dialog)
((wcmatch bname "GF_*")
(princ (ssg-textf "cmd-gefaelle-bearbeiten" (list bname)))
(c:GEFAELLESTRECKE_EDIT)
)
;; VarioFoerderer-Bloecke (VF_n) -> VARIOFOERDERER_EDIT (DCL-Dialog);
;; weist Bloecke ohne SSG_VF_EDIT-XDATA (Etage/Linienzug/Altbestand)
;; intern selbst ab, siehe c:VARIOFOERDERER_EDIT in vf_standard.lsp.
((wcmatch bname "VF_*")
(princ (ssg-textf "cmd-variofoerderer-bearbeiten" (list bname)))
(c:VARIOFOERDERER_EDIT)
)
;; Omniflo-Bloecke -> OMNI_EDIT
;; Erkennung: TEILEART-Attribut vorhanden, AP110-Blockname oder rein numerisch
((progn
+24 -15
View File
@@ -6,11 +6,14 @@
;;; Gefaellestrecke) und schreibt die Anzahlen in die Attribute
;;; des jeweiligen ILS-Blocks. Anschliessend QSAVE.
;;;
;;; Zuordnung eines Sensors zu einem ILS-Block:
;;; - Der geometrische Mittelpunkt (X/Y) des Sensors (Zentrum
;;; seiner eigenen Bounding-Box, unabhaengig vom $INSBASE)
;;; muss in der achsparallelen Bounding-Box des ILS-Blocks
;;; liegen (Z wird ignoriert).
;;; Zuordnung eines Sensors zu einem ILS-Block (Z wird ignoriert):
;;; - Scanner: der Einfuegepunkt (X/Y) muss in der Bounding-Box
;;; des ILS-Blocks liegen. Die 3D-Geometrie des Scanners kann
;;; weit vom Einfuegepunkt entfernt sein, daher zaehlt hier der
;;; Einfuegepunkt (dort klickt der Benutzer auf den Block).
;;; - Separator: der geometrische Mittelpunkt (Zentrum der eigenen
;;; Bounding-Box, unabhaengig vom $INSBASE) muss in der
;;; Bounding-Box des ILS-Blocks liegen.
;;; - Liegt der Punkt in mehreren Boxen (Ueberlappung), wird
;;; der ILS-Block mit dem naechstgelegenen Box-Zentrum gewaehlt.
;;; - Ein optionaler Toleranzrand (*senstol*) vergroessert die
@@ -112,17 +115,23 @@
)
;;; ------------------------------------------------------------
;;; Referenzpunkt eines Sensors: geometrischer Mittelpunkt seiner
;;; eigenen Bounding-Box (X/Y). Unabhaengig vom $INSBASE der
;;; Sensor-DWG. Fallback auf den Einfuegepunkt, falls die Box
;;; nicht ermittelbar ist.
;;; Referenzpunkt eines Sensors (X/Y), je nach Typ:
;;; - Scanner : Einfuegepunkt (DXF-Gruppe 10).
;;; - Separator : geometrischer Mittelpunkt seiner eigenen
;;; Bounding-Box (unabhaengig vom $INSBASE),
;;; Fallback auf den Einfuegepunkt.
;;; ------------------------------------------------------------
(defun cs-sensor-point (ent ed / bb)
(setq bb (cs-bbox ent))
(if bb
(list (/ (+ (nth 0 bb) (nth 2 bb)) 2.0)
(/ (+ (nth 1 bb) (nth 3 bb)) 2.0))
(defun cs-sensor-point (ent ed kind / bb)
(if (eq kind 'scanner)
(cdr (assoc 10 ed))
(progn
(setq bb (cs-bbox ent))
(if bb
(list (/ (+ (nth 0 bb) (nth 2 bb)) 2.0)
(/ (+ (nth 1 bb) (nth 3 bb)) 2.0))
(cdr (assoc 10 ed))
)
)
)
)
@@ -271,7 +280,7 @@
(setq kind (cs-sensor-kind nm))
(if kind
(progn
(setq pt (cs-sensor-point ent ed))
(setq pt (cs-sensor-point ent ed kind))
(if (eq kind 'scanner)
(setq scanpts (cons pt scanpts))
(setq seppts (cons pt seppts)))))
+26 -5
View File
@@ -1151,8 +1151,9 @@
(if (car (atoms-family 1 '("SSG-ID-GENERATE")))
(ssg-id-generate vf-insert))
(princ (ssg-textf "vfc-block-erstellt-eingefuegt" (list vf-bname)))
vf-insert
)
(princ (ssg-text "vfc-fehler-keine-entities"))
(progn (princ (ssg-text "vfc-fehler-keine-entities")) nil)
)
)
@@ -1247,10 +1248,10 @@
(princ "\n 3 - 3D-Objekte stueckweise (Vorwaerts-Nachbau, in Arbeit)")
(setq wahl (getint "\nIhre Wahl (1/2/3) [1]: "))
;; Konsolen-Nummer -> interne Funktion:
;; 2 = fertiger Ziel-Hoehe-Modus (intern vf-linienzug-modus3)
;; 3 = alter Vorwaerts-Nachbau (intern vf-linienzug-modus2, wird umgebaut)
(cond ((= wahl 2) (vf-linienzug-modus3))
((= wahl 3) (vf-linienzug-modus2))
;; 2 = fertiger Ziel-Hoehe-Modus (intern vf-linienzug-modus2)
;; 3 = alter Vorwaerts-Nachbau (intern vf-linienzug-modus3, wird umgebaut)
(cond ((= wahl 2) (vf-linienzug-modus2))
((= wahl 3) (vf-linienzug-modus3))
(t (vf-linienzug-modus)))
(exit)
)
@@ -1260,6 +1261,26 @@
(setq vf-nummer (vf-next-number))
(princ (ssg-textf "vfc-naechste-vf-nummer" (list (itoa vf-nummer))))
;; 2b. Standardfall (anlage-typ "standard") + Werteingabe -> DCL-Dialog
;; (dcl/variofoerderer.dcl, siehe vf_standard.lsp: vfs-standard-dialog-ablauf).
;; 3D-Linie-Eingabe und alle anderen Anlagen-Typen (Etage, Linienzug) bleiben
;; unveraendert interaktiv (fallen unten in den bestehenden Konsolen-Ablauf,
;; der die Eingabemodus-Frage dabei erneut stellt - siehe vf-eingabe-abfragen).
(if (= anlage-typ "standard")
(progn
(princ (ssg-text "vfc-eingabemodus-header"))
(princ (ssg-text "vfc-eingabemodus-3dlinie"))
(princ (ssg-text "vfc-eingabemodus-werte"))
(setq antwort (getstring (ssg-text "vfc-prompt-wahl-1-2-ohne-default")))
(if (= antwort "2")
(progn
(vfs-standard-dialog-ablauf vf-nummer)
(exit)
)
)
)
)
;; 3. Gemeinsame Eingabe (deltaL, deltaH, richtung, startpunkt) - richtung
;; steht bei beiden Eingabemodi (Werteingabe UND 3D-Linie) bereits fest.
(setq eingabe (vf-eingabe-abfragen))
+94 -89
View File
@@ -1386,7 +1386,7 @@
(foreach x liste (setq d (abs (- x w))) (if (< d bd) (setq bd d best x)))
best)
(defun vf-linienzug-modus2 ( / ss k obj-liste startpunkt start-hoehe as-seite
(defun vf-linienzug-modus3 ( / ss k obj-liste startpunkt start-hoehe as-seite
es-seite kette segmente n i seg typ hz laenge
bwinkel bseite frame antwort winkel deltaL
anzahl-gf anzahl-vf vfl-nummer lastEnt hoehe-bis
@@ -1770,7 +1770,7 @@
(- (/ (- ep-na (* perp-es np-na)) dp-na) cc)
100.0))))
(defun vf-linienzug-modus3 ( / ss k obj-liste startpunkt start-hoehe as-seite
(defun vf-linienzug-modus2 ( / ss k obj-liste startpunkt start-hoehe as-seite
endpunkt end-hoehe es-seite kette segmente n i seg
typ hz laenge bwinkel bseite antwort winkel klass
plan e ecke-bad vf-start vf-ende dz z-front
@@ -1791,57 +1791,60 @@
rad3v feste-vf dH-adj dir-x dir-y fill-D end-hz
gf-total br-gf-mode br-gf2-exp filler-A-len filler-a-done)
(princ "\n\n=========================================")
(princ "\n VF-LINIENZUG - Modus 2: Pfad + Ziel-Hoehe (fertig; Anker + Solver + Bau)")
(princ (ssg-text "vfl-m3-titel"))
(princ "\n=========================================")
;; Abhaengigkeit Gefaellestrecke-Modul
(if (null (car (atoms-family 1 '("GF-INSERT-HZ-INCL-SCALED"))))
(progn (alert "Gefaellestrecke-Modul nicht geladen!") (exit)))
(progn (alert (ssg-text "vfl-m3-alert-gf-modul")) (exit)))
(if (or (not *lib-initialized*) (null bogen-auf)) (init-bibliothek))
;; --- 1. Pfad-Objekte waehlen ---
(princ "\n\nPfad-Objekte waehlen (Linien/Boegen):")
(princ (ssg-text "vfl-m3-pfad-waehlen"))
(setq ss (ssget '((0 . "LINE,ARC"))))
(if (null ss) (progn (princ "\nKeine Objekte gewaehlt - Abbruch.") (exit)))
(if (null ss) (progn (princ (ssg-text "vfl-m3-keine-objekte")) (exit)))
(setq obj-liste '() k 0)
(repeat (sslength ss)
(setq obj-liste (cons (vlax-ename->vla-object (ssname ss k)) obj-liste))
(setq k (1+ k)))
;; --- 2. Startpunkt + Z + AS-Seite ---
(setq startpunkt (vfl-getpoint nil "\n\nStartpunkt der Kette (hoehere Seite) waehlen: "))
(if (null startpunkt) (progn (princ "\nAbgebrochen.") (exit)))
(setq start-hoehe (getreal (strcat "\nHoehe (Z) des Startpunkts ["
(rtos (caddr startpunkt) 2 1) "]: ")))
(setq startpunkt (vfl-getpoint nil (ssg-text "vfl-m3-prompt-startpunkt")))
(if (null startpunkt) (progn (princ (ssg-text "gf-status-abgebrochen")) (exit)))
(setq start-hoehe (getreal (ssg-textf "vfl-prompt-hoehe-startpunkt"
(list (rtos (caddr startpunkt) 2 1)))))
(if (null start-hoehe) (setq start-hoehe (caddr startpunkt)))
(setq startpunkt (list (car startpunkt) (cadr startpunkt) start-hoehe))
(setq *vfl-as-winkel* (vf-frage-element-winkel "vf-winkel-aus-header")) ; 30/90 vor Seite
(princ "\n\nAUS-Element - Seite waehlen:\n 1 - Links\n 2 - Rechts")
(setq as-seite (if (= (getstring "\nIhre Wahl (1/2) [1]: ") "2") "rechts" "links"))
(princ (ssg-text "gf-seite-aus-header"))
(princ (ssg-text "gf-seite-links"))
(princ (ssg-text "gf-seite-rechts"))
(setq as-seite (if (= (getstring (ssg-text "prompt-wahl-1-2")) "2") "rechts" "links"))
(vf-set-as-masse *vfl-as-winkel* as-seite) ; Masse fuer Variante
;; --- 3. Endpunkt + Z + ES-Seite (NEU in Modus 3) ---
(setq endpunkt (vfl-getpoint nil "\n\nEndpunkt der Kette (Ziel) waehlen: "))
(if (null endpunkt) (progn (princ "\nAbgebrochen.") (exit)))
(setq end-hoehe (getreal (strcat "\nZiel-Hoehe (Z) des Endpunkts ["
(rtos (caddr endpunkt) 2 1) "]: ")))
(setq endpunkt (vfl-getpoint nil (ssg-text "vfl-m3-prompt-endpunkt")))
(if (null endpunkt) (progn (princ (ssg-text "gf-status-abgebrochen")) (exit)))
(setq end-hoehe (getreal (ssg-textf "vfl-m3-prompt-zielhoehe"
(list (rtos (caddr endpunkt) 2 1)))))
(if (null end-hoehe) (setq end-hoehe (caddr endpunkt)))
(setq endpunkt (list (car endpunkt) (cadr endpunkt) end-hoehe))
(setq *vfl-es-winkel* (vf-frage-element-winkel "vf-winkel-ein-header")) ; 30/90 vor Seite
(princ "\n\nEIN-Element (ES) - Seite waehlen:\n 1 - Links\n 2 - Rechts")
(setq es-seite (if (= (getstring "\nIhre Wahl (1/2) [1]: ") "2") "rechts" "links"))
(princ (ssg-text "gf-seite-ein-header"))
(princ (ssg-text "gf-seite-links"))
(princ (ssg-text "gf-seite-rechts"))
(setq es-seite (if (= (getstring (ssg-text "prompt-wahl-1-2")) "2") "rechts" "links"))
(vf-set-es-masse *vfl-es-winkel* es-seite) ; Masse fuer Variante
;; --- 4. Sortieren + Analysieren + Eck-Vorpruefung ---
(setq kette (gf-sortiere-objekte obj-liste startpunkt))
(if (null kette)
(progn (princ "\nFEHLER: Pfad nicht sortierbar (haengt er lueckenlos zusammen?).") (exit)))
(progn (princ (ssg-text "vfl-m3-fehler-nicht-sortierbar")) (exit)))
(setq segmente (gf-analysiere-kette kette))
(setq ecke-bad (vfl2-pruefe-eckwinkel kette 5.0))
(if ecke-bad
(progn
(alert (strcat "Kein passender Bogen: Eck-Winkel " (rtos ecke-bad 2 1)
" Grad ist nicht ~30/60/90.\nBitte die Winkel anpassen."))
(alert (ssg-textf "vfl-m3-alert-eckwinkel" (list (rtos ecke-bad 2 1))))
(exit)))
;; --- 5. Klassifizierung (Phase A: nur speichern, nichts bauen) ---
@@ -1852,36 +1855,36 @@
(setq seg (nth i segmente) typ (car seg) hz (cadr seg) laenge (caddr seg))
(cond
((= typ "Linie")
(princ (strcat "\n\nSegment " (itoa (1+ i)) "/" (itoa n)
": Gerade L=" (rtos laenge 2 0) " mm hz=" (rtos hz 2 1)))
(princ (ssg-textf "vfl-m3-seg-gerade"
(list (itoa (1+ i)) (itoa n) (rtos laenge 2 0) (rtos hz 2 1))))
(cond
;; Direkt nach einer Vario-Kurve: automatisch VF (keine Abfrage) -
;; die Kurve sitzt mitten in der VF-Einheit, es MUSS VF folgen.
(nach-kurve
(princ "\n (automatisch VF - Segment folgt direkt auf eine Vario-Kurve)")
(princ (ssg-text "vfl-m3-auto-vf"))
(setq plan (cons (list "Linie" hz laenge "VF" nil) plan))
(setq nach-kurve nil))
(t
(princ "\n Typ? 1 = GF (Eingabe-Winkel) 2 = VF (Bruecke)")
(setq antwort (getstring "\nIhre Wahl (1/2) [1]: "))
(princ (ssg-text "vfl-m3-typ-gerade"))
(setq antwort (getstring (ssg-text "prompt-wahl-1-2")))
(if (= antwort "2")
(setq plan (cons (list "Linie" hz laenge "VF" nil) plan))
(progn
(setq winkel (getreal "\n GF-Neigung in Grad [3]: "))
(setq winkel (getreal (ssg-text "vfl-m3-prompt-gf-neigung")))
(if (null winkel) (setq winkel 3.0))
(if (> winkel 3.0)
(progn (princ "\n Hinweis: GF max. 3 Grad - auf 3 begrenzt.") (setq winkel 3.0)))
(progn (princ (ssg-text "vfl-m3-hinweis-gf-max")) (setq winkel 3.0)))
(setq plan (cons (list "Linie" hz laenge "GF" winkel) plan)))))))
((= typ "Bogen")
(setq bwinkel (nth 3 seg) bseite (nth 4 seg))
(princ (strcat "\n\nSegment " (itoa (1+ i)) "/" (itoa n)
": Eck/Bogen " (itoa bwinkel) " Grad " bseite))
(princ "\n Typ? 1 = GF-Bogen 2 = Vario-Kurve")
(setq antwort (getstring "\nIhre Wahl (1/2) [1]: "))
(princ (ssg-textf "vfl-m3-seg-bogen"
(list (itoa (1+ i)) (itoa n) (itoa bwinkel) bseite)))
(princ (ssg-text "vfl-m3-typ-bogen"))
(setq antwort (getstring (ssg-text "prompt-wahl-1-2")))
(if (= antwort "2")
(progn
(princ "\n Vario-Kurve - Variante? 1 = Aussen 2 = Innen")
(setq kv-variante (if (= (getstring "\nIhre Wahl (1/2) [2]: ") "1") "aussen" "innen"))
(princ (ssg-text "vfl-m3-variante-frage"))
(setq kv-variante (if (= (getstring (ssg-text "vfl-prompt-wahl-1-2-def2")) "1") "aussen" "innen"))
(setq plan (cons (list "Bogen" hz laenge bwinkel bseite "Vario-Kurve" kv-variante) plan))
(setq nach-kurve t)) ; naechste Gerade automatisch VF
(progn
@@ -1905,9 +1908,9 @@
(if (/= vf-count 1)
(progn
(princ (strcat "\n\n[M3a] Gefundene VF-Laeufe: " (itoa vf-count)))
(princ "\n[M3a] Genau EIN VF-Lauf noetig (GF...VF...GF; Vario-Kurven duerfen im Lauf liegen).")
(princ "\n[M3a] Mehrere/keine VF-Laeufe -> M3b spaeter.")
(princ (ssg-textf "vfl-m3-vf-laeufe" (list (itoa vf-count))))
(princ (ssg-text "vfl-m3-vf-lauf-noetig"))
(princ (ssg-text "vfl-m3-vf-lauf-m3b"))
(exit)))
;; Traeger-Stueck = laengste VF-Gerade im Lauf (traegt die ganze Hoehe).
(setq carrier-idx -1 i vf-start)
@@ -1918,7 +1921,7 @@
(setq carrier-idx i)))
(setq i (1+ i)))
(if (< carrier-idx 0)
(progn (princ "\n[M3a] VF-Lauf ohne VF-Gerade - Abbruch.") (exit)))
(progn (princ (ssg-text "vfl-m3-vf-lauf-ohne-gerade")) (exit)))
;; --- 7. Anker rechnen ---
;; Vorwaerts: Start-Z durch alle Front-Segmente (Index < vf-start).
@@ -1947,31 +1950,30 @@
;; --- 8. Anker-Report (noch kein Bauen) ---
(princ "\n\n=========================================")
(princ "\n M3a ANKER-VORSCHAU (grob geschaetzt; exakte Werte beim Bau)")
(princ (ssg-text "vfl-m3-anker-vorschau-header"))
(princ "\n=========================================")
(princ (strcat "\n Start-Hoehe Z: " (rtos (float start-hoehe) 2 1) " mm"))
(princ (strcat "\n Ziel-Hoehe Z: " (rtos (float end-hoehe) 2 1) " mm"))
(princ (strcat "\n delta-H gesamt: " (rtos dH-gesamt 2 1) " mm (positiv = Abfall)"))
(princ (strcat "\n VF-Lauf: Segment " (itoa (1+ vf-start)) ".." (itoa (1+ vf-ende))))
(princ (strcat "\n Front-Anker Z: " (rtos z-front 2 1) " mm (vorwaerts von AS)"))
(princ (strcat "\n Junction-Anker Z: " (rtos z-junction 2 1) " mm (rueckwaerts von ES)"))
(princ (ssg-textf "vfl-m3-start-hoehe" (list (rtos (float start-hoehe) 2 1))))
(princ (ssg-textf "vfl-m3-ziel-hoehe" (list (rtos (float end-hoehe) 2 1))))
(princ (ssg-textf "vfl-m3-delta-h-gesamt" (list (rtos dH-gesamt 2 1))))
(princ (ssg-textf "vfl-m3-vf-lauf-segmente" (list (itoa (1+ vf-start)) (itoa (1+ vf-ende)))))
(princ (ssg-textf "vfl-m3-front-anker-vorschau" (list (rtos z-front 2 1))))
(princ (ssg-textf "vfl-m3-junction-anker-vorschau" (list (rtos z-junction 2 1))))
;; Vorzeichen = Richtung (VF ist angetrieben, kann steigen UND fallen).
(setq richtn (cond ((< dH-bruecke -0.1) "Auf (steigt)")
((> dH-bruecke 0.1) "Ab (faellt)")
(t "horizontal")))
(setq richtn (cond ((< dH-bruecke -0.1) (ssg-text "vfl-m3-richtung-auf"))
((> dH-bruecke 0.1) (ssg-text "vfl-m3-richtung-ab"))
(t (ssg-text "vfl-m3-richtung-horizontal"))))
(setq req-w (if (> span-bruecke 1.0)
(* (atan (/ (abs dH-bruecke) span-bruecke)) (/ 180.0 pi))
0.0))
(princ (strcat "\n --> Bruecke: delta-H = " (rtos dH-bruecke 2 1)
" mm ueber Spannweite " (rtos span-bruecke 2 0) " mm"))
(princ (strcat "\n Richtung: VF-" richtn))
(princ "\n (VF ist angetrieben - kann STEIGEN und FALLEN; Vorzeichen = nur Auf/Ab)")
(princ (strcat "\n grobe mittlere Neigung ueber Spannweite: ~" (rtos req-w 2 1) " Grad"))
(princ (ssg-textf "vfl-m3-bruecke-dh" (list (rtos dH-bruecke 2 1) (rtos span-bruecke 2 0))))
(princ (ssg-textf "vfl-m3-bruecke-richtung" (list richtn)))
(princ (ssg-text "vfl-m3-vf-angetrieben"))
(princ (ssg-textf "vfl-m3-mittlere-neigung" (list (rtos req-w 2 1))))
(if (> req-w 51.0)
(princ "\n WARNUNG: ~Neigung > 51 Grad -> zu steil fuer Vario (Magnitude infeasibel).")
(princ "\n -> innerhalb Vario-Bereich (3..51 Grad), grobe Orientierung."))
(princ (ssg-text "vfl-m3-warnung-zu-steil"))
(princ (ssg-text "vfl-m3-vario-bereich-ok")))
(princ "\n (Anker oben = grobe Vorschau; exakte Werte werden beim Bau GEMESSEN)")
(princ (ssg-text "vfl-m3-anker-hinweis"))
(princ "\n=========================================")
;; ================= PHASE B: BAUEN (messen statt schaetzen) =================
@@ -1990,7 +1992,7 @@
(setq i (1+ i)))
;; --- B1: FRONT-Lauf bauen (Segmente 0 .. vf-start-1) -> Front-Anker MESSEN ---
(princ "\n\n>>> Phase B1: Front-Lauf (AS + GF) bauen ...")
(princ (ssg-text "vfl-m3-phase-b1"))
(setq i 0)
(while (< i vf-start)
(setq seg (nth i plan) typ (car seg) hz (cadr seg))
@@ -2016,9 +2018,9 @@
(if (= klass "GF-Bogen")
(progn
(if (null frame)
(progn (alert "Kette beginnt mit einem Bogen - bitte erst eine Gerade.") (exit)))
(progn (alert (ssg-text "vfl-m3-alert-beginnt-bogen")) (exit)))
(setq frame (vfl-insert-gf-bogen-block frame bwinkel bseite)))
(princ "\n >>> [M3a] Vario-Kurve im Front-Lauf - uebersprungen."))))
(princ (ssg-text "vfl-m3-kurve-front-uebersprungen")))))
(setq i (1+ i)))
;; Front-Anker (gemessen). Falls die VF-Bruecke ganz vorne liegt: AS jetzt setzen.
@@ -2066,11 +2068,11 @@
;; Kletter-Segment als Standard-Vario loesen; GF wird BERECHNET (L_GF) und der
;; Winkel WAEHLBAR (mehrere gueltige -> Nutzer waehlt). feste = 800 (Umlenk+Sep;
;; Motor sitzt am Kettenende). Die flache Zone gleicht danach die Laenge aus.
(princ "\n\n --- STANDARD-VARIO (Kletter-Segment) + flache Zone ---")
(princ (strcat "\n Front-Anker (gemessen): " (rtos z-front 2 1) " mm"))
(princ (strcat "\n Junction (exakt): " (rtos z-junction 2 1) " mm"))
(princ (strcat "\n Kletterhoehe " (rtos target-climb 2 1) " mm | Kletterer "
(itoa n-climb) " | Kurven " (itoa nkurve) " | kurze VF " (itoa nonclimber-cnt)))
(princ (ssg-text "vfl-m3-standard-vario-header"))
(princ (ssg-textf "vfl-m3-front-anker-gemessen" (list (rtos z-front 2 1))))
(princ (ssg-textf "vfl-m3-junction-exakt" (list (rtos z-junction 2 1))))
(princ (ssg-textf "vfl-m3-kletter-info"
(list (rtos target-climb 2 1) (itoa n-climb) (itoa nkurve) (itoa nonclimber-cnt))))
;; feste-Horizontal + Hoehen-Anpassung fuer den Solver:
;; - Mit flacher Zone: Motor sitzt am Kettenende (nicht im Kletter-Segment) ->
;; feste = 800 (Umlenk+Sep). berechne rechnet Motor-/Uebergangs-Abstieg NICHT,
@@ -2083,24 +2085,28 @@
(setq feste-vf 1300.0 dH-adj dH-bruecke))
(setq wahl3 (vfl3-waehle-winkel climber-span dH-adj feste-vf))
(if (null wahl3)
(progn (princ "\n KEIN passender Vario-Winkel -> infeasibel (Front bereits gebaut).")
(progn (princ (ssg-text "vfl-m3-kein-winkel"))
(princ) (exit)))
(setq br-winkel (car wahl3) gf-total (cadr wahl3) br-lvf (caddr wahl3) br-richtn (cadddr wahl3))
;; GF-Verteilung: 1 = alles am Einlauf (GF1); 2 = 1/2 GF1 + 1/2 GF2. Bei 1/2/1/2
;; wird der im Kletter-Segment durch das halbe GF1 frei werdende Platz mit einem
;; horizontalen Fueller-A gefuellt; GF2 (~1/2 L_GF) sitzt hinter dem Motor, der
;; ES-Laengen-Abschluss zieht seinen Fussabdruck ab (Fueller-B wird kuerzer).
(princ "\n\n GF-Verteilung: 1 - alles am Einlauf (GF1) 2 - 1/2 GF1 + 1/2 GF2")
(setq br-gf-mode (if (= (getstring "\n Ihre Wahl (1/2) [1]: ") "2") 2 1))
(princ (ssg-text "vfl-m3-gf-verteilung"))
(setq br-gf-mode (if (= (getstring (ssg-text "prompt-wahl-1-2")) "2") 2 1))
(if (= br-gf-mode 2)
(setq br-gf1 (/ gf-total 2.0) br-gf2-exp (/ gf-total 2.0)
filler-A-len (* (/ gf-total 2.0) (cos rad3v)))
(setq br-gf1 gf-total br-gf2-exp 0.0 filler-A-len 0.0))
(setq filler-a-done nil)
(princ (strcat "\n -> Vario " (itoa br-winkel) " (" br-richtn "), L_VF " (rtos br-lvf 2 0)
" mm, GF gesamt " (rtos gf-total 2 0) " mm, Verteilung "
(if (= br-gf-mode 2) "1/2 GF1 + 1/2 GF2" "alles GF1")
" (GF2-Rest = Mess-Feinkorrektur)"))
(princ (ssg-textf "vfl-m3-vario-ergebnis"
(list (itoa br-winkel)
(if (= br-richtn "Auf") (ssg-text "vfl-m3-richtung-auf-kurz")
(ssg-text "vfl-m3-richtung-ab-kurz"))
(rtos br-lvf 2 0)
(rtos gf-total 2 0)
(if (= br-gf-mode 2) (ssg-text "vfl-m3-vert-halb")
(ssg-text "vfl-m3-vert-ganz")))))
;; --- B3: Standard-Vario (Klettern, 3-Grad-Basis) + flache Zone (0 Grad) ---
;; Die flache Zone (Vario-Kurve + horizontaler Fueller) haengt EINMAL ueber auf_3
@@ -2171,13 +2177,12 @@
(setq gf2-drop (- z-aftermotor z-junction))
(if (< gf2-drop 0.0)
(progn
(princ (strcat "\n WARNUNG: Koerper klettert zu wenig - GF2<0 (fehlen "
(rtos (- gf2-drop) 2 1) " mm). Winkel zu flach; dZ nicht exakt."))
(princ (ssg-textf "vfl-m3-warnung-gf2-negativ" (list (rtos (- gf2-drop) 2 1))))
(setq gf2-drop 0.0)))
(setq gf2-planar (/ gf2-drop (/ (sin (* 3.0 (/ pi 180.0))) (cos (* 3.0 (/ pi 180.0))))))
(if (> gf2-planar 0.1)
(progn
(princ (strcat "\n GF2 (gemessener Ausgleich): L=" (rtos gf2-planar 2 1) " mm"))
(princ (ssg-textf "vfl-m3-gf2-ausgleich" (list (rtos gf2-planar 2 1))))
(setq frame (vfl-insert-gf-segment pt letzt-koerper-hz gf2-planar 3))
(vfl-acc-gf-seg (/ gf2-planar (cos (* 3.0 (/ pi 180.0)))) 3))
(setq frame (vfl-frame-3grad pt letzt-koerper-hz)))
@@ -2199,11 +2204,11 @@
(setq bwinkel (nth 3 seg) bseite (nth 4 seg) klass (nth 5 seg))
(if (= klass "GF-Bogen")
(setq frame (vfl-insert-gf-bogen-block frame bwinkel bseite))
(princ "\n >>> [M3a] Vario-Kurve im Back-Lauf - uebersprungen."))))
(princ (ssg-text "vfl-m3-kurve-back-uebersprungen")))))
(setq i (1+ i)))
;; --- B5: Kettenende Separator + ES ---
(if (null frame) (progn (princ "\nNichts gebaut - Abbruch.") (exit)))
(if (null frame) (progn (princ (ssg-text "vfl-m3-nichts-gebaut")) (exit)))
(setq frame (vfl-insert-es-element "GF" frame (car (frame->hz-winkel frame))
(if letzt-winkel letzt-winkel 3.0) (caddr (car frame)) es-seite))
@@ -2213,25 +2218,25 @@
(vfl-planar-dist startpunkt (car frame)) as-seite es-seite startpunkt lastEnt)
(setq soll-ende endpunkt ist-ende (car frame))
(princ "\n\n=========================================")
(princ "\n>>> VF-Linienzug (Modus 3, M3a) gebaut! <<<")
(princ (strcat "\n Ziel (Soll): X=" (rtos (car soll-ende) 2 1)
" Y=" (rtos (cadr soll-ende) 2 1) " Z=" (rtos (caddr soll-ende) 2 1)))
(princ (strcat "\n ES (Ist): X=" (rtos (car ist-ende) 2 1)
" Y=" (rtos (cadr ist-ende) 2 1) " Z=" (rtos (caddr ist-ende) 2 1)))
(princ (strcat "\n Abweichung: dX=" (rtos (- (car ist-ende) (car soll-ende)) 2 1)
" dY=" (rtos (- (cadr ist-ende) (cadr soll-ende)) 2 1)
" dZ=" (rtos (- (caddr ist-ende) (caddr soll-ende)) 2 1) " mm"))
(princ (ssg-text "vfl-m3-fertig-header"))
(princ (ssg-textf "vfl-m3-ziel-soll"
(list (rtos (car soll-ende) 2 1) (rtos (cadr soll-ende) 2 1) (rtos (caddr soll-ende) 2 1))))
(princ (ssg-textf "vfl-m3-es-ist"
(list (rtos (car ist-ende) 2 1) (rtos (cadr ist-ende) 2 1) (rtos (caddr ist-ende) 2 1))))
(princ (ssg-textf "vfl-m3-abweichung"
(list (rtos (- (car ist-ende) (car soll-ende)) 2 1)
(rtos (- (cadr ist-ende) (cadr soll-ende)) 2 1)
(rtos (- (caddr ist-ende) (caddr soll-ende)) 2 1))))
;; Zerlegung bezogen auf die ES-KS_AUS-ACHSE: Quer (senkrecht zur Achse) soll
;; ~0 sein (Endpunkt liegt auf der KS_AUS-Achse), Laengs = ES-Ausladung.
(setq end-hz (car (frame->hz-winkel frame))) ; KS_AUS-Achsrichtung
(setq dir-x (cos (* end-hz (/ pi 180.0))) dir-y (sin (* end-hz (/ pi 180.0))))
(princ (strcat "\n Laengs KS_AUS-Achse: "
(rtos (+ (* (- (car ist-ende) (car soll-ende)) dir-x)
(princ (ssg-textf "vfl-m3-laengs-quer"
(list (rtos (+ (* (- (car ist-ende) (car soll-ende)) dir-x)
(* (- (cadr ist-ende) (cadr soll-ende)) dir-y)) 2 1)
" mm | Quer zur Achse (soll ~0): "
(rtos (+ (* (- (car ist-ende) (car soll-ende)) (- dir-y))
(* (- (cadr ist-ende) (cadr soll-ende)) dir-x)) 2 1) " mm"))
(princ "\n (dZ=Ziel-Hoehe; Quer zur KS_AUS-Achse ~0 => Endpunkt liegt auf der Achse)")
(* (- (cadr ist-ende) (cadr soll-ende)) dir-x)) 2 1))))
(princ (ssg-text "vfl-m3-achse-hinweis"))
(princ "\n=========================================")
(princ)
)
+421
View File
@@ -699,6 +699,427 @@
endpunkt
)
;; ============================================================
;; DCL-DIALOG (Standardfall) - dcl/variofoerderer.dcl
;; Ersetzt die interaktive Werteingabe aus vf-eingabe-abfragen
;; (Konsolen-Modus "Werteingabe") fuer anlage-typ "standard" durch
;; zwei DCL-Dialoge: Basis-Eingabe und Winkel/Verteilung. Die
;; 3D-Linie-Eingabe sowie die Typen "etage"/"linienzug" bleiben
;; unveraendert interaktiv (siehe Verzweigung in c:VarioFoerderer).
;; ============================================================
;; Basis-Eingabe (Dialog 1): deltaL, deltaH, Richtung, Einfuegehoehe,
;; Fahrtrichtung, Seite.
;; prefill: Assoziationsliste zur Vorbelegung (fuer VARIOFOERDERER_EDIT) mit
;; Schluesseln "deltaL" "deltaH" "richtung" "einfuegehoehe" "hz" "seite"
;; - oder nil fuer Neuanlage mit Defaults.
;; Rueckgabe: (deltaL deltaH richtung einfuegehoehe hz seite) oder nil bei Abbruch.
(defun vfs-dialog-eingabe-basis (prefill / dcl-pfad dat ergebnis
dlg-deltal dlg-deltah dlg-richtung dlg-hoehe
dlg-fahrtrichtung dlg-seite
deltaL deltaH richtung hz seite z-start)
(setq dcl-pfad (strcat (getenv "DXFM_DCL") "/variofoerderer.dcl"))
(setq dat (load_dialog dcl-pfad))
(if (not (new_dialog "variofoerderer_basis" dat))
(progn
(if (>= dat 0) (unload_dialog dat))
(alert (ssg-textf "gf-alert-dialog-fehlt" (list dcl-pfad)))
nil
)
(progn
;; Vorbelegung: aus prefill (Edit) oder Defaults (Neuanlage)
(set_tile "deltal"
(if prefill (rtos (cdr (assoc "deltaL" prefill)) 2 0) "15000"))
(set_tile "deltah"
(if prefill (rtos (cdr (assoc "deltaH" prefill)) 2 0) "3000"))
(set_tile "einfuegehoehe"
(if prefill (rtos (cdr (assoc "einfuegehoehe" prefill)) 2 1) "0"))
(start_list "richtung")
(add_list (ssg-text "vfs-dlg-richtung-auf"))
(add_list (ssg-text "vfs-dlg-richtung-ab"))
(end_list)
(set_tile "richtung"
(if (and prefill (equal (cdr (assoc "richtung" prefill)) "Ab")) "1" "0"))
(start_list "fahrtrichtung")
(add_list (ssg-textf "gf-dlg-richtung-0" (list grad-zeichen)))
(add_list (ssg-textf "gf-dlg-richtung-90" (list grad-zeichen)))
(add_list (ssg-textf "gf-dlg-richtung-180" (list grad-zeichen)))
(add_list (ssg-textf "gf-dlg-richtung-270" (list grad-zeichen)))
(end_list)
(set_tile "fahrtrichtung"
(if prefill
(cond ((equal (cdr (assoc "hz" prefill)) 90.0 0.1) "1")
((equal (cdr (assoc "hz" prefill)) 180.0 0.1) "2")
((equal (cdr (assoc "hz" prefill)) 270.0 0.1) "3")
(t "0"))
"0"))
(start_list "seite")
(add_list (ssg-text "gf-dlg-rechts"))
(add_list (ssg-text "gf-dlg-links"))
(end_list)
(set_tile "seite"
(if (and prefill (equal (cdr (assoc "seite" prefill)) "links")) "1" "0"))
;; Actions
(action_tile "accept"
(strcat
"(setq dlg-deltal (get_tile \"deltal\"))"
"(setq dlg-deltah (get_tile \"deltah\"))"
"(setq dlg-richtung (get_tile \"richtung\"))"
"(setq dlg-hoehe (get_tile \"einfuegehoehe\"))"
"(setq dlg-fahrtrichtung (get_tile \"fahrtrichtung\"))"
"(setq dlg-seite (get_tile \"seite\"))"
"(done_dialog 1)"
)
)
(action_tile "cancel" "(done_dialog 0)")
(setq ergebnis (start_dialog))
(unload_dialog dat)
(if (= ergebnis 1)
(progn
(setq deltaL (atof dlg-deltal))
(setq deltaH (atof dlg-deltah))
(setq richtung (if (= dlg-richtung "1") "Ab" "Auf"))
(setq z-start (atof dlg-hoehe))
(setq hz
(cond ((= dlg-fahrtrichtung "1") 90.0)
((= dlg-fahrtrichtung "2") 180.0)
((= dlg-fahrtrichtung "3") 270.0)
(t 0.0)))
(setq seite (if (= dlg-seite "1") "links" "rechts"))
(list deltaL deltaH richtung z-start hz seite)
)
nil
)
)
)
)
;; Winkel/Verteilung-Eingabe (Dialog 2): Winkel-Popup aus den vorher
;; berechneten gueltigen Varianten (gueltige-winkel/ergebnis-liste, siehe
;; berechne-alle-winkel), plus L_GF-Verteilung vorne/hinten (analog Schritt
;; 8+9 in c:VarioFoerderer).
;; prefill: Assoziationsliste ("winkel" . best-winkel) ("verteilung-idx" . "0".."3")
;; ("lgf1" . mm) - oder nil fuer Vorbelegung mit dem kleinsten gueltigen Winkel.
;; Rueckgabe: (best-winkel L_GF L_VF L_GF1 L_GF2 verteilung-modus) oder nil bei Abbruch.
(defun vfs-dialog-winkel-verteilung (gueltige-winkel ergebnis-liste staustrecke-basis prefill /
dcl-pfad dat ergebnis w eintrag idx sel-idx init-verteilung
dlg-winkel dlg-verteilung dlg-lgf1
best-winkel L_GF L_VF verteilung-modus L_GF1 L_GF2)
(setq dcl-pfad (strcat (getenv "DXFM_DCL") "/variofoerderer.dcl"))
(setq dat (load_dialog dcl-pfad))
(if (not (new_dialog "variofoerderer_winkel" dat))
(progn
(if (>= dat 0) (unload_dialog dat))
(alert (ssg-textf "gf-alert-dialog-fehlt" (list dcl-pfad)))
nil
)
(progn
;; Winkel-Popup aus den gueltigen Varianten aufbauen
(start_list "winkel")
(foreach w gueltige-winkel
(setq eintrag (assoc w ergebnis-liste))
(if (= w 0)
(add_list (ssg-textf "vfs-dlg-winkel-horizontal"
(list (rtos (nth 1 eintrag) 2 1) (rtos (nth 2 eintrag) 2 1))))
(add_list (ssg-textf "vfs-dlg-winkel-option"
(list (itoa w) grad-zeichen (rtos (nth 1 eintrag) 2 1) (rtos (nth 2 eintrag) 2 1))))
)
)
(end_list)
;; Vorbelegung: Winkel aus prefill (falls noch gueltig), sonst erster
;; (kleinster) gueltiger Winkel - analog der automatischen Konsolen-Wahl.
(setq sel-idx 0 idx 0)
(if prefill
(foreach w gueltige-winkel
(if (equal w (cdr (assoc "winkel" prefill))) (setq sel-idx idx))
(setq idx (1+ idx))
)
)
(set_tile "winkel" (itoa sel-idx))
;; Verteilung: Popup + manuelles L_GF1-Feld (nur bei "Eigene Werte" aktiv)
(start_list "verteilung")
(add_list (ssg-text "vfs-dlg-verteilung-1"))
(add_list (ssg-text "vfs-dlg-verteilung-2"))
(add_list (ssg-text "vfs-dlg-verteilung-3"))
(add_list (ssg-text "vfs-dlg-verteilung-4"))
(end_list)
(setq init-verteilung (if prefill (cdr (assoc "verteilung-idx" prefill)) "0"))
(set_tile "verteilung" init-verteilung)
(set_tile "lgf1_manuell"
(if (and prefill (cdr (assoc "lgf1" prefill)))
(rtos (cdr (assoc "lgf1" prefill)) 2 1) "0"))
(mode_tile "lgf1_manuell" (if (= init-verteilung "3") 0 1))
(action_tile "verteilung"
"(mode_tile \"lgf1_manuell\" (if (= (get_tile \"verteilung\") \"3\") 0 1))")
(action_tile "accept"
(strcat
"(setq dlg-winkel (get_tile \"winkel\"))"
"(setq dlg-verteilung (get_tile \"verteilung\"))"
"(setq dlg-lgf1 (get_tile \"lgf1_manuell\"))"
"(done_dialog 1)"
)
)
(action_tile "cancel" "(done_dialog 0)")
(setq ergebnis (start_dialog))
(unload_dialog dat)
(if (= ergebnis 1)
(progn
(setq best-winkel (nth (atoi dlg-winkel) gueltige-winkel))
(setq eintrag (assoc best-winkel ergebnis-liste))
(setq L_GF (nth 1 eintrag) L_VF (nth 2 eintrag))
(setq verteilung-modus dlg-verteilung)
(cond
((= verteilung-modus "0")
(setq L_GF1 (/ L_GF 2.0) L_GF2 (/ L_GF 2.0)))
((= verteilung-modus "1")
(setq L_GF1 (float staustrecke-basis))
(setq L_GF2 (max 0.0 (- L_GF (float staustrecke-basis)))))
((= verteilung-modus "2")
(setq L_GF2 (float staustrecke-basis))
(setq L_GF1 (max 0.0 (- L_GF (float staustrecke-basis)))))
((= verteilung-modus "3")
(setq L_GF1 (atof dlg-lgf1))
(if (or (null L_GF1) (< L_GF1 0)) (setq L_GF1 (/ L_GF 2.0)))
(if (> L_GF1 L_GF) (setq L_GF1 L_GF))
(setq L_GF2 (max 0.0 (- L_GF L_GF1))))
(t (setq L_GF1 (/ L_GF 2.0) L_GF2 (/ L_GF 2.0)))
)
(list best-winkel L_GF L_VF L_GF1 L_GF2 verteilung-modus)
)
nil
)
)
)
)
;; ============================================================
;; XDATA-Metadaten fuer den Edit-Nachbau (App "SSG_VF_EDIT").
;; Markiert ein VF_n-INSERT als "mit dem Standard-Dialog erstellt" und
;; speichert die Fahrtrichtung (hz) - der einzige Wert, der sich nicht aus
;; den Sivas-Attributen rekonstruieren laesst (ANTRIEBFAHRTRICHTUNG, SEITE_AS,
;; VF_WINKEL, L_GF_m stehen dort bereits). Bewusst NICHT im Sivas-Attributsatz.
;; Ohne diese Markierung (z.B. Etage-, Linienzug- oder Altbestand-Bloecke)
;; verweigert c:VARIOFOERDERER_EDIT die Bearbeitung, um deren komplexere
;; Geometrie nicht versehentlich durch einen einfachen Neuaufbau zu ersetzen.
;; ============================================================
(if (null *vf-xdata-app*) (setq *vf-xdata-app* "SSG_VF_EDIT"))
(defun vfs-xdata-schreiben (ent hz /)
(regapp *vf-xdata-app*)
(entmod
(append (entget ent)
(list
(list -3
(list *vf-xdata-app*
(cons 1000 "standard")
(cons 1000 (rtos (float hz) 2 4)))))))
ent
)
;; XDATA lesen -> (typ-marker hz-str) oder nil.
(defun vfs-xdata-lesen (ent / xd app-data)
(setq xd (entget ent (list *vf-xdata-app*)))
(setq app-data (cdr (assoc -3 xd)))
(if app-data
(mapcar 'cdr (cdr (car app-data)))
nil
)
)
;; ============================================================
;; Gemeinsame Berechnung + Winkel/Verteilung-Dialog + Einfuegung.
;; Wird sowohl von der Neuanlage (vfs-standard-dialog-ablauf) als auch vom
;; Edit-Befehl (c:VARIOFOERDERER_EDIT) verwendet.
;; winkel-prefill: Vorbelegung fuer vfs-dialog-winkel-verteilung oder nil.
;; ============================================================
(defun vfs-standard-dialog-berechnen-einfuegen (vf-nummer deltaL deltaH richtung startpunkt hz seite
winkel-prefill /
ergebnis ergebnis-liste gueltige-winkel horizontal-info
winkelwahl best-winkel L_GF L_VF L_GF1 L_GF2 verteilung-modus
n-scanner hoehe-von hoehe-bis lastEnt vf-insert staustrecke-basis)
(setq ergebnis (berechne-standard deltaL deltaH richtung seite))
(setq ergebnis-liste (cadddr ergebnis))
(setq staustrecke-basis (ssg-cfg-or "vario" "staustrecke_basis" 1000))
;; Horizontale Zwischenstrecke als Zusatzoption (nur bei "Ab" erreichbar,
;; siehe Kommentar in c:VarioFoerderer Schritt 5b).
(setq horizontal-info nil)
(if (= richtung "Ab")
(progn
(setq horizontal-info (berechne-horizontale-mitte deltaL deltaH "Ab"))
(if (and horizontal-info (caddr horizontal-info))
(setq ergebnis-liste
(append ergebnis-liste (list (list 0 (car horizontal-info) (cadr horizontal-info) T))))
(setq horizontal-info nil)
)
)
)
(setq gueltige-winkel
(mapcar 'car
(vl-remove-if-not
(function (lambda (e) (and (nth 3 e) (numberp (nth 1 e)) (numberp (nth 2 e))
(>= (nth 1 e) 0) (>= (nth 2 e) 0))))
ergebnis-liste)))
(if (null gueltige-winkel)
(alert (ssg-textf "vfc-alert-kein-winkel"
(list (chr 916) (rtos deltaL 2 0) (rtos deltaH 2 0) richtung)))
(progn
(setq winkelwahl (vfs-dialog-winkel-verteilung gueltige-winkel ergebnis-liste staustrecke-basis winkel-prefill))
(if (null winkelwahl)
(princ (ssg-text "vfc-vorgang-abgebrochen"))
(progn
(setq best-winkel (nth 0 winkelwahl)
L_GF (nth 1 winkelwahl)
L_VF (nth 2 winkelwahl)
L_GF1 (nth 3 winkelwahl)
L_GF2 (nth 4 winkelwahl)
verteilung-modus (nth 5 winkelwahl))
(setq n-scanner 0)
(setq hoehe-von (caddr startpunkt))
(setq hoehe-bis
(cond ((= richtung "Auf") (+ hoehe-von deltaH))
((= richtung "Ab") (- hoehe-von deltaH))
(t hoehe-von)))
(setq lastEnt (vf-lastent-ohne-attribute))
(variofoerderer-einfuegen deltaL deltaH richtung best-winkel L_GF1 L_GF2 L_VF startpunkt seite hz)
(setq vf-insert
(vf-block-erstellen "standard" seite vf-nummer n-scanner
hoehe-von hoehe-bis deltaH deltaL L_VF L_GF1 L_GF2
richtung best-winkel startpunkt lastEnt hz))
(if vf-insert (vfs-xdata-schreiben vf-insert hz))
(princ "\n=========================================")
)
)
)
)
)
;; Neuanlage (Menue/Konsole -> Dialog): Startpunkt (X/Y) picken, Basis-Dialog,
;; dann gemeinsame Berechnung/Winkel-Dialog/Einfuegung.
(defun vfs-standard-dialog-ablauf (vf-nummer / eingabe deltaL deltaH richtung
z-start hz seite startpunkt startpunkt-xy)
(setq startpunkt-xy (getpoint (ssg-text "vfc-prompt-startpunkt-aus")))
(if (null startpunkt-xy) (setq startpunkt-xy '(0 0 0)))
(setq eingabe (vfs-dialog-eingabe-basis nil))
(if (null eingabe)
(princ (ssg-text "vfc-vorgang-abgebrochen"))
(progn
(setq deltaL (nth 0 eingabe)
deltaH (nth 1 eingabe)
richtung (nth 2 eingabe)
z-start (nth 3 eingabe)
hz (nth 4 eingabe)
seite (nth 5 eingabe))
(setq startpunkt (list (car startpunkt-xy) (cadr startpunkt-xy) z-start))
(vfs-standard-dialog-berechnen-einfuegen vf-nummer deltaL deltaH richtung startpunkt hz seite nil)
)
)
)
;; ============================================================
;; VARIOFOERDERER_EDIT - Doppelklick/Kontextmenue-Bearbeitung
;; ============================================================
;; Bearbeitet einen bestehenden Standard-VarioFoerderer (VF_n-Block, mit
;; SSG_VF_EDIT-XDATA) ueber die DCL-Dialoge: liest die aktuellen Parameter,
;; zeigt sie vorbelegt und baut die Strecke bei OK am selben Startpunkt neu
;; auf. Wird vom Doppelklick-Dispatcher SSG_BLOCKEDIT fuer Blocknamen "VF_*"
;; aufgerufen. Bloecke ohne SSG_VF_EDIT-XDATA (Etage, Linienzug, Altbestand)
;; werden abgewiesen, da ihre Geometrie sich nicht verlustfrei aus dem
;; einfachen Standard-Schema rekonstruieren laesst.
(defun c:VARIOFOERDERER_EDIT ( / ss ent ed bname startpunkt attribs xd
deltaL deltaH richtung z-start hz seite
eingabe vf-nummer best-winkel-attr L_GF_m-teile
prefill-basis prefill-winkel)
;; Implied Selection VOR ssg-start pruefen (ssg-start hebt Selektion auf)
(setq ss (ssget "I"))
(if (and ss (= (sslength ss) 1)
(= (cdr (assoc 0 (entget (ssname ss 0)))) "INSERT"))
(setq ent (ssname ss 0))
)
(ssg-start "VARIOFOERDERER_EDIT" '(("OSMODE") ("ATTREQ") ("ATTDIA")))
(setvar "OSMODE" 0)
(if (null ent)
(progn
(setq ss (ssget ":S" '((0 . "INSERT"))))
(if ss (setq ent (ssname ss 0)))
)
)
(if (null ent) (progn (ssg-end) (exit)))
(setq ed (entget ent))
(setq bname (cdr (assoc 2 ed)))
(if (not (wcmatch bname "VF_*"))
(progn (alert (ssg-textf "vfs-edit-kein-vf" (list bname))) (ssg-end) (exit)))
(setq xd (vfs-xdata-lesen ent))
(if (or (null xd) (/= (car xd) "standard"))
(progn (alert (ssg-textf "vfs-edit-keine-xdata" (list bname))) (ssg-end) (exit)))
(setq startpunkt (cdr (assoc 10 ed)))
(setq attribs (ssg-attrib-read ent))
(setq hz (atof (nth 1 xd)))
(setq deltaL (atof (cond ((cdr (assoc "DELTA_L_mm" attribs))) ("15000"))))
(setq deltaH (atof (cond ((cdr (assoc "DELTA_H_mm" attribs))) ("3000"))))
(setq richtung (cond ((cdr (assoc "ANTRIEBFAHRTRICHTUNG" attribs))) ("Auf")))
(setq seite (cond ((cdr (assoc "SEITE_AS" attribs))) ("rechts")))
(setq z-start (caddr startpunkt))
(setq prefill-basis
(list (cons "deltaL" deltaL) (cons "deltaH" deltaH) (cons "richtung" richtung)
(cons "einfuegehoehe" z-start) (cons "hz" hz) (cons "seite" seite)))
(setq eingabe (vfs-dialog-eingabe-basis prefill-basis))
(if (null eingabe)
(princ (ssg-text "vfc-vorgang-abgebrochen"))
(progn
(setq deltaL (nth 0 eingabe)
deltaH (nth 1 eingabe)
richtung (nth 2 eingabe)
z-start (nth 3 eingabe)
hz (nth 4 eingabe)
seite (nth 5 eingabe))
(setq startpunkt (list (car startpunkt) (cadr startpunkt) z-start))
;; Vorbelegung Winkel/Verteilung: bestehenden Winkel vorschlagen, L_GF-
;; Verteilung als "Eigene Werte" mit dem aktuellen L_GF1 (aus L_GF_m) -
;; das ist unabhaengig vom urspruenglichen Verteilungsmodus immer exakt.
(setq best-winkel-attr (atoi (cond ((cdr (assoc "VF_WINKEL" attribs))) ("0"))))
(setq L_GF_m-teile (ssg-cfg-split-comma (cond ((cdr (assoc "L_GF_m" attribs))) ("0.0,0.0"))))
(setq prefill-winkel
(list (cons "winkel" best-winkel-attr)
(cons "verteilung-idx" "3")
(cons "lgf1" (* 1000.0 (atof (car L_GF_m-teile))))))
(entdel ent)
(setq vf-nummer (vf-next-number))
(vfs-standard-dialog-berechnen-einfuegen vf-nummer deltaL deltaH richtung
startpunkt hz seite prefill-winkel)
(princ (ssg-textf "vfs-edit-neu-aufgebaut" (list bname)))
)
)
(ssg-end)
(princ)
)
;; ============================================================
;; REGISTRIERUNG
;; ============================================================
Binary file not shown.
Binary file not shown.
Binary file not shown.
+82
View File
@@ -0,0 +1,82 @@
// ============================================================
// gefaellestrecke.dcl - Gefaellestrecke Parameter-Eingabe
// Parametrische Eingabe fuer die einfache Gefaellestrecke
// (Modus 1 - Manuell) analog zum Kreisel-Dialog, ergaenzt um
// die Angabe der Einfuegehoehe.
// Eingaben entsprechen dem interaktiven Skript Gefaellestrecke.lsp:
// Abstand deltaL, Gefaellewinkel, Fahrtrichtung,
// Seite AUS-Element, Seite EIN-Element.
// ============================================================
gefaellestrecke : dialog {
label = "Gefaellestrecke erstellen";
: column {
: boxed_column {
label = "Geometrie";
: row {
: edit_box {
key = "deltal";
label = "Abstand deltaL (mm):";
edit_width = 10;
}
: edit_box {
key = "einfuegehoehe";
label = "Einfuegehoehe (mm):";
edit_width = 10;
}
}
: edit_box {
key = "winkel";
label = "Gefaellewinkel (Grad):";
edit_width = 10;
}
}
: boxed_column {
label = "Ausrichtung";
: popup_list {
key = "fahrtrichtung";
label = "Fahrtrichtung:";
width = 30;
}
}
: boxed_row {
label = "AUS-Element";
: popup_list {
key = "aus_winkel";
label = "Winkel:";
width = 12;
}
: popup_list {
key = "aus_seite";
label = "Seite:";
width = 14;
}
}
: boxed_row {
label = "EIN-Element";
: popup_list {
key = "ein_winkel";
label = "Winkel:";
width = 12;
}
: popup_list {
key = "ein_seite";
label = "Seite:";
width = 14;
}
}
}
ok_cancel;
}
+99
View File
@@ -0,0 +1,99 @@
// ============================================================
// variofoerderer.dcl - Standard-VarioFoerderer Parameter-Eingabe
// Zwei Dialoge fuer den Standardfall (anlage-typ "standard") von
// c:VarioFoerderer, ersetzen die interaktive Werteingabe (Modus
// "Werteingabe") aus vf-eingabe-abfragen / vf_core.lsp:
// Dialog 1 (variofoerderer_basis): deltaL, deltaH, Foerderrichtung,
// Einfuegehoehe, Fahrtrichtung, Seite.
// Dialog 2 (variofoerderer_winkel): Winkel (dynamisch berechnete
// gueltige Varianten), Verteilung der Gefaellestrecken vorne/hinten.
// Die 3D-Linie-Eingabe (Modus "3D-Linie") und andere Anlagen-Typen
// (Etage, Linienzug) bleiben interaktiv (Kommandozeile).
// ============================================================
variofoerderer_basis : dialog {
label = "VarioFoerderer (Standard) - Eingabe";
: column {
: boxed_column {
label = "Geometrie";
: row {
: edit_box {
key = "deltal";
label = "Horizontale Distanz deltaL (mm):";
edit_width = 10;
}
: edit_box {
key = "deltah";
label = "Hoehenunterschied deltaH (mm):";
edit_width = 10;
}
}
: row {
: popup_list {
key = "richtung";
label = "Foerderrichtung:";
width = 16;
}
: edit_box {
key = "einfuegehoehe";
label = "Einfuegehoehe (mm):";
edit_width = 10;
}
}
}
: boxed_column {
label = "Ausrichtung";
: popup_list {
key = "fahrtrichtung";
label = "Fahrtrichtung:";
width = 30;
}
: popup_list {
key = "seite";
label = "Seite:";
width = 16;
}
}
}
ok_cancel;
}
variofoerderer_winkel : dialog {
label = "VarioFoerderer (Standard) - Winkel / Verteilung";
: column {
: popup_list {
key = "winkel";
label = "Winkel:";
width = 45;
}
: boxed_column {
label = "Verteilung Gefaellestrecken (vorne/hinten)";
: popup_list {
key = "verteilung";
label = "Modus:";
width = 35;
}
: edit_box {
key = "lgf1_manuell";
label = "L_GF1 vorne (mm):";
edit_width = 10;
is_enabled = false;
}
}
}
ok_cancel;
}
+86
View File
@@ -33,6 +33,69 @@
"vfl-soll-xyz": "\n Soll: X=%1 Y=%2 Z=%3",
"vfl-ist-xyz": "\n Ist : X=%1 Y=%2 Z=%3",
"vfl-abweichung-xyz": "\n Abweichung: dX=%1 dY=%2 dZ=%3 mm",
"vfl-m3-titel": "\n VF-LINIENZUG - Modus 2: Pfad + Ziel-Hoehe (fertig; Anker + Solver + Bau)",
"vfl-m3-alert-gf-modul": "Gefaellestrecke-Modul nicht geladen!",
"vfl-m3-pfad-waehlen": "\n\nPfad-Objekte waehlen (Linien/Boegen):",
"vfl-m3-keine-objekte": "\nKeine Objekte gewaehlt - Abbruch.",
"vfl-m3-prompt-startpunkt": "\n\nStartpunkt der Kette (hoehere Seite) waehlen: ",
"vfl-prompt-hoehe-startpunkt": "\nHoehe (Z) des Startpunkts [%1]: ",
"vfl-m3-prompt-endpunkt": "\n\nEndpunkt der Kette (Ziel) waehlen: ",
"vfl-m3-prompt-zielhoehe": "\nZiel-Hoehe (Z) des Endpunkts [%1]: ",
"vfl-m3-fehler-nicht-sortierbar": "\nFEHLER: Pfad nicht sortierbar (haengt er lueckenlos zusammen?).",
"vfl-m3-alert-eckwinkel": "Kein passender Bogen: Eck-Winkel %1 Grad ist nicht ~30/60/90.\nBitte die Winkel anpassen.",
"vfl-m3-seg-gerade": "\n\nSegment %1/%2: Gerade L=%3 mm hz=%4",
"vfl-m3-auto-vf": "\n (automatisch VF - Segment folgt direkt auf eine Vario-Kurve)",
"vfl-m3-typ-gerade": "\n Typ? 1 = GF (Eingabe-Winkel) 2 = VF (Bruecke)",
"vfl-m3-prompt-gf-neigung": "\n GF-Neigung in Grad [3]: ",
"vfl-m3-hinweis-gf-max": "\n Hinweis: GF max. 3 Grad - auf 3 begrenzt.",
"vfl-m3-seg-bogen": "\n\nSegment %1/%2: Eck/Bogen %3 Grad %4",
"vfl-m3-typ-bogen": "\n Typ? 1 = GF-Bogen 2 = Vario-Kurve",
"vfl-m3-variante-frage": "\n Vario-Kurve - Variante? 1 = Aussen 2 = Innen",
"vfl-m3-vf-laeufe": "\n\n[M3a] Gefundene VF-Laeufe: %1",
"vfl-m3-vf-lauf-noetig": "\n[M3a] Genau EIN VF-Lauf noetig (GF...VF...GF; Vario-Kurven duerfen im Lauf liegen).",
"vfl-m3-vf-lauf-m3b": "\n[M3a] Mehrere/keine VF-Laeufe -> M3b spaeter.",
"vfl-m3-vf-lauf-ohne-gerade": "\n[M3a] VF-Lauf ohne VF-Gerade - Abbruch.",
"vfl-m3-anker-vorschau-header": "\n M3a ANKER-VORSCHAU (grob geschaetzt; exakte Werte beim Bau)",
"vfl-m3-start-hoehe": "\n Start-Hoehe Z: %1 mm",
"vfl-m3-ziel-hoehe": "\n Ziel-Hoehe Z: %1 mm",
"vfl-m3-delta-h-gesamt": "\n delta-H gesamt: %1 mm (positiv = Abfall)",
"vfl-m3-vf-lauf-segmente": "\n VF-Lauf: Segment %1..%2",
"vfl-m3-front-anker-vorschau": "\n Front-Anker Z: %1 mm (vorwaerts von AS)",
"vfl-m3-junction-anker-vorschau": "\n Junction-Anker Z: %1 mm (rueckwaerts von ES)",
"vfl-m3-richtung-auf": "Auf (steigt)",
"vfl-m3-richtung-ab": "Ab (faellt)",
"vfl-m3-richtung-horizontal": "horizontal",
"vfl-m3-richtung-auf-kurz": "Auf",
"vfl-m3-richtung-ab-kurz": "Ab",
"vfl-m3-bruecke-dh": "\n --> Bruecke: delta-H = %1 mm ueber Spannweite %2 mm",
"vfl-m3-bruecke-richtung": "\n Richtung: VF-%1",
"vfl-m3-vf-angetrieben": "\n (VF ist angetrieben - kann STEIGEN und FALLEN; Vorzeichen = nur Auf/Ab)",
"vfl-m3-mittlere-neigung": "\n grobe mittlere Neigung ueber Spannweite: ~%1 Grad",
"vfl-m3-warnung-zu-steil": "\n WARNUNG: ~Neigung > 51 Grad -> zu steil fuer Vario (Magnitude infeasibel).",
"vfl-m3-vario-bereich-ok": "\n -> innerhalb Vario-Bereich (3..51 Grad), grobe Orientierung.",
"vfl-m3-anker-hinweis": "\n (Anker oben = grobe Vorschau; exakte Werte werden beim Bau GEMESSEN)",
"vfl-m3-phase-b1": "\n\n>>> Phase B1: Front-Lauf (AS + GF) bauen ...",
"vfl-m3-alert-beginnt-bogen": "Kette beginnt mit einem Bogen - bitte erst eine Gerade.",
"vfl-m3-kurve-front-uebersprungen": "\n >>> [M3a] Vario-Kurve im Front-Lauf - uebersprungen.",
"vfl-m3-standard-vario-header": "\n\n --- STANDARD-VARIO (Kletter-Segment) + flache Zone ---",
"vfl-m3-front-anker-gemessen": "\n Front-Anker (gemessen): %1 mm",
"vfl-m3-junction-exakt": "\n Junction (exakt): %1 mm",
"vfl-m3-kletter-info": "\n Kletterhoehe %1 mm | Kletterer %2 | Kurven %3 | kurze VF %4",
"vfl-m3-kein-winkel": "\n KEIN passender Vario-Winkel -> infeasibel (Front bereits gebaut).",
"vfl-m3-gf-verteilung": "\n\n GF-Verteilung: 1 - alles am Einlauf (GF1) 2 - 1/2 GF1 + 1/2 GF2",
"vfl-m3-vert-halb": "1/2 GF1 + 1/2 GF2",
"vfl-m3-vert-ganz": "alles GF1",
"vfl-m3-vario-ergebnis": "\n -> Vario %1 (%2), L_VF %3 mm, GF gesamt %4 mm, Verteilung %5 (GF2-Rest = Mess-Feinkorrektur)",
"vfl-m3-warnung-gf2-negativ": "\n WARNUNG: Koerper klettert zu wenig - GF2<0 (fehlen %1 mm). Winkel zu flach; dZ nicht exakt.",
"vfl-m3-gf2-ausgleich": "\n GF2 (gemessener Ausgleich): L=%1 mm",
"vfl-m3-kurve-back-uebersprungen": "\n >>> [M3a] Vario-Kurve im Back-Lauf - uebersprungen.",
"vfl-m3-nichts-gebaut": "\nNichts gebaut - Abbruch.",
"vfl-m3-fertig-header": "\n>>> VF-Linienzug (Modus 2) gebaut! <<<",
"vfl-m3-ziel-soll": "\n Ziel (Soll): X=%1 Y=%2 Z=%3",
"vfl-m3-es-ist": "\n ES (Ist): X=%1 Y=%2 Z=%3",
"vfl-m3-abweichung": "\n Abweichung: dX=%1 dY=%2 dZ=%3 mm",
"vfl-m3-laengs-quer": "\n Laengs KS_AUS-Achse: %1 mm | Quer zur Achse (soll ~0): %2 mm",
"vfl-m3-achse-hinweis": "\n (dZ=Ziel-Hoehe; Quer zur KS_AUS-Achse ~0 => Endpunkt liegt auf der Achse)",
"gf-fehler-block-fehlt": "\n FEHLER: Block '%1' fehlt",
"gf-fehler-block-fehlt-ausruf": "\n FEHLER: Block '%1' fehlt!",
"gf-fehler-blockdatei-fehlt": "\n FEHLER: Block-Datei nicht gefunden: %1",
@@ -298,6 +361,17 @@
"vfc-einfuegen-frage": "\n\nMoechten Sie die Foerderanlage einfuegen?",
"vfc-einfuegen-optionen": "\n 1 - Ja, Module einfuegen\n 2 - Nein, abbrechen",
"vfc-vorgang-abgebrochen": "\nVorgang abgebrochen.",
"vfs-dlg-richtung-auf": "Auf",
"vfs-dlg-richtung-ab": "Ab",
"vfs-dlg-winkel-horizontal": "Horizontal (GF=%1 mm, VF=%2 mm)",
"vfs-dlg-winkel-option": "%1%2 (GF=%3 mm, VF=%4 mm)",
"vfs-dlg-verteilung-1": "Gleichmaessig (L_GF1 = L_GF2 = L_GF/2)",
"vfs-dlg-verteilung-2": "Vorne Minimum, hinten Rest",
"vfs-dlg-verteilung-3": "Hinten Minimum, vorne Rest",
"vfs-dlg-verteilung-4": "Eigene Werte eingeben",
"vfs-edit-kein-vf": "Block %1 ist keine VarioFoerderer-Strecke.",
"vfs-edit-keine-xdata": "VarioFoerderer %1 wurde nicht mit diesem Dialog erstellt (Etage/Linienzug/Altbestand) und kann hier nicht bearbeitet werden.",
"vfs-edit-neu-aufgebaut": "\nVarioFoerderer %1 neu aufgebaut.",
"vfe-alert-bib-nicht-init": "Etage-Bibliothek nicht initialisiert!",
"vfe-berechnung-header": "\n ETAGE-BERECHNUNG FUER ALLE WINKEL",
"vfe-bib-bereits-init": "\n Etage-Bibliothek bereits initialisiert.",
@@ -376,6 +450,11 @@
"cmd-kein-block-ausgewaehlt": "\nKein Block ausgewaehlt.",
"cmd-kreisel-bearbeiten": "\nKreisel bearbeiten: %1",
"cmd-eckrad-bearbeiten": "\nEckrad bearbeiten: %1",
"cmd-gefaelle-bearbeiten": "\nGefaellestrecke bearbeiten: %1",
"cmd-variofoerderer-bearbeiten": "\nVarioFoerderer bearbeiten: %1",
"gf-edit-kein-gf": "Block %1 ist keine Gefaellestrecke.",
"gf-edit-nur-einfach": "Nur einfache Gefaellestrecken (ohne Bogen) koennen ueber den Dialog bearbeitet werden.\nTYP: %1",
"gf-edit-neu-aufgebaut": "\nGefaellestrecke %1 neu aufgebaut.",
"cmd-omniflo-bearbeiten": "\nOmniflo Element bearbeiten: %1",
"cmd-attribute-bearbeiten": "\nAttribute bearbeiten: %1",
"layer-prompt-ziel-layer": "\nObjekt auf dem Ziel-Layer waehlen: ",
@@ -499,6 +578,13 @@
"gf-status-z-hoehe-ks-aus": "\n Z-Hoehe KS_AUS: %1 mm",
"gf-status-fertig": "\n>>> Fertig! <<<",
"gf-status-abgebrochen": "\nAbgebrochen.",
"gf-alert-dialog-fehlt": "Dialog-Datei nicht gefunden:\n%1",
"gf-dlg-richtung-0": "0%1 (X+, Ost)",
"gf-dlg-richtung-90": "90%1 (Y+, Nord)",
"gf-dlg-richtung-180": "180%1 (X-, West)",
"gf-dlg-richtung-270": "270%1 (Y-, Sued)",
"gf-dlg-links": "Links",
"gf-dlg-rechts": "Rechts",
"gf-status-gf-block-erstellt": "\n>>> GF-Block erstellt: %1 (%2)",
"gf-status-schritt1-aus": "\n\n1/4: %1 Fahrtrichtung=%2%3 KS_EIN-hz=%4%5 v=%6%7",
"gf-status-schritt2-staustrecke": "\n\n2/4: Staustrecke L=%1 mm hz=%2%3 v=%4%5",
+86
View File
@@ -33,6 +33,69 @@
"vfl-soll-xyz": "\n Target: X=%1 Y=%2 Z=%3",
"vfl-ist-xyz": "\n Actual: X=%1 Y=%2 Z=%3",
"vfl-abweichung-xyz": "\n Deviation: dX=%1 dY=%2 dZ=%3 mm",
"vfl-m3-titel": "\n VF LINE PATH - Mode 2: path + target height (finished; anchors + solver + build)",
"vfl-m3-alert-gf-modul": "Gefaellestrecke module not loaded!",
"vfl-m3-pfad-waehlen": "\n\nSelect path objects (lines/arcs):",
"vfl-m3-keine-objekte": "\nNo objects selected - aborting.",
"vfl-m3-prompt-startpunkt": "\n\nSelect chain start point (higher side): ",
"vfl-prompt-hoehe-startpunkt": "\nHeight (Z) of the start point [%1]: ",
"vfl-m3-prompt-endpunkt": "\n\nSelect chain end point (target): ",
"vfl-m3-prompt-zielhoehe": "\nTarget height (Z) of the end point [%1]: ",
"vfl-m3-fehler-nicht-sortierbar": "\nERROR: path cannot be sorted (is it connected without gaps?).",
"vfl-m3-alert-eckwinkel": "No matching arc: corner angle %1 deg is not ~30/60/90.\nPlease adjust the angles.",
"vfl-m3-seg-gerade": "\n\nSegment %1/%2: straight L=%3 mm hz=%4",
"vfl-m3-auto-vf": "\n (automatic VF - segment follows directly after a Vario curve)",
"vfl-m3-typ-gerade": "\n Type? 1 = GF (input angle) 2 = VF (bridge)",
"vfl-m3-prompt-gf-neigung": "\n GF slope in degrees [3]: ",
"vfl-m3-hinweis-gf-max": "\n Note: GF max. 3 deg - limited to 3.",
"vfl-m3-seg-bogen": "\n\nSegment %1/%2: corner/arc %3 deg %4",
"vfl-m3-typ-bogen": "\n Type? 1 = GF arc 2 = Vario curve",
"vfl-m3-variante-frage": "\n Vario curve - variant? 1 = Outer 2 = Inner",
"vfl-m3-vf-laeufe": "\n\n[M3a] VF runs found: %1",
"vfl-m3-vf-lauf-noetig": "\n[M3a] Exactly ONE VF run required (GF...VF...GF; Vario curves may lie within the run).",
"vfl-m3-vf-lauf-m3b": "\n[M3a] Several/no VF runs -> M3b later.",
"vfl-m3-vf-lauf-ohne-gerade": "\n[M3a] VF run without a VF straight - aborting.",
"vfl-m3-anker-vorschau-header": "\n M3a ANCHOR PREVIEW (rough estimate; exact values during build)",
"vfl-m3-start-hoehe": "\n Start height Z: %1 mm",
"vfl-m3-ziel-hoehe": "\n Target height Z: %1 mm",
"vfl-m3-delta-h-gesamt": "\n delta-H total: %1 mm (positive = descent)",
"vfl-m3-vf-lauf-segmente": "\n VF run: segment %1..%2",
"vfl-m3-front-anker-vorschau": "\n Front anchor Z: %1 mm (forward from AS)",
"vfl-m3-junction-anker-vorschau": "\n Junction anchor Z: %1 mm (backward from ES)",
"vfl-m3-richtung-auf": "up (rising)",
"vfl-m3-richtung-ab": "down (falling)",
"vfl-m3-richtung-horizontal": "horizontal",
"vfl-m3-richtung-auf-kurz": "Up",
"vfl-m3-richtung-ab-kurz": "Down",
"vfl-m3-bruecke-dh": "\n --> Bridge: delta-H = %1 mm over span %2 mm",
"vfl-m3-bruecke-richtung": "\n Direction: VF-%1",
"vfl-m3-vf-angetrieben": "\n (VF is powered - can RISE and FALL; sign = up/down only)",
"vfl-m3-mittlere-neigung": "\n rough mean slope over span: ~%1 deg",
"vfl-m3-warnung-zu-steil": "\n WARNING: ~slope > 51 deg -> too steep for Vario (magnitude infeasible).",
"vfl-m3-vario-bereich-ok": "\n -> within Vario range (3..51 deg), rough orientation.",
"vfl-m3-anker-hinweis": "\n (anchors above = rough preview; exact values are MEASURED during build)",
"vfl-m3-phase-b1": "\n\n>>> Phase B1: building front run (AS + GF) ...",
"vfl-m3-alert-beginnt-bogen": "Chain starts with an arc - please begin with a straight.",
"vfl-m3-kurve-front-uebersprungen": "\n >>> [M3a] Vario curve in front run - skipped.",
"vfl-m3-standard-vario-header": "\n\n --- STANDARD VARIO (climbing segment) + flat zone ---",
"vfl-m3-front-anker-gemessen": "\n Front anchor (measured): %1 mm",
"vfl-m3-junction-exakt": "\n Junction (exact): %1 mm",
"vfl-m3-kletter-info": "\n Climb height %1 mm | climbers %2 | curves %3 | short VF %4",
"vfl-m3-kein-winkel": "\n NO matching Vario angle -> infeasible (front already built).",
"vfl-m3-gf-verteilung": "\n\n GF distribution: 1 - all at inlet (GF1) 2 - 1/2 GF1 + 1/2 GF2",
"vfl-m3-vert-halb": "1/2 GF1 + 1/2 GF2",
"vfl-m3-vert-ganz": "all GF1",
"vfl-m3-vario-ergebnis": "\n -> Vario %1 (%2), L_VF %3 mm, GF total %4 mm, distribution %5 (GF2 remainder = measured fine correction)",
"vfl-m3-warnung-gf2-negativ": "\n WARNING: body climbs too little - GF2<0 (missing %1 mm). Angle too shallow; dZ not exact.",
"vfl-m3-gf2-ausgleich": "\n GF2 (measured compensation): L=%1 mm",
"vfl-m3-kurve-back-uebersprungen": "\n >>> [M3a] Vario curve in back run - skipped.",
"vfl-m3-nichts-gebaut": "\nNothing built - aborting.",
"vfl-m3-fertig-header": "\n>>> VF line path (mode 2) built! <<<",
"vfl-m3-ziel-soll": "\n Target (nominal): X=%1 Y=%2 Z=%3",
"vfl-m3-es-ist": "\n ES (actual): X=%1 Y=%2 Z=%3",
"vfl-m3-abweichung": "\n Deviation: dX=%1 dY=%2 dZ=%3 mm",
"vfl-m3-laengs-quer": "\n Along KS_AUS axis: %1 mm | across axis (should be ~0): %2 mm",
"vfl-m3-achse-hinweis": "\n (dZ=target height; across KS_AUS axis ~0 => end point lies on the axis)",
"gf-fehler-block-fehlt": "\n ERROR: block '%1' missing",
"gf-fehler-block-fehlt-ausruf": "\n ERROR: block '%1' missing!",
"gf-fehler-blockdatei-fehlt": "\n ERROR: block file not found: %1",
@@ -298,6 +361,17 @@
"vfc-einfuegen-frage": "\n\nDo you want to insert the conveyor system?",
"vfc-einfuegen-optionen": "\n 1 - Yes, insert modules\n 2 - No, cancel",
"vfc-vorgang-abgebrochen": "\nProcess cancelled.",
"vfs-dlg-richtung-auf": "Up",
"vfs-dlg-richtung-ab": "Down",
"vfs-dlg-winkel-horizontal": "Horizontal (GF=%1 mm, VF=%2 mm)",
"vfs-dlg-winkel-option": "%1%2 (GF=%3 mm, VF=%4 mm)",
"vfs-dlg-verteilung-1": "Even (L_GF1 = L_GF2 = L_GF/2)",
"vfs-dlg-verteilung-2": "Front minimum, rear remainder",
"vfs-dlg-verteilung-3": "Rear minimum, front remainder",
"vfs-dlg-verteilung-4": "Enter custom values",
"vfs-edit-kein-vf": "Block %1 is not a VarioFoerderer conveyor.",
"vfs-edit-keine-xdata": "VarioFoerderer %1 was not created with this dialog (Etage/Linienzug/legacy) and cannot be edited here.",
"vfs-edit-neu-aufgebaut": "\nVarioFoerderer %1 rebuilt.",
"vfe-alert-bib-nicht-init": "Etage library not initialised!",
"vfe-berechnung-header": "\n ETAGE CALCULATION FOR ALL ANGLES",
"vfe-bib-bereits-init": "\n Etage library already initialised.",
@@ -376,6 +450,11 @@
"cmd-kein-block-ausgewaehlt": "\nNo block selected.",
"cmd-kreisel-bearbeiten": "\nEdit Kreisel: %1",
"cmd-eckrad-bearbeiten": "\nEdit Eckrad: %1",
"cmd-gefaelle-bearbeiten": "\nEdit Gefaellestrecke: %1",
"cmd-variofoerderer-bearbeiten": "\nEdit VarioFoerderer: %1",
"gf-edit-kein-gf": "Block %1 is not a Gefaellestrecke.",
"gf-edit-nur-einfach": "Only simple Gefaellestrecken (without arcs) can be edited via the dialog.\nTYP: %1",
"gf-edit-neu-aufgebaut": "\nGefaellestrecke %1 rebuilt.",
"cmd-omniflo-bearbeiten": "\nEdit Omniflo element: %1",
"cmd-attribute-bearbeiten": "\nEdit attributes: %1",
"layer-prompt-ziel-layer": "\nSelect object on the target layer: ",
@@ -499,6 +578,13 @@
"gf-status-z-hoehe-ks-aus": "\n Z height KS_AUS: %1 mm",
"gf-status-fertig": "\n>>> Done! <<<",
"gf-status-abgebrochen": "\nCancelled.",
"gf-alert-dialog-fehlt": "Dialog file not found:\n%1",
"gf-dlg-richtung-0": "0%1 (X+, East)",
"gf-dlg-richtung-90": "90%1 (Y+, North)",
"gf-dlg-richtung-180": "180%1 (X-, West)",
"gf-dlg-richtung-270": "270%1 (Y-, South)",
"gf-dlg-links": "Left",
"gf-dlg-rechts": "Right",
"gf-status-gf-block-erstellt": "\n>>> GF block created: %1 (%2)",
"gf-status-schritt1-aus": "\n\n1/4: %1 travel dir=%2%3 KS_EIN-hz=%4%5 v=%6%7",
"gf-status-schritt2-staustrecke": "\n\n2/4: Buffer section L=%1 mm hz=%2%3 v=%4%5",
+1 -1
View File
@@ -214,7 +214,7 @@ def build_kreisel_merkmale(block):
"Höhe in m": hoehe_m,
"Drehrichtung": attribs.get("DREHRICHTUNG", "UZS"),
"Drehung": block.get("rotation", 0.0),
"Name": attribs.get("NAME", ""),
"Name": attribs.get("Bezeichnung", ""),
}
+21 -2
View File
@@ -4,7 +4,12 @@
export_sivas.py - Erzeugt Sivas-Export-CSV mit gruppierten Zeilen und Summierungszeilen.
Neues CSV-Format:
Nr;TeileArt;SivasNummer;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];details
Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];details
- Bezeichnung: Wert des Attributs "Bezeichnung" (Kreisel/Eckrad/VF/GF/Strecke).
Bei gruppierten Zeilen (mehrere Bloecke je Zeile) kommasepariert.
Bei Omniflo-Zeilen (Bogen/Weiche/Gerade) und der Automation-Summenzeile
bleibt das Feld leer, da es sich um Sammlungen gleichartiger Objekte handelt.
- Omniflo Bogen/Weiche: gruppiert nach SivasNummer, Anzahl summiert
- Omniflo Gerade: gruppiert nach ARTINR-Attribut, Laenge[mm] summiert
@@ -271,7 +276,9 @@ def process_blocks(blocks, lookup):
gerade_groups = {}
kreisel_list = [] # Liste von blocks
eckrad_ids = [] # IDs aller Eckrad-Bloecke
eckrad_bezeichnungen = [] # Bezeichnung-Attribut aller Eckrad-Bloecke
strecke_ids = [] # IDs loser Strecke-Elemente (Vario/Staustrecke ausserhalb VF_N)
strecke_bezeichnungen = [] # Bezeichnung-Attribut loser Strecke-Elemente
vario_list = [] # Liste von VarioFoerderer-Compound-Bloecken (VF_N), je einer Zeile
gefaelle_list = [] # Liste von Gefaellestrecke-Bloecken (GF_*), je einer Zeile
@@ -372,6 +379,7 @@ def process_blocks(blocks, lookup):
if matches_any(bname, BLOCKPATTERNS.get("pattern_eckrad", [])):
counters["anzahl_eckraeder"] += 1
eckrad_ids.append(get_id(block))
eckrad_bezeichnungen.append(block.get("attribs", {}).get("Bezeichnung", ""))
continue
# --- ILS Kreisel ---
@@ -443,6 +451,7 @@ def process_blocks(blocks, lookup):
if matches_any(bname, BLOCKPATTERNS.get("pattern_strecke_module", [])):
counters["anzahl_variofoerderer"] += 1
strecke_ids.append(get_id(block))
strecke_bezeichnungen.append(block.get("attribs", {}).get("Bezeichnung", ""))
# --- Zeilen aufbauen ---
items = []
@@ -454,6 +463,7 @@ def process_blocks(blocks, lookup):
"teileart": "Omniflo Bogen",
"sivasnr": sivasnr,
"sivasnr_quoted": False,
"bezeichnung": "",
"dispgruppe": 10,
"anzahl": g["anzahl"],
"laenge_mm": "",
@@ -468,6 +478,7 @@ def process_blocks(blocks, lookup):
"teileart": "Omniflo Weiche",
"sivasnr": sivasnr,
"sivasnr_quoted": False,
"bezeichnung": "",
"dispgruppe": 10,
"anzahl": g["anzahl"],
"laenge_mm": "",
@@ -482,6 +493,7 @@ def process_blocks(blocks, lookup):
"teileart": "Omniflo Gerade",
"sivasnr": g["artinr"],
"sivasnr_quoted": True,
"bezeichnung": "",
"dispgruppe": 10,
"anzahl": g["anzahl"],
"laenge_mm": int(g["laenge_mm"]),
@@ -499,6 +511,7 @@ def process_blocks(blocks, lookup):
"teileart": teileart,
"sivasnr": sivasnr,
"sivasnr_quoted": True,
"bezeichnung": block.get("attribs", {}).get("Bezeichnung", ""),
"dispgruppe": 20,
"anzahl": 1,
"laenge_mm": "",
@@ -514,6 +527,7 @@ def process_blocks(blocks, lookup):
"teileart": teileart,
"sivasnr": sivasnr,
"sivasnr_quoted": True,
"bezeichnung": ", ".join(b for b in eckrad_bezeichnungen if b),
"dispgruppe": 20,
"anzahl": counters["anzahl_eckraeder"],
"laenge_mm": "",
@@ -532,6 +546,7 @@ def process_blocks(blocks, lookup):
"teileart": teileart,
"sivasnr": sivasnr,
"sivasnr_quoted": True,
"bezeichnung": ", ".join(b for b in strecke_bezeichnungen if b),
"dispgruppe": 20,
"anzahl": len(strecke_ids),
"laenge_mm": "",
@@ -549,6 +564,7 @@ def process_blocks(blocks, lookup):
"teileart": teileart,
"sivasnr": sivasnr,
"sivasnr_quoted": True,
"bezeichnung": block.get("attribs", {}).get("Bezeichnung", ""),
"dispgruppe": 20,
"anzahl": 1,
"laenge_mm": "",
@@ -578,6 +594,7 @@ def process_blocks(blocks, lookup):
"teileart": teileart,
"sivasnr": sivasnr,
"sivasnr_quoted": True,
"bezeichnung": ", ".join(b for b in group["bezeichnungen"] if b),
"dispgruppe": 20,
"anzahl": len(group["ids"]),
"laenge_mm": "",
@@ -620,6 +637,7 @@ def process_blocks(blocks, lookup):
"teileart": auto_teileart,
"sivasnr": auto_sivasnr,
"sivasnr_quoted": True,
"bezeichnung": "",
"dispgruppe": 20,
"anzahl": 1,
"laenge_mm": "",
@@ -638,6 +656,7 @@ def format_csv_line(item):
f'{item["nr"]}'
f';"{item["teileart"]}"'
f';{sivasnr}'
f';"{item["bezeichnung"]}"'
f';{item["dispgruppe"]}'
f';{item["anzahl"]}'
f';{item["laenge_mm"]}'
@@ -669,7 +688,7 @@ def main():
items, _ = process_blocks(blocks, lookup)
header = "Nr;TeileArt;SivasNummer;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];details"
header = "Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];details"
with open(output_csv, "w", encoding="utf-8") as f:
f.write(header + "\n")
for item in items:
+7 -2
View File
@@ -10,7 +10,10 @@
[<-Eckrad]^C^C(ssg-ensure "KreiselInsert") ILS_Eckrad
[->Zusatzmodul]
[~BTMT-Beladung]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_BTMT_Beladung
[<-~BTMT-Entladung]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_BTMT_Entladung
[~BTMT-Entladung]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_BTMT_Entladung
[--]
[Scanner einfuegen]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_SCANNER_INSERT
[<-Separator einfuegen]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_SEPARATOR_INSERT
[->Foerderer]
[~Durch TEF angetriebene Strecke]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_TEF_Strecke
[VarioFoerderer]^C^CVarioFoerderer
@@ -121,7 +124,7 @@
[<-~APBW 110 R550/67,5 58x497]^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_675_58
[<-Element bearbeiten]^C^C(ssg-ensure "OmniModulInsert") OMNI_EDIT
[->Export]
[Export Sivas]^C^C(ssg-ensure "export") EXPORTSIVAS
[Export Sivas]^C^C(ssg-ensure "count_sep_scan") ZAEHLE_SEP_SCAN (ssg-ensure "export") EXPORTSIVAS
[<-Export CSV]^C^C(ssg-ensure "export") EXPORTCSV
[->Konfiguration]
[Umschalten 2D und 3D]^C^C(ssg-ensure "SSG_LIB_Commands") SSG_DIM_SWITCH
@@ -149,5 +152,7 @@
[SSG_LIB Edit Context]
[Kreisel bearbeiten](ssg-ensure "KreiselInsert") KreiselEdit
[Omniflo Element bearbeiten](ssg-ensure "OmniModulInsert") OMNI_EDIT
[Gefaellestrecke bearbeiten](ssg-ensure "Gefaellestrecke") GEFAELLESTRECKE_EDIT
[VarioFoerderer bearbeiten](ssg-ensure "VarioFoerderer") VARIOFOERDERER_EDIT
[--]
[SSG Bearbeiten (Auto)](ssg-ensure "SSG_LIB_Commands") SSG_BLOCKEDIT
+8 -8
View File
@@ -6,7 +6,7 @@
"block_handle": "11A",
"insert_point": [500, 500, 2500],
"actual_attributes": {
"NAME": "Kreisel1",
"Bezeichnung": "Kreisel1",
"DREHRICHTUNG": "UZS",
"N_SEPARATOREN": "2",
"KREISELART": "STANDARD",
@@ -27,7 +27,7 @@
"block_handle": "14A",
"insert_point": [-500, 500, 2500],
"actual_attributes": {
"NAME": "Kreisel2",
"Bezeichnung": "Kreisel2",
"DREHRICHTUNG": "UZS",
"N_SEPARATOREN": "2",
"KREISELART": "STANDARD",
@@ -48,7 +48,7 @@
"block_handle": "17A",
"insert_point": [-500, -500, 2500],
"actual_attributes": {
"NAME": "Kreisel3",
"Bezeichnung": "Kreisel3",
"DREHRICHTUNG": "UZS",
"N_SEPARATOREN": "2",
"KREISELART": "STANDARD",
@@ -69,7 +69,7 @@
"block_handle": "1AA",
"insert_point": [500, -500, 2500],
"actual_attributes": {
"NAME": "Kreisel4",
"Bezeichnung": "Kreisel4",
"DREHRICHTUNG": "UZS",
"N_SEPARATOREN": "2",
"KREISELART": "STANDARD",
@@ -90,7 +90,7 @@
"block_handle": "1DA",
"insert_point": [3000, 3000, 3000],
"actual_attributes": {
"NAME": "Kreisel5",
"Bezeichnung": "Kreisel5",
"DREHRICHTUNG": "UZS",
"N_SEPARATOREN": "2",
"KREISELART": "STANDARD",
@@ -111,7 +111,7 @@
"block_handle": "20F",
"insert_point": [500, 6000, 1500],
"actual_attributes": {
"NAME": "Kreisel6",
"Bezeichnung": "Kreisel6",
"DREHRICHTUNG": "UZS",
"N_SEPARATOREN": "2",
"KREISELART": "PIN",
@@ -132,7 +132,7 @@
"block_handle": "243",
"insert_point": [-500, 6500, 1500],
"actual_attributes": {
"NAME": "Kreisel7",
"Bezeichnung": "Kreisel7",
"DREHRICHTUNG": "UZS",
"N_SEPARATOREN": "2",
"KREISELART": "PIN",
@@ -153,7 +153,7 @@
"block_handle": "277",
"insert_point": [3000, 8000, 1500],
"actual_attributes": {
"NAME": "Kreisel8",
"Bezeichnung": "Kreisel8",
"DREHRICHTUNG": "UZS",
"N_SEPARATOREN": "2",
"KREISELART": "PIN",
+5 -5
View File
@@ -289,7 +289,7 @@ class TestFoerdererExportSivas:
def test_header_felder(self):
"""Sivas-CSV-Header muss korrekte Spalten haben."""
expected = ["Nr", "TeileArt", "SivasNummer",
expected = ["Nr", "TeileArt", "SivasNummer", "Bezeichnung",
"Dispogruppe", "Anzahl", "Laenge[mm]", "Hoehe[m]", "details"]
for i, name in enumerate(expected):
assert self.header[i] == name, (
@@ -317,10 +317,10 @@ class TestFoerdererExportSivas:
def test_details_sind_valides_json(self):
"""details-Spalte muss valides JSON enthalten."""
for i, row in enumerate(self.rows):
if len(row) < 8:
if len(row) < 9:
continue
try:
json.loads(row[7])
json.loads(row[8])
except json.JSONDecodeError as e:
pytest.fail(f"Zeile {i + 2}: details ist kein valides JSON: {e}")
@@ -330,10 +330,10 @@ class TestFoerdererExportSivas:
"Laengen aller Variofoerderer",
"Anzahl aller Separatoren"}
for row in self.rows:
if len(row) < 8:
if len(row) < 9:
continue
if row[1].strip('"') == "ILS 2.0 Automation und Pneumatik - Gesamtanlage":
details = json.loads(row[7])
details = json.loads(row[8])
missing = required - set(details.keys())
assert not missing, (
f"Automation-details: fehlende Felder: {missing}"
+84 -21
View File
@@ -25,8 +25,12 @@
;; --- Ergebnis eines Testfalls als JSON-String erzeugen ---
(defun gefaellestrecke:test-json (test-id modus hz deltaL winkel h-von h-bis d-h status /
;; as-winkel/es-winkel: "30" oder "90" (Element-Variante); default "90"
(defun gefaellestrecke:test-json (test-id modus hz deltaL winkel h-von h-bis d-h status
as-winkel es-winkel /
json)
(if (null as-winkel) (setq as-winkel "90"))
(if (null es-winkel) (setq es-winkel "90"))
(setq json
(strcat " {\n"
" \"test_id\": \"" test-id "\",\n"
@@ -34,6 +38,8 @@
" \"hz_grad\": " (rtos (float hz) 2 1) ",\n"
" \"deltaL_mm\": " (rtos (float deltaL) 2 0) ",\n"
" \"winkel_grad\": " (rtos (float winkel) 2 3) ",\n"
" \"as_winkel\": \"" as-winkel "\",\n"
" \"es_winkel\": \"" es-winkel "\",\n"
" \"hoehe_von_mm\": " (rtos (float h-von) 2 0) ",\n"
" \"hoehe_bis_mm\": " (rtos (float h-bis) 2 0) ",\n"
" \"delta_h_mm\": " (rtos (float d-h) 2 0) ",\n"
@@ -296,6 +302,7 @@
m2-start m2-deltaH m2-deltaL
m3-start m3-end m3-line-vla
m3b-start m3b-end m3b-e1 m3b-e2 m3b-e3 m3b-objliste
w30-rad w30-sepx w30-lstau
lbl-layer lbl-h lbl-h2)
;; Block-Bibliothek initialisieren (setzt aus-dx, ein-dx, aus-dz, ein-dz usw.)
@@ -376,7 +383,7 @@
(setq gf-ins
(car (gefaellestrecke-einfuegen
test-L_stau test-winkel (list 0 0 test-z-start)
"links" "links" 0.0 test-deltaL)))
"links" "links" 0.0 test-deltaL "90" "90")))
(if gf-ins
(progn
(setq attribs (ssg-attrib-read gf-ins))
@@ -388,13 +395,13 @@
" dH=" (itoa d-h) " mm W=" w-str " OK"))
(setq results-list
(cons (gefaellestrecke:test-json "M1_hz000" 1 0.0 test-deltaL
(atof w-str) h-von h-bis d-h "GEBAUT")
(atof w-str) h-von h-bis d-h "GEBAUT" "90" "90")
results-list)))
(progn
(princ " FEHLER")
(setq results-list
(cons (gefaellestrecke:test-json "M1_hz000" 1 0.0 test-deltaL
0.0 0 0 0 "FEHLER")
0.0 0 0 0 "FEHLER" "90" "90")
results-list))))
;; --- M1: hz=90 Grad (Nord), Start (15000, 0, 5000) ---
@@ -408,7 +415,7 @@
(setq gf-ins
(car (gefaellestrecke-einfuegen
test-L_stau test-winkel (list 15000 0 test-z-start)
"links" "links" 90.0 test-deltaL)))
"links" "links" 90.0 test-deltaL "90" "90")))
(if gf-ins
(progn
(setq attribs (ssg-attrib-read gf-ins))
@@ -420,13 +427,13 @@
" dH=" (itoa d-h) " mm W=" w-str " OK"))
(setq results-list
(cons (gefaellestrecke:test-json "M1_hz090" 1 90.0 test-deltaL
(atof w-str) h-von h-bis d-h "GEBAUT")
(atof w-str) h-von h-bis d-h "GEBAUT" "90" "90")
results-list)))
(progn
(princ " FEHLER")
(setq results-list
(cons (gefaellestrecke:test-json "M1_hz090" 1 90.0 test-deltaL
0.0 0 0 0 "FEHLER")
0.0 0 0 0 "FEHLER" "90" "90")
results-list))))
;; --- M1: hz=180 Grad (West), Start (0, -15000, 5000) ---
@@ -440,7 +447,7 @@
(setq gf-ins
(car (gefaellestrecke-einfuegen
test-L_stau test-winkel (list 0 -15000 test-z-start)
"links" "links" 180.0 test-deltaL)))
"links" "links" 180.0 test-deltaL "90" "90")))
(if gf-ins
(progn
(setq attribs (ssg-attrib-read gf-ins))
@@ -452,13 +459,13 @@
" dH=" (itoa d-h) " mm W=" w-str " OK"))
(setq results-list
(cons (gefaellestrecke:test-json "M1_hz180" 1 180.0 test-deltaL
(atof w-str) h-von h-bis d-h "GEBAUT")
(atof w-str) h-von h-bis d-h "GEBAUT" "90" "90")
results-list)))
(progn
(princ " FEHLER")
(setq results-list
(cons (gefaellestrecke:test-json "M1_hz180" 1 180.0 test-deltaL
0.0 0 0 0 "FEHLER")
0.0 0 0 0 "FEHLER" "90" "90")
results-list))))
;; --- M1: hz=270 Grad (Sued), Start (15000, -15000, 5000) ---
@@ -472,7 +479,7 @@
(setq gf-ins
(car (gefaellestrecke-einfuegen
test-L_stau test-winkel (list 15000 -15000 test-z-start)
"links" "links" 270.0 test-deltaL)))
"links" "links" 270.0 test-deltaL "90" "90")))
(if gf-ins
(progn
(setq attribs (ssg-attrib-read gf-ins))
@@ -484,13 +491,13 @@
" dH=" (itoa d-h) " mm W=" w-str " OK"))
(setq results-list
(cons (gefaellestrecke:test-json "M1_hz270" 1 270.0 test-deltaL
(atof w-str) h-von h-bis d-h "GEBAUT")
(atof w-str) h-von h-bis d-h "GEBAUT" "90" "90")
results-list)))
(progn
(princ " FEHLER")
(setq results-list
(cons (gefaellestrecke:test-json "M1_hz270" 1 270.0 test-deltaL
0.0 0 0 0 "FEHLER")
0.0 0 0 0 "FEHLER" "90" "90")
results-list))))
;; ============================================================
@@ -522,7 +529,7 @@
(princ (strcat "\n\n M2_hz000: Start=(0,-35000," (rtos test-z-start 2 0) ") ..."))
(setq ergebnis
(gefaellestrecke-einfuegen
test-L_stau test-winkel m2-start "links" "links" 0.0 test-deltaL))
test-L_stau test-winkel m2-start "links" "links" 0.0 test-deltaL "90" "90"))
(setq gf-ins (car ergebnis))
(if gf-ins
(progn
@@ -541,7 +548,7 @@
" mm W=" w-str " OK"))
(setq results-list
(cons (gefaellestrecke:test-json "M2_hz000" 2 0.0 test-deltaL
(atof w-str) h-von h-bis m2-deltaH "GEBAUT")
(atof w-str) h-von h-bis m2-deltaH "GEBAUT" "90" "90")
results-list)))
(progn
;; Fallback: sin(3deg) * 10000 ≈ 523mm
@@ -550,7 +557,7 @@
(princ (strcat " FEHLER (Fallback " delta-sym "H=" (rtos m2-deltaH 2 3) ")"))
(setq results-list
(cons (gefaellestrecke:test-json "M2_hz000" 2 0.0 test-deltaL
0.0 0 0 0 "FEHLER")
0.0 0 0 0 "FEHLER" "90" "90")
results-list))))
;; ============================================================
@@ -618,20 +625,20 @@
" W=" w-str " OK"))
(setq results-list
(cons (gefaellestrecke:test-json "M3_hz270" 3 270.0 test-deltaL
(atof w-str) h-von h-bis d-h "GEBAUT")
(atof w-str) h-von h-bis d-h "GEBAUT" "90" "90")
results-list)))
(progn
(princ "\n -> FEHLER (modus3-einfuegen)")
(setq results-list
(cons (gefaellestrecke:test-json "M3_hz270" 3 270.0 test-deltaL
0.0 0 0 0 "FEHLER")
0.0 0 0 0 "FEHLER" "90" "90")
results-list)))))
;; 3D-Linie konnte nicht erzeugt werden
(progn
(princ "\n FEHLER: 3D-Linie nicht erzeugbar!")
(setq results-list
(cons (gefaellestrecke:test-json "M3_hz270" 3 270.0 test-deltaL
0.0 0 0 0 "FEHLER_LINIE")
0.0 0 0 0 "FEHLER_LINIE" "90" "90")
results-list))))
;; ============================================================
@@ -688,15 +695,71 @@
" " delta-sym "H-Soll=200 mm W=" w-str " OK"))
(setq results-list
(cons (gefaellestrecke:test-json "M3_Bogen" 3 0.0 14785.0
(atof w-str) h-von h-bis d-h "GEBAUT")
(atof w-str) h-von h-bis d-h "GEBAUT" "90" "90")
results-list)))
(progn
(princ "\n -> FEHLER (modus3-einfuegen mit Bogen)")
(setq results-list
(cons (gefaellestrecke:test-json "M3_Bogen" 3 0.0 14785.0
0.0 0 0 0 "FEHLER")
0.0 0 0 0 "FEHLER" "90" "90")
results-list))))
;; ============================================================
;; MODUS 1 - 30-Grad AUS-/EIN-Elemente (statt 90 Grad)
;; Prueft die per DCL-Dialog waehlbare Element-Variante 30 Grad.
;; hz=0, Start (30000, 0, 5000). Eigene L_stau-Berechnung, da die
;; 30-Grad-Elemente andere aus-dx/ein-dx-Masse besitzen.
;; ============================================================
(princ "\n\n================================================================")
(princ "\n MODUS 1 - 30-Grad Elemente (M1_w30)")
(princ "\n================================================================")
(entmake (list '(0 . "TEXT")
(cons 10 (list 30000 1200.0 test-z-start))
(cons 11 (list 30000 1200.0 test-z-start))
(cons 40 lbl-h)
(cons 1 (strcat "M1 | hz=0" grad-zeichen " | AS/ES=30" grad-zeichen
" | " delta-sym "L=10000 | W=3" grad-zeichen))
'(7 . "Standard") (cons 8 lbl-layer) '(72 . 1) '(73 . 2)))
;; 30-Grad-Element-Masse setzen und L_stau dafuer berechnen
(vf-set-as-masse "30" "links")
(vf-set-es-masse "30" "links")
(setq w30-rad (* test-winkel (/ pi 180.0)))
(setq w30-sepx (* 300.0 (cos w30-rad)))
(setq w30-lstau
(/ (- test-deltaL (float aus-dx) (float ein-dx) w30-sepx) (cos w30-rad)))
(princ (strcat "\n\n M1_w30: AS/ES=30 Grad, aus-dx=" (rtos (float aus-dx) 2 1)
" ein-dx=" (rtos (float ein-dx) 2 1)
" L_stau=" (rtos w30-lstau 2 1) " ..."))
(setq gf-ins
(car (gefaellestrecke-einfuegen
w30-lstau test-winkel (list 30000 0 test-z-start)
"links" "links" 0.0 test-deltaL "30" "30")))
(if gf-ins
(progn
(setq attribs (ssg-attrib-read gf-ins))
(setq h-von (atoi (cdr (assoc "HOEHE_VON_mm" attribs))))
(setq h-bis (atoi (cdr (assoc "HOEHE_BIS_mm" attribs))))
(setq d-h (abs (- h-von h-bis)))
(setq w-str (cdr (assoc "GF_WINKEL" attribs)))
(princ (strcat " von=" (itoa h-von) " bis=" (itoa h-bis)
" dH=" (itoa d-h) " mm W=" w-str " OK"))
(setq results-list
(cons (gefaellestrecke:test-json "M1_w30" 1 0.0 test-deltaL
(atof w-str) h-von h-bis d-h "GEBAUT" "30" "30")
results-list)))
(progn
(princ " FEHLER")
(setq results-list
(cons (gefaellestrecke:test-json "M1_w30" 1 0.0 test-deltaL
0.0 0 0 0 "FEHLER" "30" "30")
results-list))))
;; Element-Masse wieder auf 90 Grad zuruecksetzen (fuer Folgelaeufe)
(vf-set-as-masse "90" "links")
(vf-set-es-masse "90" "links")
;; ============================================================
;; Zusammenfassung und Export
;; ============================================================
+23 -5
View File
@@ -82,14 +82,30 @@ class TestGefaellestreckeStatus:
)
def test_alle_modus1_gebaut(self):
"""Alle vier Modus-1-Richtungen (hz=0/90/180/270) muessen GEBAUT sein."""
"""Alle Modus-1-Testfaelle (Richtungs-Sweep + 30-Grad-Variante) muessen GEBAUT sein."""
erwartet = [t["test_id"] for t in self.tests if t["modus"] == 1]
modus1 = [r for r in self.results if r["modus"] == 1]
assert len(modus1) == 4, f"Erwartet 4 Modus-1-Testfaelle, gefunden {len(modus1)}"
assert len(modus1) == len(erwartet), (
f"Erwartet {len(erwartet)} Modus-1-Testfaelle, gefunden {len(modus1)}"
)
for r in modus1:
assert r["status"] == "GEBAUT", (
f'{r["test_id"]}: erwartet GEBAUT, ist "{r["status"]}"'
)
def test_modus1_30grad_gebaut(self):
"""Die per Dialog waehlbare 30-Grad-Element-Variante (M1_w30) muss GEBAUT sein."""
r = self.results_by_id.get("M1_w30")
if r is None:
pytest.skip("M1_w30 nicht in Ergebnissen (aeltere Testdaten?)")
assert r["status"] == "GEBAUT", (
f'M1_w30: erwartet GEBAUT, ist "{r["status"]}"'
)
assert r.get("as_winkel") == "30" and r.get("es_winkel") == "30", (
f'M1_w30: Element-Winkel sollten 30 sein, sind '
f'AS={r.get("as_winkel")} ES={r.get("es_winkel")}'
)
def test_modus2_und_modus3_gebaut(self):
"""Modus 2 und Modus 3 muessen GEBAUT sein."""
for test_id in ("M2_hz000", "M3_hz270"):
@@ -179,10 +195,12 @@ class TestGefaellestreckeModusKonsistenz:
self.tests_by_id = {t["test_id"]: t for t in self.testdata if "test_id" in t}
def test_modus1_richtungsunabhaengig(self):
"""Alle vier Modus-1-Richtungen muessen dieselbe Hoehe/Winkel liefern,
da nur die Fahrtrichtung (hz), nicht die Geometrie variiert."""
"""Die vier Modus-1-Richtungen (90-Grad-Elemente) muessen dieselbe Hoehe/Winkel
liefern, da nur die Fahrtrichtung (hz), nicht die Geometrie variiert. Die
30-Grad-Variante (M1_w30) ist bewusst ausgenommen (andere Element-Masse)."""
modus1 = [r for r in self.results
if r["modus"] == 1 and r["status"] == "GEBAUT"]
if r["modus"] == 1 and r["status"] == "GEBAUT"
and r.get("as_winkel", "90") == "90"]
assert len(modus1) >= 2, "Zu wenige Modus-1-Ergebnisse fuer Vergleich"
referenz = modus1[0]
for r in modus1[1:]:
+32 -7
View File
@@ -10,7 +10,9 @@
"hz_grad": 0.0,
"start_mm": [0, 0, 5000],
"as_seite": "links",
"es_seite": "links"
"es_seite": "links",
"as_winkel": "90",
"es_winkel": "90"
},
{
"test_id": "M1_hz090",
@@ -18,7 +20,9 @@
"hz_grad": 90.0,
"start_mm": [15000, 0, 5000],
"as_seite": "links",
"es_seite": "links"
"es_seite": "links",
"as_winkel": "90",
"es_winkel": "90"
},
{
"test_id": "M1_hz180",
@@ -26,7 +30,9 @@
"hz_grad": 180.0,
"start_mm": [0, -15000, 5000],
"as_seite": "links",
"es_seite": "links"
"es_seite": "links",
"as_winkel": "90",
"es_winkel": "90"
},
{
"test_id": "M1_hz270",
@@ -34,7 +40,20 @@
"hz_grad": 270.0,
"start_mm": [15000, -15000, 5000],
"as_seite": "links",
"es_seite": "links"
"es_seite": "links",
"as_winkel": "90",
"es_winkel": "90"
},
{
"test_id": "M1_w30",
"modus": 1,
"hz_grad": 0.0,
"start_mm": [30000, 0, 5000],
"as_seite": "links",
"es_seite": "links",
"as_winkel": "30",
"es_winkel": "30",
"beschreibung": "Modus 1 mit 30-Grad AUS-/EIN-Elementen (statt 90 Grad)"
},
{
"test_id": "M2_hz000",
@@ -44,7 +63,9 @@
"linie_start_mm": [0, -35000, 0],
"linie_ende_mm": [10000, -35000, 0],
"as_seite": "links",
"es_seite": "links"
"es_seite": "links",
"as_winkel": "90",
"es_winkel": "90"
},
{
"test_id": "M3_hz270",
@@ -54,7 +75,9 @@
"deltaH_quelle": "M2_hz000",
"deltaL_quelle": "M2_hz000",
"as_seite": "links",
"es_seite": "links"
"es_seite": "links",
"as_winkel": "90",
"es_winkel": "90"
},
{
"test_id": "M3_Bogen",
@@ -64,6 +87,8 @@
"ende_mm": [38500, -43500, 1800],
"bogen": {"winkel_grad": 90, "radius_mm": 500, "seite": "links"},
"as_seite": "links",
"es_seite": "links"
"es_seite": "links",
"as_winkel": "90",
"es_winkel": "90"
}
]