Files
dxfmakros/Lisp/OmniModulInsert.lsp
T

1184 lines
36 KiB
Common Lisp

;; ============================================================
;; OMNIFLO JSON-DATEN LADEN UND ABFRAGEN
;; Liest omniflo_boegen.json und omniflo_weichen.json ein.
;; Daten werden als Listen von Assoziationslisten gespeichert.
;;
;; Globale Variablen:
;; *OMNI-BOEGEN* - Liste aller Boegen-Eintraege
;; *OMNI-WEICHEN* - Liste aller Weichen-Eintraege
;;
;; Funktionen:
;; (omni:load-data) - Beide JSON-Dateien laden
;; (omni:get-bogen sivasid) - Bogen-Info zu einer SivasId
;; (omni:get-weiche sivasid) - Weichen-Info zu einer SivasId
;; (omni:filter lst key wert) - Eintraege nach Key/Wert filtern
;; ============================================================
;; --- Datei zeilenweise einlesen ---
(defun omni:read-file-lines (datei / f zeile ergebnis)
(setq f (open datei "r"))
(if (null f)
(progn
(princ (strcat "\n[OMNI] FEHLER: Datei nicht gefunden: " datei))
nil
)
(progn
(setq ergebnis nil)
(while (setq zeile (read-line f))
(setq ergebnis (cons zeile ergebnis))
)
(close f)
(reverse ergebnis)
)
)
)
;; --- Whitespace und Komma am Ende einer Zeile entfernen ---
(defun omni:trim (s / len ch)
(setq s (vl-string-trim " \t\r\n" s))
(setq len (strlen s))
(if (and (> len 0) (= (substr s len 1) ","))
(setq s (substr s 1 (1- len)))
)
(vl-string-trim " \t\r\n" s)
)
;; --- JSON-Wert parsen (String, Zahl, null) ---
(defun omni:parse-value (val-str / len)
(setq val-str (omni:trim val-str))
(cond
((= val-str "null") nil)
((= (substr val-str 1 1) "\"")
;; String: Anfuehrungszeichen entfernen
(setq len (strlen val-str))
(if (and (> len 1) (= (substr val-str len 1) "\""))
(substr val-str 2 (- len 2))
val-str
)
)
(T
;; Zahl
(if (vl-string-search "." val-str)
(atof val-str)
(atoi val-str)
)
)
)
)
;; --- Eine Key-Value-Zeile parsen -> dotted pair oder nil ---
(defun omni:parse-kv-line (zeile / pos key rest val)
(setq zeile (omni:trim zeile))
;; Muss mit " beginnen (Key)
(if (and (> (strlen zeile) 0) (= (substr zeile 1 1) "\""))
(progn
;; Key extrahieren: zweites Anfuehrungszeichen finden
;; vl-string-search ist 0-basiert, substr ist 1-basiert
(setq pos (vl-string-search "\"" zeile 1))
(if pos
(progn
(setq key (substr zeile 2 (1- pos)))
;; Rest nach dem schliessenden " extrahieren
(setq rest (substr zeile (+ pos 2)))
;; ":" im Rest finden
(setq pos (vl-string-search ":" rest))
(if pos
(progn
(setq val (substr rest (+ pos 2)))
(cons key (omni:parse-value val))
)
)
)
)
)
)
)
;; --- JSON-Array von flachen Objekten parsen ---
(defun omni:parse-json-array (zeilen / in-obj obj ergebnis zeile kv trimmed)
(setq in-obj nil
obj nil
ergebnis nil
)
(foreach zeile zeilen
(setq trimmed (omni:trim zeile))
(cond
;; Objekt-Start
((= trimmed "{")
(setq in-obj T
obj nil
)
)
;; Objekt-Ende
((or (= trimmed "}") (= trimmed "},"))
(if (and in-obj obj)
(setq ergebnis (cons (reverse obj) ergebnis))
)
(setq in-obj nil)
)
;; Key-Value-Zeile innerhalb eines Objekts
(in-obj
(setq kv (omni:parse-kv-line zeile))
(if kv (setq obj (cons kv obj)))
)
)
)
(reverse ergebnis)
)
;; --- JSON-Datei laden und als Liste von Alists zurueckgeben ---
(defun omni:load-json (datei / zeilen)
(setq zeilen (omni:read-file-lines datei))
(if zeilen
(omni:parse-json-array zeilen)
)
)
;; --- Beide Datensaetze laden ---
(defun omni:load-data ( / data-pfad f-boegen f-weichen)
(setq data-pfad (getenv "DXFM_DATA"))
(if (null data-pfad)
(progn
(princ "\n[OMNI] FEHLER: DXFM_DATA nicht gesetzt!")
nil
)
(progn
;; Boegen laden
(setq f-boegen (strcat data-pfad "/json/omniflo_boegen.json"))
(setq *OMNI-BOEGEN* (omni:load-json f-boegen))
(if *OMNI-BOEGEN*
(princ (strcat "\n[OMNI] " (itoa (length *OMNI-BOEGEN*)) " Boegen geladen."))
(princ (strcat "\n[OMNI] WARNUNG: Keine Boegen geladen aus " f-boegen))
)
;; Weichen laden
(setq f-weichen (strcat data-pfad "/json/omniflo_weichen.json"))
(setq *OMNI-WEICHEN* (omni:load-json f-weichen))
(if *OMNI-WEICHEN*
(princ (strcat "\n[OMNI] " (itoa (length *OMNI-WEICHEN*)) " Weichen geladen."))
(princ (strcat "\n[OMNI] WARNUNG: Keine Weichen geladen aus " f-weichen))
)
T
)
)
)
;; --- SivasId zu String konvertieren (fuer Vergleich) ---
(defun omni:sivasid-to-str (id)
(cond
((= (type id) 'STR) id)
((= (type id) 'INT) (itoa id))
((= (type id) 'REAL) (itoa (fix id)))
(T "")
)
)
;; --- Eintrag anhand SivasId in einer Liste suchen ---
(defun omni:get-by-sivasid (lst sivasid / such-str eintrag sivasnr gefunden)
(setq such-str (omni:sivasid-to-str sivasid))
(setq gefunden nil)
(foreach eintrag lst
(if (null gefunden)
(progn
(setq sivasnr (cdr (assoc "Sivasnr" eintrag)))
(if (= (omni:sivasid-to-str sivasnr) such-str)
(setq gefunden eintrag)
)
)
)
)
gefunden
)
;; --- Bogen anhand SivasId abfragen ---
;; Rueckgabe: Assoziationsliste mit allen Eigenschaften oder nil
;; Beispiel: (omni:get-bogen 821104025)
;; -> (("Sivasnr" . 821104025) ("ProfilTyp" . "APB 110 R 550/22,5...") ...)
(defun omni:get-bogen (sivasid)
(if (null *OMNI-BOEGEN*) (omni:load-data))
(omni:get-by-sivasid *OMNI-BOEGEN* sivasid)
)
;; --- Weiche anhand SivasId abfragen ---
;; Rueckgabe: Assoziationsliste mit allen Eigenschaften oder nil
;; Beispiel: (omni:get-weiche 834372001)
;; -> (("Sivasnr" . 834372001) ("ProfilTyp" . "WEICHE S 45...") ...)
(defun omni:get-weiche (sivasid)
(if (null *OMNI-WEICHEN*) (omni:load-data))
(omni:get-by-sivasid *OMNI-WEICHEN* sivasid)
)
;; --- Eintraege nach beliebigem Key/Wert filtern ---
;; lst = *OMNI-BOEGEN* oder *OMNI-WEICHEN*
;; key = Schluesselname z.B. "KurvenWinkel"
;; wert = Gesuchter Wert z.B. 45
;; Rueckgabe: Liste aller passenden Eintraege
;;
;; Beispiel: (omni:filter *OMNI-BOEGEN* "KurvenWinkel" 45)
;; -> Liste aller 45-Grad-Boegen
;; Beispiel: (omni:filter *OMNI-WEICHEN* "WeichenTyp" "Doppelweiche")
;; -> Liste aller Doppelweichen
(defun omni:filter (lst key wert / eintrag val ergebnis)
(setq ergebnis nil)
(foreach eintrag lst
(setq val (cdr (assoc key eintrag)))
(if (equal val wert)
(setq ergebnis (cons eintrag ergebnis))
)
)
(reverse ergebnis)
)
;; --- Einzelnen Wert aus einem Eintrag lesen ---
;; eintrag = Assoziationsliste (Rueckgabe von omni:get-bogen etc.)
;; key = Schluesselname z.B. "Radius"
;; Beispiel: (omni:val (omni:get-bogen 821104025) "Radius") -> 550
(defun omni:val (eintrag key)
(cdr (assoc key eintrag))
)
;; --- SivasNummern aller Boegen fuer einen bestimmten Winkel ---
;; winkel = KurvenWinkel z.B. 90, 45, 22.5
;; Rueckgabe: Liste von SivasIds (gemischt INT/STR)
;; Beispiel: (omni:boegen-ids 45) -> (821104021 821104026 "821104026+0_B10071" ...)
(defun omni:boegen-ids (winkel / lst eintrag ergebnis)
(if (null *OMNI-BOEGEN*) (omni:load-data))
(setq ergebnis nil)
(foreach eintrag *OMNI-BOEGEN*
(if (equal (cdr (assoc "KurvenWinkel" eintrag)) winkel)
(setq ergebnis (cons (cdr (assoc "Sivasnr" eintrag)) ergebnis))
)
)
(reverse ergebnis)
)
;; --- SivasNummern aller Boegen, gruppiert nach Winkel ---
;; Rueckgabe: Assoziationsliste ((180 . (id ...)) (90 . (id ...)) ...)
;; Beispiel: (omni:boegen-ids-alle)
;; -> ((180 821104043) (90 821104022 821104030 ...) (67.5 ...) (45 ...) (22.5 ...))
(defun omni:boegen-ids-alle ()
(list
(cons 180 (omni:boegen-ids 180))
(cons 90 (omni:boegen-ids 90))
(cons 67.5 (omni:boegen-ids 67.5))
(cons 45 (omni:boegen-ids 45))
(cons 22.5 (omni:boegen-ids 22.5))
)
)
;; --- SivasNummern von Weichen nach Winkel und WeichenTyp ---
;; winkel = KurvenWinkel z.B. 90, 45
;; weichentyp = "Einzelweiche", "Doppelweiche", "Dreiwegeweiche"
;; Beispiel: (omni:weichen-ids 90 "Einzelweiche")
(defun omni:weichen-ids (winkel weichentyp / eintrag ergebnis)
(if (null *OMNI-WEICHEN*) (omni:load-data))
(setq ergebnis nil)
(foreach eintrag *OMNI-WEICHEN*
(if (and (equal (cdr (assoc "KurvenWinkel" eintrag)) winkel)
(= (cdr (assoc "WeichenTyp" eintrag)) weichentyp)
)
(setq ergebnis (cons (cdr (assoc "Sivasnr" eintrag)) ergebnis))
)
)
(reverse ergebnis)
)
;; --- SivasNummern von Weichenkombinationen (Delta/Star) ---
;; typ = "DELTA" oder "STAR"
;; Filtert anhand ProfilTyp-Inhalt
(defun omni:weichen-kombi-ids (typ / eintrag ergebnis profil)
(if (null *OMNI-WEICHEN*) (omni:load-data))
(setq ergebnis nil)
(foreach eintrag *OMNI-WEICHEN*
(setq profil (cdr (assoc "ProfilTyp" eintrag)))
(if (and profil (vl-string-search typ profil))
(setq ergebnis (cons (cdr (assoc "Sivasnr" eintrag)) ergebnis))
)
)
(reverse ergebnis)
)
;; --- Alle Weichen-SivasNummern gruppiert ---
;; Rueckgabe: Assoziationsliste nach Kategorie
;; Beispiel: (omni:weichen-ids-alle)
;; -> (("W90-Einfach" id1 id2 ...)
;; ("W90-Doppel" ...)
;; ...
;; ("WKomb-Delta" ...)
;; ("WKomb-Star" ...))
(defun omni:weichen-ids-alle ()
(list
;; 90 Grad
(cons "W90-Einfach" (omni:weichen-ids 90 "Einzelweiche"))
(cons "W90-Doppel" (omni:weichen-ids 90 "Doppelweiche"))
(cons "W90-Dreiwege" (omni:weichen-ids 90 "Dreiwegeweiche"))
;; 45 Grad
(cons "W45-Einfach" (omni:weichen-ids 45 "Einzelweiche"))
(cons "W45-Doppel" (omni:weichen-ids 45 "Doppelweiche"))
(cons "W45-Dreiwege" (omni:weichen-ids 45 "Dreiwegeweiche"))
;; Parallel (KurvenWinkel = 0)
(cons "WP-Einfach" (omni:weichen-ids 0 "Einzelweiche"))
(cons "WP-Doppel" (omni:weichen-ids 0 "Doppelweiche"))
(cons "WP-Dreiwege" (omni:weichen-ids 0 "Dreiwegeweiche"))
;; Weichenkoerper (KurvenWinkel = 22.5)
(cons "WK-Einfach" (omni:weichen-ids 22.5 "Einzelweiche"))
(cons "WK-Doppel" (omni:weichen-ids 22.5 "Doppelweiche"))
(cons "WK-Dreiwege" (omni:weichen-ids 22.5 "Dreiwegeweiche"))
;; Weichenkombinationen
(cons "WKomb-Delta" (omni:weichen-kombi-ids "DELTA"))
(cons "WKomb-Star" (omni:weichen-kombi-ids "STAR"))
)
)
;; --- BricsCAD-Befehl: Daten laden ---
(defun c:OMNI_LOAD ()
(omni:load-data)
(princ)
)
;; --- BricsCAD-Befehl: Bogen-Info anzeigen ---
(defun c:OMNI_INFO_BOGEN ( / id eintrag)
(if (null *OMNI-BOEGEN*) (omni:load-data))
(setq id (getstring T "\nSivasId des Bogens eingeben: "))
(if (= id "") (princ "\nAbgebrochen.")
(progn
;; Versuch als Zahl, dann als String
(setq eintrag (omni:get-bogen (if (/= (atoi id) 0) (atoi id) id)))
(if eintrag
(progn
(princ (strcat "\n ProfilTyp: " (omni:sivasid-to-str (omni:val eintrag "ProfilTyp"))))
(princ (strcat "\n Radius: " (itoa (fix (omni:val eintrag "Radius")))))
(princ (strcat "\n KurvenWinkel: " (rtos (omni:val eintrag "KurvenWinkel") 2 1)))
(princ (strcat "\n Breite: " (itoa (fix (omni:val eintrag "Breite")))))
(princ (strcat "\n Laenge: " (itoa (fix (omni:val eintrag "Länge")))))
(princ (strcat "\n Antriebsart: " (itoa (fix (omni:val eintrag "Antriebsart")))))
)
(princ (strcat "\nKein Bogen mit SivasId '" id "' gefunden."))
)
)
)
(princ)
)
;; --- BricsCAD-Befehl: Weichen-Info anzeigen ---
(defun c:OMNI_INFO_WEICHE ( / id eintrag wkl)
(if (null *OMNI-WEICHEN*) (omni:load-data))
(setq id (getstring T "\nSivasId der Weiche eingeben: "))
(if (= id "") (princ "\nAbgebrochen.")
(progn
(setq eintrag (omni:get-weiche (if (/= (atoi id) 0) (atoi id) id)))
(if eintrag
(progn
(princ (strcat "\n ProfilTyp: " (omni:sivasid-to-str (omni:val eintrag "ProfilTyp"))))
(princ (strcat "\n WeichenTyp: " (omni:sivasid-to-str (omni:val eintrag "WeichenTyp"))))
(setq wkl (omni:val eintrag "KurvenWinkel"))
(princ (strcat "\n KurvenWinkel: " (if (= (type wkl) 'INT) (itoa wkl) (rtos wkl 2 1))))
(princ (strcat "\n Schaltungstyp: " (omni:sivasid-to-str (omni:val eintrag "Schaltungstyp"))))
(princ (strcat "\n Breite: " (itoa (fix (omni:val eintrag "Breite")))))
(princ (strcat "\n Laenge: " (itoa (fix (omni:val eintrag "Länge")))))
(princ (strcat "\n KurvenRichtung: " (itoa (fix (omni:val eintrag "KurvenRichtung")))))
(if (omni:val eintrag "WeichenkörperLänge")
(princ (strcat "\n WK-Laenge: " (rtos (omni:val eintrag "WeichenkörperLänge") 2 1)))
)
)
(princ (strcat "\nKeine Weiche mit SivasId '" id "' gefunden."))
)
)
)
(princ)
)
;; ============================================================
;; OMNIFLO BOGEN-DIALOG
;; Generischer Dialog fuer Bogen-Auswahl nach Winkel
;; ============================================================
;; --- Detail-Felder im Dialog aktualisieren ---
;; Wird bei Dropdown-Aenderung aufgerufen (action_tile callback)
(defun omni:bogen-dlg-update (idx-str / idx eintrag wkl)
(setq idx (atoi idx-str))
(setq eintrag (nth idx *OMNI-DLG-BOEGEN*))
(if eintrag
(progn
(set_tile "val_sivasnr"
(omni:sivasid-to-str (omni:val eintrag "Sivasnr")))
(setq wkl (omni:val eintrag "KurvenWinkel"))
(set_tile "val_winkel"
(if (= (type wkl) 'INT) (strcat (itoa wkl) " Grad")
(strcat (rtos wkl 2 1) " Grad")
)
)
(set_tile "val_radius"
(itoa (fix (omni:val eintrag "Radius"))))
(set_tile "val_breite"
(itoa (fix (omni:val eintrag "Breite"))))
(set_tile "val_laenge"
(itoa (fix (omni:val eintrag "Länge"))))
)
)
)
;; --- Bogen-Auswahl-Dialog oeffnen ---
;; winkel = KurvenWinkel (90, 67.5, 45, 22.5, 180)
;; Rueckgabe: gewaehlter Bogen-Eintrag (alist) oder nil bei Abbruch
(defun omni:bogen-dialog (winkel / dcl-pfad dat boegen-liste
profil-liste ergebnis)
(if (null *OMNI-BOEGEN*) (omni:load-data))
;; Boegen nach Winkel filtern
(setq boegen-liste (omni:filter *OMNI-BOEGEN* "KurvenWinkel" winkel))
(if (null boegen-liste)
(progn
(alert (strcat "Keine Boegen fuer "
(if (= (type winkel) 'INT) (itoa winkel) (rtos winkel 2 1))
" Grad gefunden."))
nil
)
(progn
;; In globaler Variable fuer Dialog-Callbacks speichern
(setq *OMNI-DLG-BOEGEN* boegen-liste)
;; ProfilTyp-Liste fuer Dropdown aufbauen
(setq profil-liste
(mapcar '(lambda (e) (cdr (assoc "ProfilTyp" e))) boegen-liste))
;; DCL laden
(setq dcl-pfad (strcat (getenv "DXFM_DCL") "/omniflo_boegen.dcl"))
(setq dat (load_dialog dcl-pfad))
(if (not (new_dialog "omniflo_boegen" dat))
(progn (alert "Bogen-Dialog konnte nicht geladen werden.") nil)
(progn
;; Dropdown befuellen
(start_list "bogenart")
(mapcar 'add_list profil-liste)
(end_list)
(set_tile "bogenart" "0")
;; Startwerte anzeigen
(omni:bogen-dlg-update "0")
;; Callback bei Dropdown-Aenderung
(action_tile "bogenart" "(omni:bogen-dlg-update $value)")
;; OK/Abbrechen
(action_tile "accept"
"(setq ergebnis (atoi (get_tile \"bogenart\"))) (done_dialog 1)")
(action_tile "cancel" "(done_dialog 0)")
(start_dialog)
(unload_dialog dat)
;; Gewaehlten Eintrag zurueckgeben
(if ergebnis
(nth ergebnis *OMNI-DLG-BOEGEN*)
nil
)
)
)
)
)
)
;; ============================================================
;; OMNIFLO MODUL-BEFEHLE
;; ============================================================
;; --- Omniflo / Boegen ---
(defun c:OMNI_APB_630_90 ( / eintrag)
(setq eintrag (omni:bogen-dialog 90))
(if eintrag
(omni:insert-from-entry eintrag)
(princ "\n[BOGEN] Abgebrochen.")
)
(princ)
)
(defun c:OMNI_APB_550_675 ( / eintrag)
(setq eintrag (omni:bogen-dialog 67.5))
(if eintrag
(omni:insert-from-entry eintrag)
(princ "\n[BOGEN] Abgebrochen.")
)
(princ)
)
(defun c:OMNI_APB_630_45 ( / eintrag)
(setq eintrag (omni:bogen-dialog 45))
(if eintrag
(omni:insert-from-entry eintrag)
(princ "\n[BOGEN] Abgebrochen.")
)
(princ)
)
(defun c:OMNI_APB_550_225 ( / eintrag)
(setq eintrag (omni:bogen-dialog 22.5))
(if eintrag
(omni:insert-from-entry eintrag)
(princ "\n[BOGEN] Abgebrochen.")
)
(princ)
)
(defun c:OMNI_APB_650_180 ( / eintrag)
(setq eintrag (omni:bogen-dialog 180))
(if eintrag
(omni:insert-from-entry eintrag)
(princ "\n[BOGEN] Abgebrochen.")
)
(princ)
)
;; --- Omniflo / Aluprofil Gerade ---
;; Attribut-Definitionen fuer Aluprofil-Bloecke: ((TAG DEFAULT) ...)
;; LAENGE und LAENGEMAX werden automatisch gesetzt.
(setq *omni-profil-attrib-defs*
'(("ETIKETTE" "")
("AUFLOESE" "")
("GRUPPE" "")
("A" "")
("B" "")
("C" "")
("BESCHR" "")
("ARTINR" "")
("MENGE" "")
("POSITION" "")
("LAENGE" "")
("LAYER" "")
("TLAGE" "")
("LAENGEMAX" ""))
)
;; Attribute eines bestimmten INSERT-Entity setzen.
;; ent = Entity-Name des INSERT-Blocks
;; attrib-alist = (("TAG" . "Wert") ...)
(defun omni:attrib-set-on (ent attrib-alist / obj ed typ tag wert)
(setq obj (entnext ent))
(while obj
(setq ed (entget obj))
(setq typ (cdr (assoc 0 ed)))
(if (equal typ "SEQEND") (setq obj nil)
(progn
(if (equal typ "ATTRIB")
(progn
(setq tag (cdr (assoc 2 ed)))
(setq wert (cdr (assoc tag attrib-alist)))
(if (and wert (> (strlen wert) 0))
(progn
(entmod (subst (cons 1 wert) (assoc 1 ed) ed))
(entupd obj)
)
)
)
)
(setq obj (entnext obj))
)
)
)
)
;; Aluprofil-Fahrstrecke einfuegen.
;;
;; Ablauf:
;; 1. Nutzer waehlt Einfuegepunkt -> Text "blockname" wird horizontal platziert
;; 2. Nutzer klickt Endpunkt -> Linie definiert Fahrstreckenlaenge und Richtung
;; 3. Laenge wird gegen laengemax geprueft (Fehlermeldung bei Ueberschreitung)
;; 4. Compound-Block aus Linie + Attributen wird erzeugt und eingefuegt
;; 5. Text wird gedreht, verschoben (oberhalb Linie) und Inhalt aktualisiert
;; z.B. "APG110 L=2879"
;;
;; blockname = Profiltyp (z.B. "AP60", "AP110", "APG110")
;; laengemax = Maximale Fahrstreckenlaenge in mm
(defun omni:insert-block (blockname laengemax /
pt pt2 laenge laengeStr
dx dy angle angleDeg
textEnt textHeight textGap
perpX perpY textPt ed
lastEnt ss e bname blockEnt attribs
oldOsnap oldCmdEcho oldLayer oldAttreq oldAttdia
ok)
(setq textHeight 100.0)
(setq textGap 20.0)
(setq pt (getpoint "\nEinfuegepunkt waehlen: "))
(if (null pt)
(progn (princ "\n[OMNI] Abgebrochen.") nil)
(progn
;; Einstellungen sichern
(setq oldOsnap (getvar "OSMODE"))
(setq oldCmdEcho (getvar "CMDECHO"))
(setq oldLayer (getvar "CLAYER"))
(setvar "CMDECHO" 0)
;; 1. Text horizontal am Einfuegepunkt erzeugen (per entmake)
(entmake (list '(0 . "TEXT")
(cons 8 (getvar "CLAYER"))
(cons 10 (list (car pt) (cadr pt)
(if (caddr pt) (caddr pt) 0.0)))
(cons 40 textHeight)
(cons 1 blockname)
'(50 . 0.0)))
(setq textEnt (entlast))
;; 2. Endpunkt fuer Fahrstrecke abfragen (Schleife bei Ueberschreitung)
(setq ok nil)
(while (not ok)
(setq pt2 (getpoint pt "\nEndpunkt der Fahrstrecke waehlen: "))
(if (null pt2)
(progn
;; Abbruch: Text loeschen
(command "_.ERASE" textEnt "")
(setvar "OSMODE" oldOsnap)
(setvar "CMDECHO" oldCmdEcho)
(setvar "CLAYER" oldLayer)
(princ "\n[OMNI] Abgebrochen.")
(setq ok T pt nil)
)
(progn
(setq laenge (distance (list (car pt) (cadr pt))
(list (car pt2) (cadr pt2))))
(if (> laenge laengemax)
(alert (strcat "Die gewuenschte Fahrstreckenlaenge von "
(rtos laenge 2 0) " mm ueberschreitet die Maximallaenge von "
(rtos laengemax 2 0) " mm des Fahrstreckenprofils.\n"
"Bitte neu definieren!"))
(progn
(setq laengeStr (rtos laenge 2 0))
(setq dx (- (car pt2) (car pt))
dy (- (cadr pt2) (cadr pt)))
(setq angle (atan dy dx))
(setq angleDeg (* (/ 180.0 pi) angle))
;; 3. Compound-Block: Linie bei (0,0) + ATTDEFs
(setq lastEnt textEnt)
;; Linie von Ursprung bis (laenge, 0)
(command "_.LINE" (list 0.0 0.0) (list laenge 0.0) "")
;; Unsichtbare Attribut-Definitionen
(ssg-attrib-make-defs *omni-profil-attrib-defs* 50.0)
;; Neue Entities einsammeln (alles nach textEnt)
(setq ss (ssadd))
(setq e (entnext lastEnt))
(while e (ssadd e ss) (setq e (entnext e)))
;; Block erzeugen
(setq bname (strcat blockname "_"
(ssg-make-blockname
(list (car pt) (cadr pt)
(if (caddr pt) (caddr pt) 0.0)))))
(command "_.-BLOCK" bname (list 0.0 0.0 0.0) ss "")
;; Block einfuegen (ohne Attribut-Dialog)
(setq oldAttreq (getvar "ATTREQ"))
(setq oldAttdia (getvar "ATTDIA"))
(setvar "ATTREQ" 0)
(setvar "ATTDIA" 0)
(command "_.INSERT" bname pt 1 1 angleDeg)
(setvar "ATTREQ" oldAttreq)
(setvar "ATTDIA" oldAttdia)
(setq blockEnt (entlast))
;; 4. Attribute setzen
(setq attribs (ssg-attrib-merge
(list (cons "LAENGE" laengeStr)
(cons "A" laengeStr)
(cons "LAENGEMAX" (rtos laengemax 2 0)))
*omni-profil-attrib-defs*))
(omni:attrib-set-on blockEnt attribs)
;; 5. Text aktualisieren: oberhalb der Linie positionieren,
;; um Linienwinkel drehen, Inhalt mit Laenge ergaenzen
(setq perpX (* (- (sin angle)) textGap)
perpY (* (cos angle) textGap))
(setq textPt (list (+ (car pt) perpX)
(+ (cadr pt) perpY)
(if (caddr pt) (caddr pt) 0.0)))
(setq ed (entget textEnt))
(setq ed (subst (cons 10 textPt) (assoc 10 ed) ed))
(if (assoc 50 ed)
(setq ed (subst (cons 50 angle) (assoc 50 ed) ed))
(setq ed (append ed (list (cons 50 angle))))
)
(setq ed (subst (cons 1 (strcat blockname " L=" laengeStr))
(assoc 1 ed) ed))
(entmod ed)
(entupd textEnt)
(princ (strcat "\n[OMNI] " blockname " eingefuegt. Laenge=" laengeStr " mm"))
(setq ok T)
)
)
)
)
)
;; Einstellungen wiederherstellen
(setvar "OSMODE" oldOsnap)
(setvar "CMDECHO" oldCmdEcho)
(setvar "CLAYER" oldLayer)
pt
)
)
)
(defun c:OMNI_AP60 ()
(omni:insert-block "AP60" 7000.0)
(princ)
)
(defun c:OMNI_AP110 ()
(omni:insert-block "AP110" 6000.0)
(princ)
)
(defun c:OMNI_APG110 ()
(omni:insert-block "APG110" 6000.0)
(princ)
)
;; ============================================================
;; OMNIFLO WEICHEN-DIALOG
;; Generischer Dialog fuer Weichen-Auswahl nach Winkel/Typ
;; mit Filter fuer Schaltungstyp und Richtung
;; ============================================================
;; --- Aktuelle Filterwerte aus Radio-Buttons lesen ---
(defun omni:weichen-get-filter ( / sch ri)
(setq sch "alle")
(if (= (get_tile "sch_m") "1") (setq sch "M"))
(if (= (get_tile "sch_p") "1") (setq sch "P"))
(setq ri "alle")
(if (= (get_tile "ri_links") "1") (setq ri "1"))
(if (= (get_tile "ri_rechts") "1") (setq ri "2"))
(list sch ri)
)
;; --- Gefilterte Weichen-Liste aufbauen ---
;; basis-liste = alle Weichen fuer den gewaehlten Winkel/Typ
;; sch-filter = "M", "P" oder "alle"
;; ri-filter = "1", "2" oder "alle"
(defun omni:weichen-filter-liste (basis-liste sch-filter ri-filter / eintrag sch kr ergebnis)
(setq ergebnis nil)
(foreach eintrag basis-liste
(setq sch (cdr (assoc "Schaltungstyp" eintrag)))
(setq kr (cdr (assoc "KurvenRichtung" eintrag)))
(if (and
(or (= sch-filter "alle") (= sch sch-filter))
(or (= ri-filter "alle")
(= (omni:sivasid-to-str kr) ri-filter))
)
(setq ergebnis (cons eintrag ergebnis))
)
)
(reverse ergebnis)
)
;; --- Dropdown mit gefilterter Liste neu befuellen ---
(defun omni:weichen-dlg-refresh ( / filter sch-f ri-f gefiltert profil-liste)
(setq filter (omni:weichen-get-filter))
(setq sch-f (car filter))
(setq ri-f (cadr filter))
(setq gefiltert (omni:weichen-filter-liste *OMNI-DLG-WEICHEN-BASIS* sch-f ri-f))
(setq *OMNI-DLG-WEICHEN* gefiltert)
;; Dropdown neu befuellen
(setq profil-liste
(mapcar '(lambda (e) (cdr (assoc "ProfilTyp" e))) gefiltert))
(start_list "profiltyp")
(mapcar 'add_list profil-liste)
(end_list)
;; Ersten Eintrag anzeigen (falls vorhanden)
(if gefiltert
(progn
(set_tile "profiltyp" "0")
(omni:weichen-dlg-update "0")
)
(progn
(set_tile "val_sivasnr" "---")
(set_tile "val_winkel" "---")
(set_tile "val_breite" "---")
(set_tile "val_laenge" "---")
)
)
)
;; --- Detail-Felder im Weichen-Dialog aktualisieren ---
(defun omni:weichen-dlg-update (idx-str / idx eintrag wkl)
(setq idx (atoi idx-str))
(setq eintrag (nth idx *OMNI-DLG-WEICHEN*))
(if eintrag
(progn
(set_tile "val_sivasnr"
(omni:sivasid-to-str (omni:val eintrag "Sivasnr")))
(setq wkl (omni:val eintrag "KurvenWinkel"))
(set_tile "val_winkel"
(if (= (type wkl) 'INT) (strcat (itoa wkl) " Grad")
(strcat (rtos wkl 2 1) " Grad")
)
)
(set_tile "val_breite"
(itoa (fix (omni:val eintrag "Breite"))))
(set_tile "val_laenge"
(itoa (fix (omni:val eintrag "Länge"))))
)
)
)
;; --- Weichen-Auswahl-Dialog oeffnen ---
;; winkel = KurvenWinkel (90, 45, 0, 22.5)
;; weichentyp = "Einzelweiche", "Doppelweiche", "Dreiwegeweiche" oder nil fuer alle
;; Rueckgabe: gewaehlter Weichen-Eintrag (alist) oder nil bei Abbruch
(defun omni:weichen-dialog (winkel weichentyp / dcl-pfad dat basis-liste
profil-liste ergebnis)
(if (null *OMNI-WEICHEN*) (omni:load-data))
;; Weichen nach Winkel filtern (nil = alle Winkel)
(if winkel
(setq basis-liste (omni:filter *OMNI-WEICHEN* "KurvenWinkel" winkel))
(setq basis-liste *OMNI-WEICHEN*)
)
;; Optional nach WeichenTyp filtern
(if weichentyp
(setq basis-liste
(vl-remove-if-not
'(lambda (e) (= (cdr (assoc "WeichenTyp" e)) weichentyp))
basis-liste))
)
(if (null basis-liste)
(progn
(alert (strcat "Keine Weichen fuer "
(cond
((null winkel) "alle Winkel")
((= (type winkel) 'INT) (strcat (itoa winkel) " Grad"))
(T (strcat (rtos winkel 2 1) " Grad"))
)
(if weichentyp (strcat " / " weichentyp) "")
" gefunden."))
nil
)
(progn
;; Basis-Liste und gefilterte Liste in globalen Variablen speichern
(setq *OMNI-DLG-WEICHEN-BASIS* basis-liste)
(setq *OMNI-DLG-WEICHEN* basis-liste)
;; ProfilTyp-Liste fuer Dropdown aufbauen
(setq profil-liste
(mapcar '(lambda (e) (cdr (assoc "ProfilTyp" e))) basis-liste))
;; DCL laden
(setq dcl-pfad (strcat (getenv "DXFM_DCL") "/omniflo_weichen.dcl"))
(setq dat (load_dialog dcl-pfad))
(if (not (new_dialog "omniflo_weichen" dat))
(progn (alert "Weichen-Dialog konnte nicht geladen werden.") nil)
(progn
;; Dropdown befuellen
(start_list "profiltyp")
(mapcar 'add_list profil-liste)
(end_list)
(set_tile "profiltyp" "0")
;; Startwerte anzeigen
(omni:weichen-dlg-update "0")
;; Callback bei Dropdown-Aenderung
(action_tile "profiltyp" "(omni:weichen-dlg-update $value)")
;; Callbacks fuer Filter-Radio-Buttons (alle loesen Refresh aus)
(action_tile "sch_alle" "(omni:weichen-dlg-refresh)")
(action_tile "sch_m" "(omni:weichen-dlg-refresh)")
(action_tile "sch_p" "(omni:weichen-dlg-refresh)")
(action_tile "ri_alle" "(omni:weichen-dlg-refresh)")
(action_tile "ri_links" "(omni:weichen-dlg-refresh)")
(action_tile "ri_rechts" "(omni:weichen-dlg-refresh)")
;; OK/Abbrechen
(action_tile "accept"
"(setq ergebnis (atoi (get_tile \"profiltyp\"))) (done_dialog 1)")
(action_tile "cancel" "(done_dialog 0)")
(start_dialog)
(unload_dialog dat)
;; Gewaehlten Eintrag zurueckgeben
(if ergebnis
(nth ergebnis *OMNI-DLG-WEICHEN*)
nil
)
)
)
)
)
)
;; ============================================================
;; OMNIFLO DXF-BLOCK EINFUEGEN
;; Fuegt eine DXF-Datei aus data/omniflo/ als Block ein.
;; Der Benutzer waehlt den Einfuegepunkt und Drehwinkel.
;; ============================================================
;; --- DXF-Datei als Block einfuegen ---
;; sivasnr-str = SivasNr als String (Dateiname ohne .dxf)
;; Rueckgabe: Einfuegepunkt oder nil bei Abbruch
(defun omni:insert-dxf (sivasnr-str / dxf-pfad data-pfad pt
oldOsnap oldCmdEcho oldLayer)
(setq data-pfad (getenv "DXFM_DATA"))
(if (null data-pfad)
(progn
(princ "\n[OMNI] FEHLER: DXFM_DATA nicht gesetzt!")
nil
)
(progn
(setq dxf-pfad (strcat data-pfad "/omniflo/" sivasnr-str ".dxf"))
(if (not (findfile dxf-pfad))
(progn
(princ (strcat "\n[OMNI] FEHLER: DXF nicht gefunden: " dxf-pfad))
nil
)
(progn
(setq pt (getpoint "\nEinfuegepunkt waehlen: "))
(if (null pt)
(progn (princ "\n[OMNI] Abgebrochen.") nil)
(progn
;; Einstellungen sichern
(setq oldOsnap (getvar "OSMODE"))
(setq oldCmdEcho (getvar "CMDECHO"))
(setq oldLayer (getvar "CLAYER"))
(setvar "CMDECHO" 0)
;; Block einfuegen mit Winkelabfrage (pause)
(command "_.INSERT" dxf-pfad pt "" "" pause)
;; Einstellungen wiederherstellen
(setvar "OSMODE" oldOsnap)
(setvar "CMDECHO" oldCmdEcho)
(setvar "CLAYER" oldLayer)
(princ (strcat "\n[OMNI] " sivasnr-str " eingefuegt."))
pt
)
)
)
)
)
)
)
;; --- Eintrag aus Dialog-Ergebnis einfuegen ---
;; Nimmt einen Eintrag (alist) und fuegt die zugehoerige DXF ein.
(defun omni:insert-from-entry (eintrag / sivasnr-str)
(if eintrag
(progn
(setq sivasnr-str (omni:sivasid-to-str (omni:val eintrag "Sivasnr")))
(princ (strcat "\n[OMNI] Einfuegen: "
(omni:val eintrag "ProfilTyp") " (" sivasnr-str ")"))
(omni:insert-dxf sivasnr-str)
)
)
)
;; ============================================================
;; OMNIFLO WEICHEN-BEFEHLE
;; ============================================================
;; --- Omniflo / Weiche 90 Grad ---
(defun c:OMNI_W90_Einfach ( / eintrag)
(setq eintrag (omni:weichen-dialog 90 "Einzelweiche"))
(if eintrag
(omni:insert-from-entry eintrag)
(princ "\n[WEICHE] Abgebrochen.")
)
(princ)
)
(defun c:OMNI_W90_Doppel ( / eintrag)
(setq eintrag (omni:weichen-dialog 90 "Doppelweiche"))
(if eintrag
(omni:insert-from-entry eintrag)
(princ "\n[WEICHE] Abgebrochen.")
)
(princ)
)
(defun c:OMNI_W90_Dreiwege ( / eintrag)
(setq eintrag (omni:weichen-dialog 90 "Dreiwegeweiche"))
(if eintrag
(omni:insert-from-entry eintrag)
(princ "\n[WEICHE] Abgebrochen.")
)
(princ)
)
;; --- Omniflo / Weiche 45 Grad ---
(defun c:OMNI_W45_Einfach ( / eintrag)
(setq eintrag (omni:weichen-dialog 45 "Einzelweiche"))
(if eintrag
(omni:insert-from-entry eintrag)
(princ "\n[WEICHE] Abgebrochen.")
)
(princ)
)
(defun c:OMNI_W45_Doppel ( / eintrag)
(setq eintrag (omni:weichen-dialog 45 "Doppelweiche"))
(if eintrag
(omni:insert-from-entry eintrag)
(princ "\n[WEICHE] Abgebrochen.")
)
(princ)
)
(defun c:OMNI_W45_Dreiwege ( / eintrag)
(setq eintrag (omni:weichen-dialog 45 "Dreiwegeweiche"))
(if eintrag
(omni:insert-from-entry eintrag)
(princ "\n[WEICHE] Abgebrochen.")
)
(princ)
)
;; --- Omniflo / Weichen Parallel ---
(defun c:OMNI_WP_Einfach ( / eintrag)
(setq eintrag (omni:weichen-dialog 0 "Einzelweiche"))
(if eintrag
(omni:insert-from-entry eintrag)
(princ "\n[WEICHE] Abgebrochen.")
)
(princ)
)
(defun c:OMNI_WP_Doppel ( / eintrag)
(setq eintrag (omni:weichen-dialog 0 "Doppelweiche"))
(if eintrag
(omni:insert-from-entry eintrag)
(princ "\n[WEICHE] Abgebrochen.")
)
(princ)
)
(defun c:OMNI_WP_Dreiwege ( / eintrag)
(setq eintrag (omni:weichen-dialog 0 "Dreiwegeweiche"))
(if eintrag
(omni:insert-from-entry eintrag)
(princ "\n[WEICHE] Abgebrochen.")
)
(princ)
)
;; --- Omniflo / Weichenkoerper ---
(defun c:OMNI_WK_Einfach ( / eintrag)
(setq eintrag (omni:weichen-dialog 22.5 "Einzelweiche"))
(if eintrag
(omni:insert-from-entry eintrag)
(princ "\n[WEICHE] Abgebrochen.")
)
(princ)
)
(defun c:OMNI_WK_Doppel ( / eintrag)
(setq eintrag (omni:weichen-dialog 22.5 "Doppelweiche"))
(if eintrag
(omni:insert-from-entry eintrag)
(princ "\n[WEICHE] Abgebrochen.")
)
(princ)
)
(defun c:OMNI_WK_Dreiwege ( / eintrag)
(setq eintrag (omni:weichen-dialog 22.5 "Dreiwegeweiche"))
(if eintrag
(omni:insert-from-entry eintrag)
(princ "\n[WEICHE] Abgebrochen.")
)
(princ)
)
;; --- Omniflo / Weichenkombinationen ---
(defun c:OMNI_WKomb_Delta ( / eintrag)
(setq eintrag (omni:weichen-dialog nil "Deltaweiche"))
(if eintrag
(omni:insert-from-entry eintrag)
(princ "\n[WEICHE] Abgebrochen.")
)
(princ)
)
(defun c:OMNI_WKomb_Star ( / eintrag)
(setq eintrag (omni:weichen-dialog nil "Sternweiche"))
(if eintrag
(omni:insert-from-entry eintrag)
(princ "\n[WEICHE] Abgebrochen.")
)
(princ)
)
;; --- Omniflo / TEF Elemente ---
(defun c:OMNI_TEF_UmlenkR ()
(princ "\n[DUMMY] Umlenkspannst. rechts fuer TEF links")
(princ)
)
(defun c:OMNI_TEF_UmlenkL ()
(princ "\n[DUMMY] Umlenkspannst. links fuer TEF rechts")
(princ)
)
(defun c:OMNI_TEF_AntriebL ()
(princ "\n[DUMMY] Antriebst. links fuer TEF links")
(princ)
)
(defun c:OMNI_TEF_AntriebR ()
(princ "\n[DUMMY] Antriebst. rechts fuer TEF rechts")
(princ)
)
(defun c:OMNI_TEF_Gerade ()
(princ "\n[DUMMY] TEF Gerade")
(princ)
)
;; --- Omniflo / KettenFoerderer ---
(defun c:OMNI_KettenFoerderer ()
(princ "\n[DUMMY] KettenFoerderer")
(princ)
)