[MERGE] Lager branch in main
This commit is contained in:
@@ -0,0 +1,183 @@
|
||||
;; ============================================================
|
||||
;; JAM_EDIT.LSP - Staubereich (JAM_AREA) bearbeiten
|
||||
;;
|
||||
;; Die Staubereiche zeichnet sps_skel (lib/tro_annotate.py --anlage) als
|
||||
;; Block JAM_AREA: ein Rechteck, darin der Name Jam<NNNN>_<k>. Attribute
|
||||
;; NAME sichtbar - Jam0054_3
|
||||
;; CONVEYOR, NUMBER unsichtbar - Foerderer NNNN und laufende Nummer k
|
||||
;; TRO, ENTRY unsichtbar - TRO und Eingang, in den er fuehrt
|
||||
;; (stabiler Schluessel, nicht aendern)
|
||||
;; AREA unsichtbar - Kennung der TRO-JSON (J0039)
|
||||
;; AUTO unsichtbar - von sps_skel abgeleitete Nummer NNNN_k
|
||||
;;
|
||||
;; Aufruf JAM_EDIT:
|
||||
;; - Doppelklick auf den Staubereich -> ***DOUBLECLICK [INSERT] -> SSG_BLOCKEDIT
|
||||
;; - EATTEDIT -> c:EATTEDIT -> SSG_BLOCKEDIT
|
||||
;; - direkt: JAM_EDIT
|
||||
;; Der Dispatcher SSG_BLOCKEDIT (SSG_LIB_Commands.lsp) leitet Blocknamen
|
||||
;; "JAM_*" hierher.
|
||||
;;
|
||||
;; Der Dialog aendert nur die Zeichnung. In die SCL kommt die Aenderung mit
|
||||
;; tro_annotate.bat --file <csv> --read-jams (-> cfg/<csv>_jam_names.ini)
|
||||
;; scl_skeleton.bat --json <csv>_anlage.json --templates
|
||||
;;
|
||||
;; Setzt ssg_core.lsp (ssg-start/ssg-end, ssg-attrib-*) und ssg_lang.lsp voraus.
|
||||
;; ============================================================
|
||||
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; Nur Ziffern, nicht leer
|
||||
;; ------------------------------------------------------------
|
||||
(defun jam-ziffern-p (s)
|
||||
(and s (/= s "") (not (wcmatch s "*[~0-9]*")))
|
||||
)
|
||||
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; Name aus Foerderer und Nummer: "0054" "3" -> "Jam0054_3"
|
||||
;; ------------------------------------------------------------
|
||||
(defun jam-name (foerderer nummer)
|
||||
(strcat "Jam" foerderer "_" nummer)
|
||||
)
|
||||
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; Gibt es den Namen schon an einem anderen Staubereich?
|
||||
;; Liefert die Kennung (AREA) des anderen Blocks oder nil.
|
||||
;; ------------------------------------------------------------
|
||||
(defun jam-name-belegt (name eigener / ss i ent attribs treffer)
|
||||
(setq treffer nil)
|
||||
(if (setq ss (ssget "_X" (list '(0 . "INSERT") '(2 . "JAM_*"))))
|
||||
(progn
|
||||
(setq i 0)
|
||||
(while (and (null treffer) (setq ent (ssname ss i)))
|
||||
(if (not (eq ent eigener))
|
||||
(progn
|
||||
(setq attribs (ssg-attrib-read ent))
|
||||
(if (= (strcase (cond ((cdr (assoc "NAME" attribs))) (""))) (strcase name))
|
||||
(setq treffer (cond ((cdr (assoc "AREA" attribs))) ("?")))
|
||||
)
|
||||
)
|
||||
)
|
||||
(setq i (1+ i))
|
||||
)
|
||||
)
|
||||
)
|
||||
treffer
|
||||
)
|
||||
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; C:JAM_EDIT - Dialog fuer einen Staubereich
|
||||
;; ------------------------------------------------------------
|
||||
(defun c:JAM_EDIT ( / ss ent ed bname attribs
|
||||
alt-conv alt-nr auto tro entry area
|
||||
neu-conv neu-nr auto-conv auto-nr pos
|
||||
dcl-pfad dat ergebnis name andere)
|
||||
|
||||
;; 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 "JAM_EDIT" nil)
|
||||
|
||||
(if (null ent)
|
||||
(progn
|
||||
(princ (ssg-text "cmd-block-auswaehlen"))
|
||||
(setq ss (ssget ":S" '((0 . "INSERT"))))
|
||||
(if ss (setq ent (ssname ss 0)))
|
||||
)
|
||||
)
|
||||
(if (null ent)
|
||||
(progn (princ (ssg-text "cmd-kein-block-ausgewaehlt")) (ssg-end) (exit))
|
||||
)
|
||||
|
||||
(setq ed (entget ent)
|
||||
bname (cdr (assoc 2 ed)))
|
||||
(if (not (wcmatch bname "JAM_*"))
|
||||
(progn
|
||||
(alert (ssg-textf "jam-edit-kein-jam" (list bname)))
|
||||
(ssg-end)
|
||||
(exit)
|
||||
)
|
||||
)
|
||||
|
||||
;; --- aktuelle Attribute lesen ----------------------------------------
|
||||
(setq attribs (ssg-attrib-read ent)
|
||||
alt-conv (cond ((cdr (assoc "CONVEYOR" attribs))) (""))
|
||||
alt-nr (cond ((cdr (assoc "NUMBER" attribs))) (""))
|
||||
auto (cond ((cdr (assoc "AUTO" attribs))) (""))
|
||||
tro (cond ((cdr (assoc "TRO" attribs))) ("?"))
|
||||
entry (cond ((cdr (assoc "ENTRY" attribs))) ("?"))
|
||||
area (cond ((cdr (assoc "AREA" attribs))) ("?")))
|
||||
|
||||
;; AUTO "0054_3" -> Foerderer "0054", Nummer "3"
|
||||
(setq auto-conv "" auto-nr "")
|
||||
(if (setq pos (vl-string-search "_" auto))
|
||||
(setq auto-conv (substr auto 1 pos)
|
||||
auto-nr (substr auto (+ pos 2)))
|
||||
)
|
||||
|
||||
;; --- Dialog -----------------------------------------------------------
|
||||
(setq dcl-pfad (strcat (getenv "DXFM_DCL") "/jam_edit.dcl"))
|
||||
(setq dat (load_dialog dcl-pfad))
|
||||
(if (not (new_dialog "jam_edit" dat))
|
||||
(progn
|
||||
(alert (ssg-textf "jam-edit-dialog-fehlt" (list dcl-pfad)))
|
||||
(ssg-end)
|
||||
(exit)
|
||||
)
|
||||
)
|
||||
|
||||
(set_tile "bereich" (ssg-textf "jam-edit-bereich" (list area tro entry)))
|
||||
(set_tile "auto" (ssg-textf "jam-edit-auto"
|
||||
(list (if (= auto "") "-" (jam-name auto-conv auto-nr)))))
|
||||
(set_tile "hinweis" (ssg-text "jam-edit-hinweis"))
|
||||
(set_tile "conveyor" alt-conv)
|
||||
(set_tile "number" alt-nr)
|
||||
(if (= auto "") (mode_tile "reset" 1))
|
||||
|
||||
(setq neu-conv alt-conv neu-nr alt-nr)
|
||||
(action_tile "reset"
|
||||
"(set_tile \"conveyor\" auto-conv) (set_tile \"number\" auto-nr)")
|
||||
(action_tile "accept"
|
||||
(strcat "(setq neu-conv (vl-string-trim \" \" (get_tile \"conveyor\"))"
|
||||
" neu-nr (vl-string-trim \" \" (get_tile \"number\")))"
|
||||
"(done_dialog 1)"))
|
||||
(action_tile "cancel" "(done_dialog 0)")
|
||||
|
||||
(setq ergebnis (start_dialog))
|
||||
(unload_dialog dat)
|
||||
|
||||
;; --- pruefen und zurueckschreiben -------------------------------------
|
||||
(if (= ergebnis 1)
|
||||
(cond
|
||||
((not (and (jam-ziffern-p neu-conv) (= (strlen neu-conv) 4)))
|
||||
(alert (ssg-text "jam-edit-foerderer-ungueltig")))
|
||||
((not (and (jam-ziffern-p neu-nr) (> (atoi neu-nr) 0)))
|
||||
(alert (ssg-text "jam-edit-nummer-ungueltig")))
|
||||
(t
|
||||
(setq neu-nr (itoa (atoi neu-nr))
|
||||
name (jam-name neu-conv neu-nr))
|
||||
(ssg-attrib-set-on ent (list (cons "CONVEYOR" neu-conv)
|
||||
(cons "NUMBER" neu-nr)
|
||||
(cons "NAME" name)))
|
||||
(entupd ent)
|
||||
(princ (ssg-textf "jam-edit-gespeichert" (list name area)))
|
||||
(if (setq andere (jam-name-belegt name ent))
|
||||
(princ (ssg-textf "jam-edit-doppelt" (list name andere)))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(ssg-end)
|
||||
(princ)
|
||||
)
|
||||
|
||||
|
||||
(prompt "\nJam_Edit.lsp geladen - Befehl: JAM_EDIT")
|
||||
(princ)
|
||||
File diff suppressed because it is too large
Load Diff
+143
-91
@@ -420,6 +420,18 @@
|
||||
att-entity att-data att-tag new-value
|
||||
beforeAtt)
|
||||
|
||||
;; Mindestabstand: unterhalb des Durchmessers wuerden sich die Endkreise
|
||||
;; (AN8/SP8) beruehren bzw. ueberschneiden - harte Sperre fuer alle Aufrufer
|
||||
;; (Insert/Connect/Redraw/Edit/Script), da draw-module der einzige
|
||||
;; gemeinsame Zeichenpfad ist.
|
||||
(if (< abstand *kreisel-durchmesser*)
|
||||
(progn
|
||||
(ssg-emsg (ssg-textf "kreisel-emsg-abstand-zu-klein"
|
||||
(list (rtos abstand 2 0) (rtos *kreisel-durchmesser* 2 0))))
|
||||
(exit)
|
||||
)
|
||||
)
|
||||
|
||||
;; Attribute vorbereiten
|
||||
(setq attribs (ssg-attrib-merge attribs *kreisel-attrib-defs*))
|
||||
(setq attribs (subst (cons "ABSTAND" (rtos abstand 2 0))
|
||||
@@ -695,11 +707,23 @@
|
||||
)
|
||||
|
||||
;; 2. Abstand (Tangentenlaenge) - Linie gibt auch den Winkel vor
|
||||
(setq p2 (getpoint pt (ssg-textf "kreisel-prompt-abstand"
|
||||
(list (rtos *kreisel-default-laenge* 2 0)))))
|
||||
(setq erg (kreisel-insert-richtung pt p2 *kreisel-default-laenge*)
|
||||
abstand (car erg)
|
||||
rotation (cadr erg))
|
||||
;; Mindestabstand = Kreisel-Durchmesser (sonst beruehren/ueberschneiden
|
||||
;; sich die Endkreise) - bei Unterschreitung erneut abfragen.
|
||||
(setq abstand nil)
|
||||
(while (null abstand)
|
||||
(setq p2 (getpoint pt (ssg-textf "kreisel-prompt-abstand"
|
||||
(list (rtos *kreisel-default-laenge* 2 0)))))
|
||||
(setq erg (kreisel-insert-richtung pt p2 *kreisel-default-laenge*)
|
||||
abstand (car erg)
|
||||
rotation (cadr erg))
|
||||
(if (< abstand *kreisel-durchmesser*)
|
||||
(progn
|
||||
(ssg-emsg (ssg-textf "kreisel-emsg-abstand-zu-klein"
|
||||
(list (rtos abstand 2 0) (rtos *kreisel-durchmesser* 2 0))))
|
||||
(setq abstand nil)
|
||||
)
|
||||
)
|
||||
)
|
||||
(princ (ssg-textf "kreisel-abstand-ausgabe" (list (rtos abstand 2 0))))
|
||||
|
||||
;; 3. Hoehe (Z-Koordinate)
|
||||
@@ -747,24 +771,29 @@
|
||||
(progn (ssg-end) (princ (ssg-text "kreisel-abgebrochen")) (princ) (exit))
|
||||
)
|
||||
|
||||
;; 2. Endpunkt (aeusserster Punkt SP-Seite) mit Gummiband
|
||||
(setq ptEnd (getpoint ptStart (ssg-text "kreisel-prompt-endpunkt")))
|
||||
(if (null ptEnd)
|
||||
(progn (ssg-end) (princ (ssg-text "kreisel-abgebrochen")) (princ) (exit))
|
||||
)
|
||||
;; 2. Endpunkt (aeusserster Punkt SP-Seite) mit Gummiband - der Abstand
|
||||
;; (Kreismitten-Tangentenlaenge = dist - Durchmesser) muss mindestens dem
|
||||
;; Durchmesser entsprechen, sonst beruehren/ueberschneiden sich die
|
||||
;; Endkreise; bei Unterschreitung erneut abfragen statt abzubrechen.
|
||||
(setq abstand nil)
|
||||
(while (null abstand)
|
||||
(setq ptEnd (getpoint ptStart (ssg-text "kreisel-prompt-endpunkt")))
|
||||
(if (null ptEnd)
|
||||
(progn (ssg-end) (princ (ssg-text "kreisel-abgebrochen")) (princ) (exit))
|
||||
)
|
||||
|
||||
;; 3. Geometrie berechnen
|
||||
(setq dx (- (car ptEnd) (car ptStart))
|
||||
dy (- (cadr ptEnd) (cadr ptStart)))
|
||||
(setq dist (sqrt (+ (* dx dx) (* dy dy))))
|
||||
(setq abstand (- dist *kreisel-durchmesser*))
|
||||
;; 3. Geometrie berechnen
|
||||
(setq dx (- (car ptEnd) (car ptStart))
|
||||
dy (- (cadr ptEnd) (cadr ptStart)))
|
||||
(setq dist (sqrt (+ (* dx dx) (* dy dy))))
|
||||
(setq abstand (- dist *kreisel-durchmesser*))
|
||||
|
||||
(if (<= abstand 0.0)
|
||||
(progn
|
||||
(ssg-emsg (ssg-textf "kreisel-emsg-distanz-klein"
|
||||
(list (rtos dist 2 0) (rtos *kreisel-durchmesser* 2 0))))
|
||||
(ssg-end)
|
||||
(exit)
|
||||
(if (< abstand *kreisel-durchmesser*)
|
||||
(progn
|
||||
(ssg-emsg (ssg-textf "kreisel-emsg-distanz-klein"
|
||||
(list (rtos dist 2 0) (rtos (* 2.0 *kreisel-durchmesser*) 2 0))))
|
||||
(setq abstand nil)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -883,7 +912,7 @@
|
||||
;; geaendertem) Abstand neu. Alle Attribute bleiben
|
||||
;; erhalten.
|
||||
;; -----------------------------------------------
|
||||
(defun c:KreiselRedraw ( / sel ent ed attribs basePoint rotation newAbstand)
|
||||
(defun c:KreiselRedraw ( / sel ent ed attribs basePoint rotation newAbstand gueltig)
|
||||
|
||||
(ssg-start (ssg-text "kreisel-start-redraw") '(("CECOLOR")))
|
||||
|
||||
@@ -910,11 +939,20 @@
|
||||
(cdr (assoc "HOEHE" attribs))
|
||||
(cdr (assoc "KREISELART" attribs)))))
|
||||
|
||||
;; 3. Neuen Abstand abfragen (Enter = beibehalten)
|
||||
(initget 6)
|
||||
(setq newAbstand (getdist (ssg-textf "kreisel-prompt-neuer-abstand" (list (cdr (assoc "ABSTAND" attribs))))))
|
||||
(if (null newAbstand)
|
||||
(setq newAbstand (atof (cdr (assoc "ABSTAND" attribs))))
|
||||
;; 3. Neuen Abstand abfragen (Enter = beibehalten); Mindestabstand =
|
||||
;; Kreisel-Durchmesser, sonst beruehren/ueberschneiden sich die Endkreise.
|
||||
(setq newAbstand nil gueltig nil)
|
||||
(while (not gueltig)
|
||||
(initget 6)
|
||||
(setq newAbstand (getdist (ssg-textf "kreisel-prompt-neuer-abstand" (list (cdr (assoc "ABSTAND" attribs))))))
|
||||
(if (null newAbstand)
|
||||
(setq newAbstand (atof (cdr (assoc "ABSTAND" attribs))))
|
||||
)
|
||||
(if (< newAbstand *kreisel-durchmesser*)
|
||||
(ssg-emsg (ssg-textf "kreisel-emsg-abstand-zu-klein"
|
||||
(list (rtos newAbstand 2 0) (rtos *kreisel-durchmesser* 2 0))))
|
||||
(setq gueltig T)
|
||||
)
|
||||
)
|
||||
;; NEU - Neue Höhe abfragen:
|
||||
(setq newHoehe (getreal (ssg-textf "kreisel-prompt-neue-hoehe" (list (cdr (assoc "HOEHE" attribs))))))
|
||||
@@ -991,7 +1029,7 @@
|
||||
;; 3. Bei OK: Block loeschen und mit neuen Werten neu zeichnen
|
||||
;; -----------------------------------------------
|
||||
(defun c:KreiselEdit ( / sel ss ent ed attribs basePoint rotation
|
||||
dcl-pfad dat ergebnis
|
||||
dcl-pfad dat ergebnis fertig
|
||||
dlg-name dlg-abstand dlg-hoehe dlg-ausrichtung
|
||||
dlg-drehrichtung dlg-kreiselart dlg-geruest-einzelmodul
|
||||
dlg-geruest-typ
|
||||
@@ -1049,73 +1087,87 @@
|
||||
(princ (ssg-textf "kreisel-edit-bestehend"
|
||||
(list (cdr (assoc "ABSTAND" attribs)) (rtos rotation 2 1) (cdr (assoc "KREISELART" attribs)))))
|
||||
|
||||
;; 3. DCL-Dialog laden
|
||||
(setq dcl-pfad (strcat (getenv "DXFM_DCL") "/kreisel_edit.dcl"))
|
||||
(setq dat (load_dialog dcl-pfad))
|
||||
(if (not (new_dialog "kreisel_edit" dat))
|
||||
(progn (alert (ssg-textf "kreisel-edit-dialog-fehlt" (list dcl-pfad))) (ssg-end) (exit))
|
||||
)
|
||||
;; 3. DCL-Dialog laden; bei zu kleinem Abstand (< Kreisel-Durchmesser,
|
||||
;; sonst beruehren/ueberschneiden sich die Endkreise) erneut anzeigen,
|
||||
;; statt den fehlerhaften Wert zu uebernehmen (Projektmuster wie GERUEST).
|
||||
(setq dlg-abstand (cdr (assoc "ABSTAND" attribs)))
|
||||
(setq fertig nil)
|
||||
(while (not fertig)
|
||||
(setq dcl-pfad (strcat (getenv "DXFM_DCL") "/kreisel_edit.dcl"))
|
||||
(setq dat (load_dialog dcl-pfad))
|
||||
(if (not (new_dialog "kreisel_edit" dat))
|
||||
(progn (alert (ssg-textf "kreisel-edit-dialog-fehlt" (list dcl-pfad))) (ssg-end) (exit))
|
||||
)
|
||||
|
||||
;; Ausrichtungs-Labels fuer popup_list aufbauen
|
||||
(setq ausrichtLabels "")
|
||||
(foreach entry *kreisel-ausrichtungen*
|
||||
(if (= ausrichtLabels "")
|
||||
(setq ausrichtLabels (car entry))
|
||||
(setq ausrichtLabels (strcat ausrichtLabels "\n" (car entry)))
|
||||
;; Ausrichtungs-Labels fuer popup_list aufbauen
|
||||
(setq ausrichtLabels "")
|
||||
(foreach entry *kreisel-ausrichtungen*
|
||||
(if (= ausrichtLabels "")
|
||||
(setq ausrichtLabels (car entry))
|
||||
(setq ausrichtLabels (strcat ausrichtLabels "\n" (car entry)))
|
||||
)
|
||||
)
|
||||
|
||||
;; Tiles initialisieren (Abstand aus vorherigem Versuch uebernehmen)
|
||||
(set_tile "name" (cdr (assoc "Bezeichnung" attribs)))
|
||||
(set_tile "abstand" dlg-abstand)
|
||||
(set_tile "hoehe" (cdr (assoc "HOEHE" attribs)))
|
||||
|
||||
(start_list "ausrichtung")
|
||||
(foreach entry *kreisel-ausrichtungen*
|
||||
(add_list (car entry))
|
||||
)
|
||||
(end_list)
|
||||
(set_tile "ausrichtung" (itoa (kreisel-rotation-to-idx rotation)))
|
||||
|
||||
(start_list "drehrichtung")
|
||||
(add_list "UZS")
|
||||
(add_list "GUZ")
|
||||
(end_list)
|
||||
(set_tile "drehrichtung" (if (equal (cdr (assoc "DREHRICHTUNG" attribs)) "GUZ") "1" "0"))
|
||||
|
||||
(start_list "kreiselart")
|
||||
(add_list "STANDARD")
|
||||
(add_list "PIN")
|
||||
(end_list)
|
||||
(set_tile "kreiselart" (if (equal (cdr (assoc "KREISELART" attribs)) "PIN") "1" "0"))
|
||||
|
||||
(set_tile "geruest_einzelmodul"
|
||||
(if (equal (cdr (assoc "GERUEST_EINZELMODUL" attribs)) "1") "1" "0"))
|
||||
|
||||
(start_list "geruest_typ")
|
||||
(foreach opt *ssg-geruest-optionen* (add_list opt))
|
||||
(end_list)
|
||||
(set_tile "geruest_typ" (itoa (ssg-geruest-typ-to-idx (cdr (assoc "GERUEST_TYP" attribs)))))
|
||||
|
||||
;; Actions
|
||||
(action_tile "accept"
|
||||
(strcat
|
||||
"(setq dlg-name (get_tile \"name\"))"
|
||||
"(setq dlg-abstand (get_tile \"abstand\"))"
|
||||
"(setq dlg-hoehe (get_tile \"hoehe\"))"
|
||||
"(setq dlg-ausrichtung (get_tile \"ausrichtung\"))"
|
||||
"(setq dlg-drehrichtung (get_tile \"drehrichtung\"))"
|
||||
"(setq dlg-kreiselart (get_tile \"kreiselart\"))"
|
||||
"(setq dlg-geruest-einzelmodul (get_tile \"geruest_einzelmodul\"))"
|
||||
"(setq dlg-geruest-typ (get_tile \"geruest_typ\"))"
|
||||
"(done_dialog 1)"
|
||||
)
|
||||
)
|
||||
(action_tile "cancel" "(done_dialog 0)")
|
||||
|
||||
(setq ergebnis (start_dialog))
|
||||
(unload_dialog dat)
|
||||
|
||||
(cond
|
||||
((/= ergebnis 1) (setq fertig T))
|
||||
((< (atof dlg-abstand) *kreisel-durchmesser*)
|
||||
(ssg-emsg (ssg-textf "kreisel-emsg-abstand-zu-klein"
|
||||
(list (rtos (atof dlg-abstand) 2 0) (rtos *kreisel-durchmesser* 2 0)))))
|
||||
(t (setq fertig T))
|
||||
)
|
||||
)
|
||||
|
||||
;; Tiles initialisieren
|
||||
(set_tile "name" (cdr (assoc "Bezeichnung" attribs)))
|
||||
(set_tile "abstand" (cdr (assoc "ABSTAND" attribs)))
|
||||
(set_tile "hoehe" (cdr (assoc "HOEHE" attribs)))
|
||||
|
||||
(start_list "ausrichtung")
|
||||
(foreach entry *kreisel-ausrichtungen*
|
||||
(add_list (car entry))
|
||||
)
|
||||
(end_list)
|
||||
(set_tile "ausrichtung" (itoa (kreisel-rotation-to-idx rotation)))
|
||||
|
||||
(start_list "drehrichtung")
|
||||
(add_list "UZS")
|
||||
(add_list "GUZ")
|
||||
(end_list)
|
||||
(set_tile "drehrichtung" (if (equal (cdr (assoc "DREHRICHTUNG" attribs)) "GUZ") "1" "0"))
|
||||
|
||||
(start_list "kreiselart")
|
||||
(add_list "STANDARD")
|
||||
(add_list "PIN")
|
||||
(end_list)
|
||||
(set_tile "kreiselart" (if (equal (cdr (assoc "KREISELART" attribs)) "PIN") "1" "0"))
|
||||
|
||||
(set_tile "geruest_einzelmodul"
|
||||
(if (equal (cdr (assoc "GERUEST_EINZELMODUL" attribs)) "1") "1" "0"))
|
||||
|
||||
(start_list "geruest_typ")
|
||||
(foreach opt *ssg-geruest-optionen* (add_list opt))
|
||||
(end_list)
|
||||
(set_tile "geruest_typ" (itoa (ssg-geruest-typ-to-idx (cdr (assoc "GERUEST_TYP" attribs)))))
|
||||
|
||||
;; Actions
|
||||
(action_tile "accept"
|
||||
(strcat
|
||||
"(setq dlg-name (get_tile \"name\"))"
|
||||
"(setq dlg-abstand (get_tile \"abstand\"))"
|
||||
"(setq dlg-hoehe (get_tile \"hoehe\"))"
|
||||
"(setq dlg-ausrichtung (get_tile \"ausrichtung\"))"
|
||||
"(setq dlg-drehrichtung (get_tile \"drehrichtung\"))"
|
||||
"(setq dlg-kreiselart (get_tile \"kreiselart\"))"
|
||||
"(setq dlg-geruest-einzelmodul (get_tile \"geruest_einzelmodul\"))"
|
||||
"(setq dlg-geruest-typ (get_tile \"geruest_typ\"))"
|
||||
"(done_dialog 1)"
|
||||
)
|
||||
)
|
||||
(action_tile "cancel" "(done_dialog 0)")
|
||||
|
||||
(setq ergebnis (start_dialog))
|
||||
(unload_dialog dat)
|
||||
|
||||
;; 4. Bei OK: Block loeschen und neu zeichnen
|
||||
(if (= ergebnis 1)
|
||||
(progn
|
||||
|
||||
@@ -1538,10 +1538,12 @@
|
||||
)
|
||||
|
||||
;; --- Omniflo / KettenFoerderer ---
|
||||
(defun c:OMNI_KettenFoerderer ()
|
||||
(princ "\n[DUMMY] KettenFoerderer")
|
||||
(princ)
|
||||
)
|
||||
;; Der Platzhalter c:OMNI_KettenFoerderer (reiner Dummy, gab nur "[DUMMY]
|
||||
;; KettenFoerderer" aus und war im Menue ausgegraut) wurde entfernt: der
|
||||
;; Kettenfoerderer ist seit 2026-10-22 als eigene Baugruppe umgesetzt, der
|
||||
;; Menueeintrag zeigt jetzt auf (ssg-ensure "KettenFoerderer") KETTENFOERDERER
|
||||
;; (Lisp/KettenFoerderer.lsp). Damit war der Dummy toter Code - auf ihn verwies
|
||||
;; nur noch der Menueeintrag selbst.
|
||||
|
||||
|
||||
;; --- Omniflo / Ladeschleifen ---
|
||||
|
||||
+89
-32
@@ -38,21 +38,22 @@ am Label-Anfang, bei Submenue-Schliessern hinter dem `<-` (`[<-~Label]`).
|
||||
|
||||
| Menuebereich | Eintraege | Definiert in |
|
||||
| --- | --- | --- |
|
||||
| Omniflo ▸ Anbaugruppen | `OMNI_KettenFoerderer` | `OmniModulInsert.lsp` |
|
||||
| Omniflo ▸ Boegen fuer Weichen | alle `OMNI_APBW_*` (14) | `OmniModulInsert.lsp` |
|
||||
| ILS ▸ Zusatzmodule/Kurven | `ILS_ETF_Etagenfoerderer`, `ILS_K{90,60,30}{L,R}{A,I}` (12), `ILS_Gefaellestrecke` | `SSG_LIB_Commands.lsp` |
|
||||
| Geruest | `GERUEST` (Gattertraeger-Platzhalter, derselbe Befehl wie Saeulen/Rohrabhaenger/Wandbefestigung) | `GeruestInsert.lsp` |
|
||||
|
||||
`OMNI_TEF_*` (UmlenkR/L, AntriebL/R, TEF Gerade) sind entgegen frueherem Stand
|
||||
**implementiert** (echtes `omni:insert-dxf`), nur `OMNI_KettenFoerderer` ist
|
||||
weiterhin Dummy.
|
||||
**implementiert** (echtes `omni:insert-dxf`). Der Menueeintrag KettenFoerderer ist
|
||||
ebenfalls aktiv (Modul `KettenFoerderer.lsp`, Beschreibung in `CLAUDE.md`).
|
||||
|
||||
Aktiv (implementiert) sind u.a.: Kreisel, Eckrad, VarioFoerderer (Standard/Etage/
|
||||
Linienzug), Gefaellestrecke, Geruest (Saeulen/Rohrabhaenger/Wandbefestigung/
|
||||
Rohr-Geruest-Traeger), TRO-Marker, Connections, BTMT Be-/Entladung, Scanner/
|
||||
Separator, Omniflo Boegen (APB)/TEF-Elemente/Aluprofil-Geraden (AP)/alle Weichen
|
||||
(W90/W45/WP/WK/WKomb)/Ladeschleifen, Export (Sivas/CSV), Werkzeuge (Block-/
|
||||
Text-Tools, Planquadrate) und die Tests.
|
||||
(W90/W45/WP/WK/WKomb)/Ladeschleifen/Schwenkschienen/Fahrstrecke, Kettenfoerderer,
|
||||
Export (Sivas/CSV), Werkzeuge (Block-/Text-Tools, Faehnchen + Stueckliste,
|
||||
DIN-Formate, Planquadrate) und die Tests. Die frueheren Dummy-Befehle fuer ILS-Kurven
|
||||
(`ILS_K*`), Etagenfoerderer (`ILS_ETF_*`) und `ILS_Gefaellestrecke` wurden samt
|
||||
Menueeintraegen entfernt.
|
||||
|
||||
---
|
||||
|
||||
@@ -383,6 +384,10 @@ Gefaellestrecke/`vf_core` geladen sein; Kern-Modul.
|
||||
| `extract-ks-from-block[-raw] name` | KS_EIN/KS_AUS-Punkte eines Blocks ermitteln (Cache `*ks-cache*`) |
|
||||
| `insert-block-by-ks name ks-nr pt` | Block anhand KS-Punkt einfuegen (nur Rz-Rotation) |
|
||||
| `insert-inclined-scaled-block` / `insert-rotated-block-with-ks` | Geneigten/rotierten Block mit KS-Offset einfuegen (Rz*Ry) |
|
||||
| `ks-xy-winkel ks-eintrag` | Richtung der X-Achse eines KS in der XY-Ebene (Grad); `nil` bei senkrechter Achse |
|
||||
| `ks-block-messen name` / `ks-versatz ks-data` | KS eines Blocks messen, ohne bleibende Einfuegung / Versatz KS_AUS-KS_EIN |
|
||||
| `insert-block-ks-skaliert name pt hz skala` | Wie `insert-block-by-ks`, zusaetzlich in X skaliert |
|
||||
| `insert-block-ks-matrix name pt R skala` | Einfuegen mit **freier 3x3-Rotationsmatrix** (`ks-rot-x/-y/-z`), z.B. fuer aufgerichtete Baugruppen |
|
||||
|
||||
---
|
||||
|
||||
@@ -578,9 +583,9 @@ umbiegen. Falls das bereits passiert ist, hilft nur ein manuelles
|
||||
|
||||
---
|
||||
|
||||
### `tests.lsp` – Testbefehle
|
||||
### `external_call.lsp` – Python-Aufruf testen
|
||||
|
||||
Testbefehle für die Python-Integration. Export-Funktionen wurden in `export.lsp` ausgelagert.
|
||||
Testbefehl für die Python-Integration (frueher `tests.lsp`). Export-Funktionen liegen in `export.lsp`.
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
| --- | --- |
|
||||
@@ -605,7 +610,7 @@ Verzeichnisstruktur: [`../tests/README.md`](../tests/README.md)):
|
||||
|
||||
Welche JSON-Angaben pro Element-Typ nötig sind (abgeleitet aus den
|
||||
Produktions-Routinen, nicht aus den Test-Wrappern), dokumentiert
|
||||
[`../tests/testdata/object_data.md`](../tests/testdata/object_data.md) –
|
||||
[`../doc/json-input-lisp.md`](../doc/json-input-lisp.md) (Nachfolger des geloeschten `tests/testdata/object_data.md`) –
|
||||
inkl. der Unterscheidung scriptbar vs. nur-interaktiv.
|
||||
|
||||
### LISP-Unit-Tests (`test_unit.lsp`)
|
||||
@@ -701,7 +706,7 @@ AutoLISP-Implementierung fuer alle Omniflo-Komponenten: Boegen, Weichen, Verbind
|
||||
| Geraden | `OMNI_AP60`, `OMNI_AP110`, `OMNI_APG110` | Omniflo-Geradenstuecke |
|
||||
| Ladeschleifen | `OMNI_LADESCHLEIFE_AP110` | Ladeschleife aus `omniflo_ladeschleifen.json` ueber DCL-Dialog (`dcl/omniflo_ladeschleifen.dcl`) einfuegen; Daten per `ssg-json-laden` (Beschreibungen enthalten Kommas). Blockdatei `<Sivasnr>.dwg` unter `DXFM_OMNIFLO` (`omni:insert-dxf` faellt auf `.dwg` zurueck, wenn keine `.dxf` existiert). Per `OMNI_EDIT` editierbar |
|
||||
| TEF Elemente | `OMNI_TEF_UmlenkR/L`, `OMNI_TEF_AntriebL/R`, `OMNI_TEF_Gerade` | Feste TEF-Bauteile ohne Sivas-Auswahl, direkt per `omni:insert-dxf` an gewaehltem Punkt eingefuegt (Dateien unter `DXFM_OMNIFLO`) |
|
||||
| Anbaugruppen ⚠️ | `OMNI_KettenFoerderer` | **Dummy** (noch nicht implementiert, im Menue ausgegraut); `OMNI_STOPPER`/`OMNI_SCANNER`/`OMNI_BUERSTENBREMSE` sind implementiert |
|
||||
| Anbaugruppen | `OMNI_STOPPER`, `OMNI_SCANNER`, `OMNI_BUERSTENBREMSE` | Implementiert |
|
||||
| Verbinder | `OMNI_TV_*` | Verbinder-DWG aus `data/omniflo/Verbinder` (dimensionsunabhaengig, `omni:insert-verbinder` -> `omni:insert-datei`, Punkt + Drehung interaktiv). Zuordnung Befehl -> DWG nach Dateiname, z.B. `OMNI_TV_W_AP60` -> `TV_W-AP60_oben`, `OMNI_TV_ENDPLATTE` -> `VB_ENDP_AP`, `OMNI_TV_W_AP60_KPL` -> `TV_W-AP60_kpl`, `OMNI_TV_ANSCHLAG` -> `VB_ENDP_AP_Spulenzug`, `OMNI_TV_SW_I_AP110` -> `TV_SW_I_SW-AP110`, `OMNI_TV_MUFFE` -> `VB_Muffe`. Alle 18 Eintraege aktiv |
|
||||
| Bogenweichen ⚠️ | `OMNI_APBW_*` | **Dummy** (noch nicht implementiert, im Menue ausgegraut) |
|
||||
| Bearbeiten | `OMNI_EDIT` | Omniflo-Block selektieren und Attribute bearbeiten |
|
||||
@@ -712,13 +717,12 @@ nicht zu verwechseln mit den einzelnen `OMNI_TEF_*`-Befehlen oben.
|
||||
|
||||
---
|
||||
|
||||
### `SSG_LIB_Commands.lsp` – BTMT, Sensoren, Dummy-Befehle, Konfiguration und SSG_BLOCKEDIT
|
||||
### `SSG_LIB_Commands.lsp` – BTMT, Sensoren, Konfiguration und SSG_BLOCKEDIT
|
||||
|
||||
Sammeldatei fuer Menue-Befehle: teils Platzhalter fuer noch nicht implementierte
|
||||
Eintraege, teils bereits **echte** Funktionalitaet (BTMT Be-/Entladung, Sensoren,
|
||||
Konfiguration, Doppelklick-Dispatcher). Alle noch offenen Dummy-Menueintraege sind in
|
||||
`menu/SSG_LIB.mnu` mit `~` ausgegraut (siehe Abschnitt
|
||||
["Status: noch offene Menueintraege"](#status-noch-offene-menueintraege-im-menue-ausgegraut)).
|
||||
Sammeldatei fuer Menue-Befehle: BTMT Be-/Entladung, Sensoren, Eingang/Ausgang,
|
||||
Konfiguration und der Doppelklick-Dispatcher. Die frueheren Dummy-Befehle (ILS-Kurven,
|
||||
Etagenfoerderer) sind entfernt; noch offene Menueintraege anderer Module siehe Abschnitt
|
||||
["Status: noch offene Menueintraege"](#status-noch-offene-menueintraege-im-menue-ausgegraut).
|
||||
|
||||
**Sensoren einfuegen** (real, ueber `ils-insert-sensor` → wiederholtes `_.INSERT`
|
||||
mit interaktivem Einfuegepunkt/Rotation, Blockdatei via `ssg-ils-block-datei`):
|
||||
@@ -760,15 +764,6 @@ Sivas-Export zusaetzlich in den Summenzaehlern "Anzahl aller BTBeladung"/
|
||||
dieselbe `ils-insert-station`-Routine wie BTMT Be-/Entladung (frei platzierbar,
|
||||
Blöcke `Eingang_<DIM>.dwg`/`Ausgang_<DIM>.dwg` in `data/ils`).
|
||||
|
||||
Registrierte Dummy-Befehle:
|
||||
|
||||
| Gruppe | Befehle |
|
||||
| --- | --- |
|
||||
| ILS Zusatzmodule | `ILS_ETF_Etagenfoerderer`|
|
||||
| ILS Kurven angetrieben Aussen | `ILS_K90LA`, `ILS_K90RA`, `ILS_K60LA`, `ILS_K60RA`, `ILS_K30LA`, `ILS_K30RA` |
|
||||
| ILS Kurven angetrieben Innen | `ILS_K90LI`, `ILS_K90RI`, `ILS_K60LI`, `ILS_K60RI`, `ILS_K30LI`, `ILS_K30RI` |
|
||||
| ILS Gefaellestrecken-Kurven | `ILS_Gefaellestrecke` |
|
||||
|
||||
> `FOERDERANLAGE` ist nicht hier definiert – dieser Befehl ist in `VarioFoerderer.lsp` implementiert.
|
||||
|
||||
**Konfigurationsbefehle** (Menue → Konfiguration):
|
||||
@@ -776,11 +771,12 @@ Registrierte Dummy-Befehle:
|
||||
| Befehl | Beschreibung |
|
||||
| --- | --- |
|
||||
| `SSG_DIM_SWITCH` | Schaltet zwischen 2D/3D-Bloecken um (setzt `DXFM_DIM`, `DXFM_BLOCKS`, `DXFM_OMNIFLO`) |
|
||||
| `SSG_DIM_ALL_2D` / `SSG_DIM_ALL_3D` | Alle VF_n-/GF_n-Bloecke der Zeichnung nach 2D bzw. 3D umbauen |
|
||||
| `SSG_SPRACHE` | Oeffnet Dialog `sprache.dcl`, setzt `*ssg-lang*` und persistiert via `DXFM_LANG` (siehe [`ssg_lang.lsp`](#ssg_langlsp--sprachumschaltung-deutschenglisch)) |
|
||||
|
||||
**SSG_BLOCKEDIT** – Doppelklick/Kontextmenue-Dispatcher:
|
||||
|
||||
Erkennt den Blocktyp des selektierten INSERT-Blocks und ruft den passenden Bearbeitungsbefehl auf (Reihenfolge wichtig: `GR_*` **vor** dem Omniflo-Zweig, da Geruest-Bloecke ebenfalls ein TEILEART-Attribut tragen):
|
||||
Erkennt den Blocktyp des selektierten INSERT-Blocks und ruft den passenden Bearbeitungsbefehl auf (Reihenfolge wichtig: `GR_*` und `KF_*` **vor** dem Omniflo-Zweig, da diese Bloecke ebenfalls ein TEILEART-Attribut tragen koennen):
|
||||
|
||||
| Blockmuster | Aktion |
|
||||
| --- | --- |
|
||||
@@ -788,8 +784,11 @@ Erkennt den Blocktyp des selektierten INSERT-Blocks und ruft den passenden Bearb
|
||||
| `ECKRAD_*` | `EckradEdit` |
|
||||
| `GF_*` | `GEFAELLESTRECKE_EDIT` |
|
||||
| `VF_*` | `VARIOFOERDERER_EDIT` |
|
||||
| `GR_*` | Geruest – `BEDIT` (kein eigener Edit-Pfad; siehe `GeruestInsert.lsp`) |
|
||||
| `CONNECTION_*` | `CONNECTION_EDIT` |
|
||||
| `JAM_*` | `JAM_EDIT` |
|
||||
| `TRO_*` | `TRO_EDIT` |
|
||||
| `GR_*` | Geruest – nativer Attribut-Editor `_.EATTEDIT` (kein eigener Edit-Pfad; siehe `GeruestInsert.lsp`) |
|
||||
| `KF_*` | `KF_EDIT` |
|
||||
| Omniflo (TEILEART-Attribut, AP110*, numerisch) | `OMNI_EDIT` |
|
||||
| Sonstige | `BEDIT` (Block-Editor) |
|
||||
|
||||
@@ -800,18 +799,20 @@ Erkennt den Blocktyp des selektierten INSERT-Blocks und ruft den passenden Bearb
|
||||
Rohr-Geruest-Baugruppen (Saeulen, Rohrabhaenger, Wandbefestigung, Rohr-Geruest-Traeger)
|
||||
aus [`data/json/geruest.json`](../data/json/geruest.json) bzw.
|
||||
[`data/json/geruest_traeger.json`](../data/json/geruest_traeger.json) konfigurieren
|
||||
und einfuegen. Die Dialogdefinition wird **zur Laufzeit erzeugt**
|
||||
(`geruest-dcl-schreiben`, temporaere DCL-Datei) – es gibt keine feste
|
||||
`dcl/geruest.dcl`, weil je Anbauteil ein eigenes Mengenfeld gebraucht wird.
|
||||
und einfuegen. Das Dialog-Layout steht als **Vorlage** in `dcl/geruest.dcl` bzw.
|
||||
`dcl/geruest_traeger.dcl`; nur die datenabhaengigen Bloecke (Varianten-Radiobuttons,
|
||||
Mengenfeld je Anbauteil) werden zur Laufzeit an Markerzeilen `//@NAME@` eingesetzt
|
||||
(`ssg-dcl-vorlage-fuellen`, temporaere DCL-Datei).
|
||||
Ausfuehrliche Beschreibung (Konfigurationen, Attribut-Schema, Querstreben/Muffe,
|
||||
Traeger-Beschriftung): siehe `../CLAUDE.md` Abschnitt "AutoLISP-Module".
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
| --- | --- |
|
||||
| `c:GERUEST` | Dialog ohne Vorgabe-Bereich (Dropdown Rohrabhaenger/Saeulen/Wandbefestigung) |
|
||||
| `c:GERUEST_SAEULEN` / `c:GERUEST_ROHRABHAENGER` / `c:GERUEST_WANDBEFESTIGUNG` | Dialog mit vorgewaehltem Bereich (derselbe Dialog wie `GERUEST`) |
|
||||
| `c:GERUEST_SAEULEN` / `c:GERUEST_ROHRABHAENGER` / `c:GERUEST_WANDBEFESTIGUNG` | Je eigener Dialog fuer den Bereich (keine Umschaltung im Dialog) |
|
||||
| `c:GERUEST` | Ohne Bereich nur ein Hinweis (im Menue Platzhalter fuer den Gattertraeger) |
|
||||
| `c:GERUEST_TRAEGER` | Eigener fester Dialog (`dcl/geruest_traeger.dcl`): Rohr-Geruest-Traeger mit Linien-Logik (Start-/Endpunkt oder Laenge, Laengenabzuege, Querstreben/Muffe-Verteilung) |
|
||||
| `c:GERUEST_TRAEGER_BESCHRIFTEN` | Alle Traeger der Zeichnung neu beschriften (eigenes TEXT-Objekt, verknuepft per XDATA `SSG_GR_BESCHR`) |
|
||||
| `c:OMNI_FAHRSTRECKE` / `c:OMNI_FAHRSTRECKE_BESCHRIFTEN` | Omniflo-Fahrstrecke mit derselben Linien-Logik (Daten `omniflo_fahrstrecke.json`, Vorlage `dcl/fahrstrecke.dcl`) bzw. Neubeschriftung |
|
||||
|
||||
Block-Praefix `GR_<id>_<timestamp>` – **nicht kosmetisch**: `SSG_BLOCKEDIT` muss
|
||||
`GR_*` vor dem Omniflo-Zweig abfangen, da Geruest-Bloecke ebenfalls ein
|
||||
@@ -908,3 +909,59 @@ in assoziativen Arrays, MINSERT-Rastern und verschachtelten Bloecken. `LAGER_EXP
|
||||
ordnet jedes goh_rack zuerst ueber den Layer `LG_*_G<n>` seines obersten INSERTs
|
||||
(`lg-rk-top`), erst dann ueber die Geschosskontur zu. `LG_REGALE` zeigt die Zaehlung
|
||||
je Geschoss in der Befehlszeile.
|
||||
|
||||
---
|
||||
|
||||
### `Jam_Edit.lsp` – Staubereiche (SPS)
|
||||
|
||||
Staubereiche zeichnet sps_skel (`tro_annotate.py --anlage`) als Block `JAM_AREA`
|
||||
(Name `Jam<NNNN>_<k>`).
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
| --- | --- |
|
||||
| `c:JAM_EDIT` | Foerderer und laufende Nummer per Dialog (`dcl/jam_edit.dcl`) aendern; Knopf zurueck auf den abgeleiteten Wert, Warnung bei doppeltem Namen. Auch per Doppelklick (`SSG_BLOCKEDIT`, `JAM_*`) |
|
||||
|
||||
---
|
||||
|
||||
### `KettenFoerderer.lsp` – Kettenfoerderer/Schraegfoerderer Stahl
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
| --- | --- |
|
||||
| `c:KETTENFOERDERER` | Baut aus `KF_UM_<winkel>` -> `KF_LAENGE` -> `KF_AN_<winkel>` plus Draufsicht `KF_2D` einen Block `KF_<n>` (Dialog `dcl/kettenfoerderer.dcl`, Daten `data/json/kettenfoerderer.json`) |
|
||||
| `c:KF_EDIT` | `KF_n` bearbeiten und an derselben Stelle neu aufbauen (auch per Doppelklick) |
|
||||
| `c:KF_KS_PRUEFEN` | Diagnose (nicht im Menue) |
|
||||
|
||||
Details (aufgerichtete Geometrie, Attribut-Schema, Sivas-Export): `../CLAUDE.md`.
|
||||
|
||||
---
|
||||
|
||||
### Werkzeuge: `ssg_stueckliste.lsp`, `DinFormate.lsp`
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
| --- | --- |
|
||||
| `c:SSG_FAEHNCHEN_STUECKLISTE` | Positions-Faehnchen je Element und grob gruppierte Stuecklistentabelle, komplett aus der Zeichnung (kein Datei-Import) |
|
||||
| `c:DIN_FORMATE` | DIN-Rahmen A0-A4 und optional Schriftkopf (KOPF11, DE/EN/FR/IT) aus `cfg/rahmen/` einfuegen (Dialog `dcl/dinformate.dcl`) |
|
||||
|
||||
---
|
||||
|
||||
### Export-Hilfen: `count_sep_scan.lsp`, `check_hoehen.lsp`
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
| --- | --- |
|
||||
| `c:ZAEHLE_SEP_SCAN` | Scanner/Separatoren je Kreisel/VF/GF zaehlen und in `ANZAHL_SCANNER`/`ANZAHL_SEPARATOR` schreiben (laeuft auch vor jedem Export) |
|
||||
| `c:HOEHEN_CHECK` | Hoehen von Kreiseln/VF/GF messen, auf 0/negativ pruefen und in die Hoehen-Attribute schreiben |
|
||||
|
||||
---
|
||||
|
||||
### Entwickler-/Pflege-Module
|
||||
|
||||
| Datei | Befehle | Zweck |
|
||||
| --- | --- | --- |
|
||||
| `addattribute.lsp` | `ILS_ATTR_SYNC`, `ILS_ATTR_REPLACE` | ATTDEFs der Block-DWGs mit `data/ils/allocations.json` abgleichen |
|
||||
| `collect_attributes.lsp` | `ILS_ATTR_COLLECT` | ATTDEF-Werte aller DWGs nach `allocations_collected.json` schreiben |
|
||||
| `list_blocks.lsp` | `ILS_BLOCK_LIST` | Sub-Block-Definitionen aller DWGs auflisten (Kollisionen 2D/3D) |
|
||||
| `purge_blocks.lsp` | `ILS_BLOCK_PURGE` | Unbenutzte Bloecke/Layer in allen DWGs entfernen |
|
||||
| `ks_pruefung.lsp` | `KS_PRUEFEN` | KS_EIN/KS_AUS der 2D- gegen die 3D-Variante vergleichen (CSV) |
|
||||
| `menu-inventory.lsp` | `MenuInventory` | BricsCAD-Menuegruppen, Plugins, Startdateien auflisten |
|
||||
| `EtageVarioFoerderer.lsp` | - | Kompatibilitaets-Wrapper, laedt `vf_core.lsp` |
|
||||
| `tro_types.lsp` | - | Von `tro_annotate.py --emit-lisp` erzeugte TRO-Typliste |
|
||||
|
||||
@@ -226,6 +226,7 @@
|
||||
(if (car (atoms-family 1 '("SSG-ENSURE")))
|
||||
(progn (ssg-ensure "Gefaellestrecke") (ssg-ensure "VarioFoerderer")))
|
||||
(setq enames '() n-gf 0 n-vf 0 n-skip 0)
|
||||
(setq *vfl-konvert-fehler* nil) ; Fehlschlaege der Linienzug-Konvertierung
|
||||
(ssg-start "SSG_DIM_BATCH" '(("OSMODE") ("ATTREQ") ("ATTDIA")))
|
||||
(setvar "OSMODE" 0)
|
||||
;; Erst alle enames sammeln (entdel veraendert die Zeichnung waehrend der Iteration)
|
||||
@@ -247,12 +248,12 @@
|
||||
(if (gf-konvertiere-ent ent ziel-dim) (setq n-gf (1+ n-gf))))
|
||||
((wcmatch bname "VF_*")
|
||||
;; VF_-Bloecke nach Edit-Marker unterscheiden: Standard/Etage
|
||||
;; ueber vf-konvertiere-ent, Linienzug (Modus 1/2) ueber den
|
||||
;; ueber vf-konvertiere-ent, Linienzug (Modus 1/2/3) ueber den
|
||||
;; Journal-Replay-Konverter vfl-konvertiere-ent. Altbestand ohne
|
||||
;; bekannten Marker wird uebersprungen.
|
||||
(setq marker (car (vfs-xdata-lesen ent)))
|
||||
(cond
|
||||
((member marker '("linienzug" "linienzug2"))
|
||||
((member marker '("linienzug" "linienzug2" "linienzug3"))
|
||||
(if (vfl-konvertiere-ent ent ziel-dim) (setq n-vf (1+ n-vf))
|
||||
(setq n-skip (1+ n-skip))))
|
||||
((member marker '("standard" "etage"))
|
||||
@@ -264,6 +265,14 @@
|
||||
(ssg-end)
|
||||
(princ (ssg-textf "dim-batch-fertig"
|
||||
(list ziel-dim (itoa n-gf) (itoa n-vf) (itoa n-skip))))
|
||||
;; Fehlgeschlagene Linienzug-Bloecke gesammelt ausgeben (alter Block blieb
|
||||
;; jeweils unveraendert stehen, siehe vfl-konvertiere-ent)
|
||||
(if *vfl-konvert-fehler*
|
||||
(progn
|
||||
(princ (ssg-textf "dim-batch-fehlerliste"
|
||||
(list (itoa (length *vfl-konvert-fehler*)))))
|
||||
(foreach f *vfl-konvert-fehler*
|
||||
(princ (ssg-textf "dim-batch-fehler-zeile" (list (car f) (cdr f)))))))
|
||||
(princ)
|
||||
)
|
||||
|
||||
@@ -382,6 +391,23 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; Staubereiche (JAM_AREA) -> JAM_EDIT (DCL-Dialog)
|
||||
;; Ebenfalls aus der Beschriftung von sps_skel (tro_annotate.py --anlage);
|
||||
;; Foerderer und laufende Nummer des Staubereichs Jam<NNNN>_<k>.
|
||||
((wcmatch bname "JAM_*")
|
||||
(princ (ssg-textf "cmd-jam-bearbeiten" (list bname)))
|
||||
(if (and (null *ssg-Jam_Edit-loaded*) (atoms-family 1 '("SSG-ENSURE")))
|
||||
(ssg-ensure "Jam_Edit")
|
||||
)
|
||||
(if (atoms-family 1 '("C:JAM_EDIT"))
|
||||
(c:JAM_EDIT)
|
||||
(progn
|
||||
(princ (ssg-textf "tro-edit-modul-fehlt" (list "Jam_Edit.lsp")))
|
||||
(command "_.EATTEDIT")
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; TRO-Marker (TRO_SYM_<Typ>) -> TRO_EDIT (DCL-Dialog)
|
||||
;; Die Marker kommen aus sps_skel (lib/tro_annotate.py) und tragen die
|
||||
;; Attribute ID und TYPE. Modul bei Bedarf nachladen, damit der Doppelklick
|
||||
@@ -418,6 +444,24 @@
|
||||
(ssg-end)
|
||||
)
|
||||
|
||||
;; Kettenfoerderer (KF_n, KettenFoerderer.lsp) -> KF_EDIT (DCL-Dialog mit
|
||||
;; Neuaufbau an derselben Stelle). MUSS - aus demselben Grund wie GR_* -
|
||||
;; vor dem Omniflo-Zweig stehen: traegt die Baugruppe ein TEILEART-
|
||||
;; Attribut, wuerde dort sonst der Omniflo-Elementdialog aufgehen.
|
||||
((wcmatch bname "KF_*")
|
||||
(princ (ssg-textf "cmd-kettenfoerderer-bearbeiten" (list bname)))
|
||||
(if (and (null *ssg-KettenFoerderer-loaded*) (atoms-family 1 '("SSG-ENSURE")))
|
||||
(ssg-ensure "KettenFoerderer")
|
||||
)
|
||||
(if (atoms-family 1 '("C:KF_EDIT"))
|
||||
(c:KF_EDIT)
|
||||
(progn
|
||||
(princ (ssg-textf "tro-edit-modul-fehlt" (list "KettenFoerderer.lsp")))
|
||||
(command "_.EATTEDIT")
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; Omniflo-Bloecke -> OMNI_EDIT
|
||||
;; Erkennung: TEILEART-Attribut vorhanden, AP110-Blockname oder rein numerisch
|
||||
((progn
|
||||
|
||||
+315
-19
@@ -16,10 +16,12 @@
|
||||
;;; - ENTER -> Markierungskreis (Layer *ch-mark-layer*),
|
||||
;;; Block spaeter manuell anpassen.
|
||||
;;;
|
||||
;;; Phase 3 - Buehne: liegt die rohe Montagehoehe ueber
|
||||
;;; *ch-buehne-schwelle-m* (Default 2,0 m), wird pro Block gefragt,
|
||||
;;; ob eine Buehne vorhanden ist; deren Hoehe wird abgezogen
|
||||
;;; (MONTAGEHOEHE_m = roh - Buehne).
|
||||
;;; Phase 3 - Buehne nach Kreisel-Familien (siehe Abschnitt PHASE 3):
|
||||
;;; liegt eine Familie ueber *ch-buehne-schwelle-m* (Default 3,0 m), wird
|
||||
;;; EINMAL pro Familie gefragt; die Buehnenhoehe wird von den Kreiseln und
|
||||
;;; den zugehoerigen VF/GF abgezogen (MONTAGEHOEHE_m = roh - Buehne).
|
||||
;;; Bloecke, die keiner Familie zuzuordnen sind, werden wie frueher
|
||||
;;; einzeln gefragt (ch-write-montage).
|
||||
;;;
|
||||
;;; PHASE 1-3 bewusst OHNE: QSAVE (Testmodus, UNDO moeglich).
|
||||
;;;
|
||||
@@ -42,7 +44,19 @@
|
||||
;; Schwelle (m): ab dieser Montagehoehe wird pro Block nach einer
|
||||
;; Buehne gefragt (typische Anlagenhoehe ~2 m; darueber liegt die
|
||||
;; Anlage vermutlich auf einer Buehne).
|
||||
(if (null *ch-buehne-schwelle-m*) (setq *ch-buehne-schwelle-m* 2.0))
|
||||
(if (null *ch-buehne-schwelle-m*) (setq *ch-buehne-schwelle-m* 3.0))
|
||||
|
||||
;; Phase 3 (Familien): maximaler Hoehenunterschied zweier Kreisel-Familien (mm),
|
||||
;; zwischen denen eine Strecke denselben Buehnenabzug bekommt, und
|
||||
;; Zuordnungstoleranzen Strecken-Ende -> Kreisel (XY-Abstand zur Kreiselachse
|
||||
;; ueber den Radradius hinaus, Hoehenabweichung in mm).
|
||||
(if (null *ch-fam-max-hoehendiff-mm*) (setq *ch-fam-max-hoehendiff-mm* 1500.0))
|
||||
(if (null *ch-zuordnung-xy-mm*) (setq *ch-zuordnung-xy-mm* 300.0))
|
||||
(if (null *ch-zuordnung-z-mm*) (setq *ch-zuordnung-z-mm* 100.0))
|
||||
|
||||
;; Register der in Phase 1/2 geschriebenen Bloecke fuer Phase 3:
|
||||
;; je Block (ent art lbl roh pein paus erledigt).
|
||||
(setq *ch-rec* nil)
|
||||
|
||||
;;; ------------------------------------------------------------
|
||||
;;; vf_core-KS-Helfer sicherstellen (extract-ks-from-block-raw).
|
||||
@@ -127,12 +141,19 @@
|
||||
(if entry (caddr (car entry)) nil)
|
||||
)
|
||||
|
||||
;;; Ganzer KS-Ursprung (x y z) oder nil.
|
||||
(defun ch-ks-pt (ksdata ksname / entry)
|
||||
(setq entry (cadr (assoc ksname ksdata)))
|
||||
(if entry (car entry) nil)
|
||||
)
|
||||
|
||||
;;; ------------------------------------------------------------
|
||||
;;; KS_EIN.Z / KS_AUS.Z eines Composite-Blocks (VF_n/GF_n) messen.
|
||||
;;; Rueckgabe: (kez kaz) - fehlende Werte = nil.
|
||||
;;; Rueckgabe: (kez kaz pein paus) - fehlende Werte = nil. pein/paus sind
|
||||
;;; die ganzen KS-Ursprungspunkte (fuer die Kreisel-Zuordnung in Phase 3).
|
||||
;;; ------------------------------------------------------------
|
||||
(defun ch-measure-vfgf (ename / obj subs nm ksdata kez kaz)
|
||||
(setq kez nil kaz nil)
|
||||
(defun ch-measure-vfgf (ename / obj subs nm ksdata kez kaz pein paus)
|
||||
(setq kez nil kaz nil pein nil paus nil)
|
||||
(setq obj (vlax-ename->vla-object ename))
|
||||
(setq subs (vl-catch-all-apply 'vlax-invoke (list obj 'Explode)))
|
||||
(if (and (not (vl-catch-all-error-p subs)) subs)
|
||||
@@ -145,10 +166,12 @@
|
||||
(cond
|
||||
((and (null kez) (wcmatch nm *ch-as-pattern*))
|
||||
(setq ksdata (extract-ks-from-block-raw sub))
|
||||
(setq kez (ch-ks-z ksdata "KS_EIN")))
|
||||
(setq kez (ch-ks-z ksdata "KS_EIN")
|
||||
pein (ch-ks-pt ksdata "KS_EIN")))
|
||||
((and (null kaz) (wcmatch nm *ch-es-pattern*))
|
||||
(setq ksdata (extract-ks-from-block-raw sub))
|
||||
(setq kaz (ch-ks-z ksdata "KS_AUS")))
|
||||
(setq kaz (ch-ks-z ksdata "KS_AUS")
|
||||
paus (ch-ks-pt ksdata "KS_AUS")))
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -158,7 +181,7 @@
|
||||
(vl-catch-all-apply 'vla-Delete (list sub))))
|
||||
)
|
||||
)
|
||||
(list kez kaz)
|
||||
(list kez kaz pein paus)
|
||||
)
|
||||
|
||||
;;; ------------------------------------------------------------
|
||||
@@ -278,7 +301,275 @@
|
||||
)
|
||||
|
||||
;;; ============================================================
|
||||
;;; HAUPTBEFEHL (Phase 1 + 2)
|
||||
;;; PHASE 3 - Buehnen-Familien
|
||||
;;; ------------------------------------------------------------
|
||||
;;; Kreisel, die sich beruehren (Rad/Rad, Rad/Laufprofil, gleiche Hoehe -
|
||||
;;; KREISEL_WEICHEN-Kern kreisel-bp-*), haben zwingend dieselbe Hoehe und
|
||||
;;; bilden eine FAMILIE. Pro Familie ueber der Schwelle wird EINMAL nach
|
||||
;;; der Buehne gefragt; deren Hoehe wird von den Kreiseln der Familie und
|
||||
;;; von allen VF/GF abgezogen, deren beide Enden in dieser Familie liegen.
|
||||
;;; Strecken zwischen zwei Familien bekommen den Abzug nur bei gleicher
|
||||
;;; Buehnenhoehe UND hoechstens *ch-fam-max-hoehendiff-mm* Hoehenunterschied.
|
||||
;;; Geschrieben wird nur MONTAGEHOEHE_m (aus der Rohhoehe, also wiederholbar);
|
||||
;;; HOEHE/HOEHE_VON_mm bleiben, damit csv:hoehen-aktualisieren nichts zurueck-
|
||||
;;; setzt.
|
||||
;;; ============================================================
|
||||
|
||||
;;; Wurzel eines Knotens in der Eltern-Alist (Union-Find ohne Pfadkompression).
|
||||
(defun ch-fam-wurzel (rep k / p)
|
||||
(while (and (setq p (cdr (assoc k rep))) (/= p k))
|
||||
(setq k p))
|
||||
k
|
||||
)
|
||||
|
||||
;;; Familien aus Knoten und Kanten (reiner Kern).
|
||||
;;; knoten = ((schluessel idnum) ...), kanten = ((schluesselA schluesselB) ...)
|
||||
;;; Rueckgabe: Liste von Familien (je Liste von Schluesseln). Mitglieder und
|
||||
;;; Familien sind nach kleinster ID-Nummer geordnet (Gleichstand: Reihenfolge
|
||||
;;; in knoten); unbekannte Schluessel in kanten werden uebergangen.
|
||||
(defun ch-familien (knoten kanten / rep ra rb idx sortiert fams w)
|
||||
(foreach k knoten (setq rep (cons (cons (car k) (car k)) rep)))
|
||||
(foreach e kanten
|
||||
(if (and (assoc (car e) rep) (assoc (cadr e) rep))
|
||||
(progn
|
||||
(setq ra (ch-fam-wurzel rep (car e))
|
||||
rb (ch-fam-wurzel rep (cadr e)))
|
||||
(if (/= ra rb)
|
||||
(setq rep (subst (cons ra rb) (assoc ra rep) rep))))))
|
||||
(setq idx 0)
|
||||
(foreach k knoten
|
||||
(setq sortiert (cons (list (cadr k) (car k) idx) sortiert)
|
||||
idx (1+ idx)))
|
||||
(setq sortiert (vl-sort sortiert 'ch-id<))
|
||||
(foreach s sortiert
|
||||
(setq w (ch-fam-wurzel rep (cadr s)))
|
||||
(if (assoc w fams)
|
||||
(setq fams (subst (append (assoc w fams) (list (cadr s))) (assoc w fams) fams))
|
||||
(setq fams (append fams (list (list w (cadr s)))))))
|
||||
(mapcar 'cdr fams)
|
||||
)
|
||||
|
||||
;;; Abzugsregel fuer eine Strecke zwischen zwei VERSCHIEDENEN Familien
|
||||
;;; (reiner Kern). b1/b2 = Buehnenhoehe der Familien in m (0 = keine),
|
||||
;;; z1/z2 = Familienhoehen in mm, maxdiff = erlaubter Unterschied in mm.
|
||||
;;; Rueckgabe (status . abzug_m): "kein" (beide ohne Buehne), "konflikt"
|
||||
;;; (verschiedene Buehnenhoehen), "hoehe" (Familien zu weit auseinander),
|
||||
;;; "abzug" (gleiche Buehne, abzug_m = b1).
|
||||
(defun ch-kreuz-abzug (b1 b2 z1 z2 maxdiff)
|
||||
(cond
|
||||
((and (equal b1 0.0 1e-6) (equal b2 0.0 1e-6)) (cons "kein" 0.0))
|
||||
((not (equal b1 b2 1e-6)) (cons "konflikt" 0.0))
|
||||
((> (abs (- z1 z2)) maxdiff) (cons "hoehe" 0.0))
|
||||
(t (cons "abzug" b1))
|
||||
)
|
||||
)
|
||||
|
||||
;;; Montagehoehe nach Buehnenabzug (reiner Kern). nil, wenn kein gueltiger
|
||||
;;; Abzug moeglich ist (b <= 0 oder b >= roh).
|
||||
(defun ch-abzug-anwenden (roh b)
|
||||
(if (and (> b 0.0) (< b roh)) (- roh b))
|
||||
)
|
||||
|
||||
;;; XY-Abstand eines Punktes von der Strecke a-b (reiner Kern).
|
||||
(defun ch-pkt-strecke-abstand (pt a b / lot tt)
|
||||
(setq lot (kreisel-bp-lot pt a b)
|
||||
tt (max 0.0 (min 1.0 (car lot))))
|
||||
(kreisel-bp-abst pt (kreisel-bp-plus a (kreisel-bp-mal (kreisel-bp-minus b a) tt)))
|
||||
)
|
||||
|
||||
;;; Naechster Kreisel/Eckrad zu einem Strecken-Endpunkt (reiner Kern).
|
||||
;;; pt = (x y [z]), z = Hoehe in mm, elemente = kreisel-bp-element-Records.
|
||||
;;; Treffer: XY-Abstand zur Achse <= Radradius + tolxy und |z - Kreiselhoehe|
|
||||
;;; <= tolz. Rueckgabe: Handle des naechsten Treffers oder nil.
|
||||
(defun ch-kreisel-finden (pt z elemente tolxy tolz / best bd d ac)
|
||||
(foreach e elemente
|
||||
(if (<= (abs (- z (kreisel-bp-get "z" e))) tolz)
|
||||
(progn
|
||||
(setq ac (kreisel-bp-get "achse" e)
|
||||
d (ch-pkt-strecke-abstand pt (car ac) (cadr ac)))
|
||||
(if (and (<= d (+ (kreisel-bp-get "r" e) tolxy))
|
||||
(or (null bd) (< d bd)))
|
||||
(setq bd d best (kreisel-bp-get "handle" e))))))
|
||||
best
|
||||
)
|
||||
|
||||
;;; Abzugsregel fuer eine Strecke aus den Familiensaetzen ihrer beiden Enden
|
||||
;;; (reiner Kern). fs/fe = (idx handles z b). Gleiche Familie -> ("innen" . b),
|
||||
;;; sonst Ergebnis von ch-kreuz-abzug.
|
||||
(defun ch-strecke-abzug (fs fe maxdiff)
|
||||
(if (= (car fs) (car fe))
|
||||
(cons "innen" (cadddr fs))
|
||||
(ch-kreuz-abzug (cadddr fs) (cadddr fe) (caddr fs) (caddr fe) maxdiff))
|
||||
)
|
||||
;;; Flache Schleife (reiner Kern): Strecke startet und endet am SELBEN Kreisel
|
||||
;;; (h1 = h2) und hat gleiche Anfangs-/Endhoehe (|z1 - z2| <= tol, mm). Ihre
|
||||
;;; Buehne laesst sich nicht aus der Familie ableiten und wird einzeln gefragt.
|
||||
(defun ch-schleife-p (h1 h2 z1 z2 tol)
|
||||
(and h1 h2 (= h1 h2) (<= (abs (- z1 z2)) tol))
|
||||
)
|
||||
|
||||
;;; ID-Nummer eines Elements (999999 ohne gueltige ID).
|
||||
(defun ch-id-nummer (id)
|
||||
(if (and id (/= id "") (> (atoi id) 0)) (atoi id) 999999)
|
||||
)
|
||||
|
||||
;;; Element-Record zu einem Handle.
|
||||
(defun ch-elem-zu-handle (h elemente / res)
|
||||
(foreach e elemente
|
||||
(if (and (null res) (= (kreisel-bp-get "handle" e) h)) (setq res e)))
|
||||
res
|
||||
)
|
||||
|
||||
;;; Kreisel-Modul (kreisel-bp-*) sicherstellen.
|
||||
(defun ch-ensure-kreisel ()
|
||||
(if (null (car (atoms-family 1 '("KREISEL-BP-BERECHNEN"))))
|
||||
(if (car (atoms-family 1 '("SSG-ENSURE")))
|
||||
(vl-catch-all-apply '(lambda () (ssg-ensure "KreiselInsert")))))
|
||||
(if (car (atoms-family 1 '("KREISEL-BP-BERECHNEN"))) t nil)
|
||||
)
|
||||
|
||||
;;; Montage-Rohwert schreiben (ohne Rueckfrage) und fuer Phase 3 vormerken.
|
||||
;;; pts = (pein paus) bei VF/GF, sonst nil. Rueckgabe: roh.
|
||||
(defun ch-montage-roh (ent art raw lbl pts)
|
||||
(ch-set-att ent "MONTAGEHOEHE_m" (rtos raw 2 3))
|
||||
(setq *ch-rec* (append *ch-rec*
|
||||
(list (list ent art lbl raw (car pts) (cadr pts)))))
|
||||
raw
|
||||
)
|
||||
|
||||
;;; Familie hervorheben (mode 3) bzw. zuruecknehmen (mode 4).
|
||||
(defun ch-fam-hervorheben (handles mode / e)
|
||||
(foreach h handles
|
||||
(if (setq e (handent h)) (redraw e mode)))
|
||||
)
|
||||
|
||||
;;; Buehnenhoehe (m) fuer eine Familie erfragen. nil = keine Buehne.
|
||||
;;; z = Familienhoehe in mm, prev = zuletzt eingegebene Buehne (Vorgabe) oder nil.
|
||||
(defun ch-frage-buehne (txt z prev / b ok)
|
||||
(if (ssg-in-yesno txt nil)
|
||||
(progn
|
||||
(while (not ok)
|
||||
(setq b (ssg-in-real (ssg-text "chh-buehne-hoehe") prev))
|
||||
(cond
|
||||
((null b) (setq ok T))
|
||||
((and (> b 0.0) (< b (/ z 1000.0))) (setq ok T))
|
||||
(t (princ (ssg-textf "chh-buehne-ungueltig" (list (rtos (/ z 1000.0) 2 3))))
|
||||
(setq b nil))))
|
||||
b))
|
||||
)
|
||||
|
||||
;;; Phase 3 ausfuehren: arbeitet das Register *ch-rec* ab. Bloecke ohne
|
||||
;;; Familie (Zuordnung unklar) fragen wie zuvor einzeln nach.
|
||||
(defun ch-phase3 ( / elems ber knoten kanten fams famdat h2f n-fam n-bue
|
||||
rep z b prev rec idx fs fe kr neu lbl h
|
||||
n-kr n-innen n-kreuz n-konf n-offen ents)
|
||||
(setq n-kr 0 n-innen 0 n-kreuz 0 n-konf 0 n-offen 0 n-fam 0 n-bue 0
|
||||
ents nil)
|
||||
(princ (ssg-text "chh-start"))
|
||||
(if (ch-ensure-kreisel)
|
||||
(progn
|
||||
(setq elems (kreisel-bp-elemente-sammeln)
|
||||
ber (car (kreisel-bp-berechnen elems (kreisel-bp-toleranz)
|
||||
(kreisel-bp-toleranz-z))))
|
||||
(setq knoten (mapcar '(lambda (el) (list (kreisel-bp-get "handle" el)
|
||||
(ch-id-nummer (kreisel-bp-get "id" el))))
|
||||
elems)
|
||||
kanten (mapcar '(lambda (tr) (list (kreisel-bp-get "handle" (kreisel-bp-get "a" tr))
|
||||
(kreisel-bp-get "handle" (kreisel-bp-get "b" tr))))
|
||||
ber))
|
||||
(setq fams (ch-familien knoten kanten))
|
||||
|
||||
;; --- je Familie einmal fragen ---
|
||||
(setq idx 0)
|
||||
(foreach fam fams
|
||||
(setq idx (1+ idx) n-fam (1+ n-fam)
|
||||
rep (ch-elem-zu-handle (car fam) elems)
|
||||
z (kreisel-bp-get "z" rep)
|
||||
b 0.0)
|
||||
(if (> (/ z 1000.0) *ch-buehne-schwelle-m*)
|
||||
(progn
|
||||
(ch-fam-hervorheben fam 3)
|
||||
(setq b (ch-frage-buehne
|
||||
(ssg-textf "chh-fam-frage"
|
||||
(list (itoa idx) (kreisel-bp-elem-text rep)
|
||||
(itoa (length fam)) (rtos (/ z 1000.0) 2 3)))
|
||||
z prev))
|
||||
(ch-fam-hervorheben fam 4)
|
||||
(if (null b) (setq b 0.0))
|
||||
(if (> b 0.0) (setq prev b n-bue (1+ n-bue)))))
|
||||
(setq famdat (cons (list idx fam z b) famdat))
|
||||
(foreach h fam (setq h2f (cons (cons h idx) h2f))))
|
||||
(setq famdat (reverse famdat))
|
||||
|
||||
;; --- Kreisel schreiben ---
|
||||
(foreach rec *ch-rec*
|
||||
(if (= (cadr rec) "KREISEL")
|
||||
(progn
|
||||
(setq h (cdr (assoc 5 (entget (car rec))))
|
||||
fs (cdr (assoc h h2f)))
|
||||
(if fs
|
||||
(progn
|
||||
(setq b (cadddr (assoc fs famdat)))
|
||||
(if (> b 0.0)
|
||||
(if (setq neu (ch-abzug-anwenden (nth 3 rec) b))
|
||||
(progn (ch-set-att (car rec) "MONTAGEHOEHE_m" (rtos neu 2 3))
|
||||
(setq n-kr (1+ n-kr)))))
|
||||
(setq ents (cons (car rec) ents)))))))
|
||||
|
||||
;; --- Strecken zuordnen ---
|
||||
(foreach rec *ch-rec*
|
||||
(if (and (member (cadr rec) '("VF" "GF")) (nth 4 rec) (nth 5 rec))
|
||||
(progn
|
||||
(setq lbl (nth 2 rec)
|
||||
fs (ch-kreisel-finden (nth 4 rec) (caddr (nth 4 rec)) elems
|
||||
*ch-zuordnung-xy-mm* *ch-zuordnung-z-mm*)
|
||||
fe (ch-kreisel-finden (nth 5 rec) (caddr (nth 5 rec)) elems
|
||||
*ch-zuordnung-xy-mm* *ch-zuordnung-z-mm*))
|
||||
(if (and fs fe)
|
||||
(if (ch-schleife-p fs fe (caddr (nth 4 rec)) (caddr (nth 5 rec)) 1.0)
|
||||
;; Flache Schleife am selben Kreisel: Buehne nicht ableitbar ->
|
||||
;; bleibt unentschieden und wird im Rest einzeln gefragt
|
||||
(princ (ssg-textf "chh-schleife" (list lbl)))
|
||||
(progn
|
||||
(setq fs (assoc (cdr (assoc fs h2f)) famdat)
|
||||
fe (assoc (cdr (assoc fe h2f)) famdat)
|
||||
kr (ch-strecke-abzug fs fe *ch-fam-max-hoehendiff-mm*))
|
||||
(setq ents (cons (car rec) ents))
|
||||
(cond
|
||||
((= (car kr) "konflikt")
|
||||
(setq n-konf (1+ n-konf))
|
||||
(princ (ssg-textf "chh-kreuz-konflikt"
|
||||
(list lbl (rtos (cadddr fs) 2 3) (rtos (cadddr fe) 2 3)))))
|
||||
((= (car kr) "hoehe")
|
||||
(setq n-konf (1+ n-konf))
|
||||
(princ (ssg-textf "chh-kreuz-hoehe"
|
||||
(list lbl (rtos (abs (- (caddr fs) (caddr fe))) 2 0)
|
||||
(rtos *ch-fam-max-hoehendiff-mm* 2 0)))))
|
||||
((> (cdr kr) 0.0)
|
||||
(if (setq neu (ch-abzug-anwenden (nth 3 rec) (cdr kr)))
|
||||
(progn
|
||||
(ch-set-att (car rec) "MONTAGEHOEHE_m" (rtos neu 2 3))
|
||||
(if (= (car kr) "innen")
|
||||
(setq n-innen (1+ n-innen))
|
||||
(setq n-kreuz (1+ n-kreuz))))
|
||||
(princ (ssg-textf "chh-strecke-neg"
|
||||
(list lbl (rtos (cdr kr) 2 3) (rtos (nth 3 rec) 2 3))))))
|
||||
))))))))
|
||||
(princ (ssg-text "chh-kein-kreisel")))
|
||||
|
||||
;; --- Rest: blockweise wie bisher ---
|
||||
(foreach rec *ch-rec*
|
||||
(if (not (member (car rec) ents))
|
||||
(progn
|
||||
(setq n-offen (1+ n-offen))
|
||||
(ch-write-montage (car rec) (nth 3 rec) (nth 2 rec)))))
|
||||
(princ (ssg-textf "chh-summe"
|
||||
(list (itoa n-fam) (itoa n-bue) (itoa n-kr) (itoa n-innen)
|
||||
(itoa n-kreuz) (itoa n-konf) (itoa n-offen))))
|
||||
)
|
||||
|
||||
;;; ============================================================
|
||||
;;; HAUPTBEFEHL (Phase 1 + 2, danach Phase 3)
|
||||
;;; ============================================================
|
||||
(defun c:HOEHEN_CHECK ( / ss i idx id items it ent ed nm lbl zc meas kez kaz
|
||||
montage inp delta mss
|
||||
@@ -292,6 +583,7 @@
|
||||
)
|
||||
)
|
||||
(setq n-kreisel 0 n-vf 0 n-gf 0 n-fixed 0 n-marked 0 n-fehler 0)
|
||||
(setq *ch-rec* nil)
|
||||
|
||||
;; Alte Markierungskreise entfernen (Idempotenz)
|
||||
(setq mss (ssget "_X" (list (cons 0 "CIRCLE") (cons 8 *ch-mark-layer*))))
|
||||
@@ -348,7 +640,7 @@
|
||||
(ch-move-z ent (- inp zc))
|
||||
(setq zc inp)
|
||||
(ch-set-att ent "HOEHE" (rtos zc 2 0))
|
||||
(setq montage (ch-write-montage ent (/ zc 1000.0) lbl))
|
||||
(setq montage (ch-montage-roh ent "KREISEL" (/ zc 1000.0) lbl nil))
|
||||
(setq n-fixed (1+ n-fixed))
|
||||
(princ (strcat "\n -> verschoben & gesetzt: HOEHE=" (rtos zc 2 0)
|
||||
" -> MONTAGEHOEHE_m=" (rtos montage 2 3))))
|
||||
@@ -362,7 +654,7 @@
|
||||
;; --- gueltig ---
|
||||
(progn
|
||||
(ch-set-att ent "HOEHE" (rtos zc 2 0))
|
||||
(setq montage (ch-write-montage ent (/ zc 1000.0) lbl))
|
||||
(setq montage (ch-montage-roh ent "KREISEL" (/ zc 1000.0) lbl nil))
|
||||
(princ (strcat "\n " lbl ": HOEHE=" (rtos zc 2 0)
|
||||
" -> MONTAGEHOEHE_m=" (rtos montage 2 3))))
|
||||
)
|
||||
@@ -399,10 +691,11 @@
|
||||
(progn
|
||||
(ch-set-att ent "HOEHE_VON_mm" (rtos kez 2 0))
|
||||
(ch-set-att ent "HOEHE_BIS_mm" (rtos kaz 2 0))
|
||||
(setq montage (ch-write-montage ent
|
||||
(setq montage (ch-montage-roh ent
|
||||
(if (wcmatch nm "GF_*") "GF" "VF")
|
||||
(if (wcmatch nm "GF_*")
|
||||
(/ kez 1000.0)
|
||||
(/ (+ kez kaz) 2000.0)) lbl))
|
||||
(/ (+ kez kaz) 2000.0)) lbl (cddr meas)))
|
||||
(setq n-fixed (1+ n-fixed))
|
||||
(princ (strcat "\n -> verschoben & gesetzt: VON=" (rtos kez 2 0)
|
||||
", BIS=" (rtos kaz 2 0)
|
||||
@@ -420,10 +713,11 @@
|
||||
(t
|
||||
(ch-set-att ent "HOEHE_VON_mm" (rtos kez 2 0))
|
||||
(ch-set-att ent "HOEHE_BIS_mm" (rtos kaz 2 0))
|
||||
(setq montage (ch-write-montage ent
|
||||
(setq montage (ch-montage-roh ent
|
||||
(if (wcmatch nm "GF_*") "GF" "VF")
|
||||
(if (wcmatch nm "GF_*")
|
||||
(/ kez 1000.0)
|
||||
(/ (+ kez kaz) 2000.0)) lbl))
|
||||
(/ (+ kez kaz) 2000.0)) lbl (cddr meas)))
|
||||
(princ (strcat "\n " lbl ": HOEHE_VON_mm=" (rtos kez 2 0)
|
||||
", HOEHE_BIS_mm=" (rtos kaz 2 0)
|
||||
" -> MONTAGEHOEHE_m=" (rtos montage 2 3))))
|
||||
@@ -431,6 +725,8 @@
|
||||
)
|
||||
)
|
||||
)
|
||||
;; Phase 3: Buehnen-Familien (arbeitet das Register *ch-rec* ab)
|
||||
(ch-phase3)
|
||||
(princ (strcat "\n--------------------------------------------"
|
||||
"\n Kreisel: " (itoa n-kreisel)
|
||||
" VF: " (itoa n-vf)
|
||||
@@ -449,4 +745,4 @@
|
||||
)
|
||||
|
||||
(princ "\n>>> check_hoehen.lsp geladen (Phase 1-3). Befehl: HOEHEN_CHECK")
|
||||
(princ)
|
||||
(princ)
|
||||
@@ -2397,6 +2397,11 @@
|
||||
;; VB_*/TV_* = Omniflo-Verbinder (siehe pattern_verbinder in
|
||||
;; cfg/export.cfg, OMNI_TV_* in OmniModulInsert.lsp). export_sivas.py
|
||||
;; fuehrt sie ueber TEILEART/ARTINR im allgemeinen Omniflo-Zweig.
|
||||
;; KF_* = Kettenfoerderer/Schraegfoerderer Stahl (siehe
|
||||
;; pattern_kettenfoerderer in cfg/export.cfg, KettenFoerderer.lsp). Wie
|
||||
;; GR_* eine selbst zusammengebaute Baugruppe mit eigenen Attributen
|
||||
;; (TEILEART/ARTINR), darum eigenstaendig gesammelt - die drei Bausteine
|
||||
;; darin werden NICHT einzeln gezaehlt.
|
||||
;; Bloecke auf GEFRORENEN Layern (und die Hilfsobjekte gefrorener VF_n/GF_n)
|
||||
;; werden ausgelassen, solange *csv-gefrorene-ausschliessen* an ist (Standard,
|
||||
;; Dialog CSV_EXPORT_KONFIG); ausgeschaltete Layer zaehlen nicht als gefroren.
|
||||
@@ -2449,6 +2454,7 @@
|
||||
(wcmatch bname (export:pattern "pattern_ausgang" "Ausgang*"))
|
||||
(wcmatch bname (export:pattern "pattern_geruest" "GR_*"))
|
||||
(wcmatch bname (export:pattern "pattern_verbinder" "VB_*,TV_*"))
|
||||
(wcmatch bname (export:pattern "pattern_kettenfoerderer" "KF_*"))
|
||||
(wcmatch bname (export:pattern "pattern_unit_marker" "ZZ_UNIT_MARKER*"))
|
||||
;; Rein numerische Namen = Omniflo SivasNr (Boegen/Weichen)
|
||||
;; Rein LISP-intern (Python klassifiziert Omniflo stattdessen
|
||||
@@ -2915,8 +2921,48 @@
|
||||
)
|
||||
|
||||
|
||||
;; Vor dem Sivas-Export anbieten, den Hoehen-Check (HOEHEN_CHECK, check_hoehen.lsp)
|
||||
;; auszufuehren: Er setzt die Montagehoehen inkl. Buehnenabzug, den der Export
|
||||
;; selbst nicht kennt. Bewusst eine Rueckfrage (Vorgabe Ja, Enter startet den
|
||||
;; Check, "Nein" ueberspringt ihn) statt automatisch: der Check stellt Fragen
|
||||
;; und wuerde Hand-Korrekturen von MONTAGEHOEHE_m bei jedem Export ueberschreiben. Entfaellt ohne GUI und bei abgeschaltetem
|
||||
;; Schalter *csv-hoehencheck-fragen* (automatische Tests).
|
||||
(if (null *csv-hoehencheck-fragen*) (setq *csv-hoehencheck-fragen* T))
|
||||
|
||||
(defun csv:hoehencheck-anbieten ()
|
||||
(if (and *csv-hoehencheck-fragen*
|
||||
(ssg-gui-p)
|
||||
(car (atoms-family 1 '("SSG-IN-YESNO")))
|
||||
(ssg-in-yesno (ssg-text "exp-hoehencheck-frage") T))
|
||||
(progn
|
||||
(ssg-ensure "check_hoehen")
|
||||
(if (car (atoms-family 1 '("C:HOEHEN_CHECK")))
|
||||
(c:HOEHEN_CHECK)
|
||||
(princ (ssg-text "exp-hoehencheck-fehlt")))))
|
||||
)
|
||||
|
||||
;; Vor dem Sivas-Export die Zeichnung bereinigen (BricsCAD-Befehl BEREINIG /
|
||||
;; PURGE): entfernt unbenutzte Bloecke, Layer, Linientypen usw. samt
|
||||
;; verschachtelter Elemente. Sprachunabhaengig ueber -PURGE mit "_All".
|
||||
;; Schalter *csv-bereinigen-vor-export* (Standard an; Tests schalten ab, da
|
||||
;; die Zeichnung veraendert wird).
|
||||
(if (null *csv-bereinigen-vor-export*) (setq *csv-bereinigen-vor-export* 'an))
|
||||
|
||||
(defun csv:bereinigen ()
|
||||
(if (and (eq *csv-bereinigen-vor-export* 'an) (ssg-gui-p))
|
||||
(progn
|
||||
(princ (ssg-text "exp-bereinigen"))
|
||||
;; Zweimal, weil das Entfernen eines Blocks dessen Layer/Linientypen
|
||||
;; erst frei macht (zusaetzlich zur Nested-Option)
|
||||
(repeat 2
|
||||
(vl-catch-all-apply
|
||||
'(lambda () (command "_.-PURGE" "_All" "*" "_No"))))
|
||||
(princ))))
|
||||
|
||||
;; --- EXPORTSIVAS: Sivas-spezifischer CSV-Export mit Summierungszeilen ---
|
||||
(defun c:EXPORTSIVAS ()
|
||||
(csv:bereinigen)
|
||||
(csv:hoehencheck-anbieten)
|
||||
(csv:run-export "EXPORTSIVAS"
|
||||
(export:filename "sivas_script")
|
||||
(export:filename "sivas_csv")
|
||||
|
||||
@@ -1264,6 +1264,13 @@
|
||||
("L_VF_m" "0.000")
|
||||
("ANTRIEBFAHRTRICHTUNG" "Auf")
|
||||
("VF_WINKEL" "0")
|
||||
;; Hoehe je VF-SEGMENT in Metern (3 Nachkommastellen), kommagetrennt und
|
||||
;; Eintrag fuer Eintrag parallel zu L_VF_m/VF_WINKEL: Mittelwert aus KS_EIN
|
||||
;; und KS_AUS des jeweiligen geraden VF-Abschnitts (vf-vfhoehe-segment in
|
||||
;; vf_core.lsp, erfasst in vfs-vf-koerper). Zwischen Umlenk- und
|
||||
;; Motorstation koennen mehrere Abschnitte liegen (auf/ab/horizontal).
|
||||
;; Sivas-Merkmale 4433-4437 (bis zu fuenf Abschnitte je Gruppe).
|
||||
("VF_HOEHE_m" "0.000")
|
||||
("VF_Bogen_A_90" "0")
|
||||
("VF_Bogen_A_60" "0")
|
||||
("VF_Bogen_A_30" "0")
|
||||
|
||||
+13
-1
@@ -86,8 +86,20 @@
|
||||
;; Einheiten-Proxies selbst ab; Separator-/Element-
|
||||
;; Kopien sammeln sich dagegen an - Zeichnung mit
|
||||
;; eingeschaltetem Schalter nicht speichern.
|
||||
;; kf-zeit - Zwischenzeiten beim Aufruf von KETTENFOERDERER
|
||||
;; (Daten lesen / Dialogaufbau), siehe kf-zeit in
|
||||
;; KettenFoerderer.lsp. Standard 0 - nur einschalten,
|
||||
;; wenn der Dialog spuerbar verzoegert erscheint.
|
||||
;; testlauf - Laufprotokoll je Test von SSG_RUN_ALL_TESTS nach
|
||||
;; DXFM_LOG/testlauf_<name>.dbg (eigene Datei, nicht
|
||||
;; ueber *dbg-path*; jede Zeile sofort geschrieben,
|
||||
;; damit bei einem haengenden Test der letzte Schritt
|
||||
;; sichtbar ist). Standard 1 - kostet nur ein paar
|
||||
;; Zeilen je Test, siehe testrun:log in
|
||||
;; tests/test_run_all.lsp.
|
||||
;; ------------------------------------------------------------
|
||||
(foreach nm '(("vf-sepliste" . 1) ("csv_leave_proxies" . 0))
|
||||
(foreach nm '(("vf-sepliste" . 1) ("csv_leave_proxies" . 0) ("kf-zeit" . 0)
|
||||
("testlauf" . 1))
|
||||
(if (not (assoc (car nm) *dbg-schalter*))
|
||||
(setq *dbg-schalter* (cons nm *dbg-schalter*))))
|
||||
|
||||
|
||||
@@ -47,6 +47,9 @@
|
||||
;; das ID-ATTDEF steht seit *geruest-attrib-defs* zur Verfuegung.
|
||||
;; VB_*/TV_* (Omniflo-Verbinder, siehe pattern_verbinder in
|
||||
;; cfg/export.cfg) ebenso - fest im Code wie GR_*.
|
||||
;; KF_* (Kettenfoerderer, siehe pattern_kettenfoerderer in cfg/export.cfg,
|
||||
;; KettenFoerderer.lsp) ebenso - das ID-ATTDEF kommt aus kf-attrib-defs, das
|
||||
;; auf dem gemeinsamen Strecken-Schema aufsetzt und darum ID bereits fuehrt.
|
||||
;; Gefaellebogen_* (siehe pattern_nested_bogen in cfg/export.cfg): einer der
|
||||
;; Bausteine einer GF-Kette, verpackt in VF_n/GF_n; wird beim Export ebenso
|
||||
;; als temporaere Kopie ausgepackt wie die uebrigen Vario_*/Staustrecke_*-
|
||||
@@ -84,6 +87,7 @@
|
||||
(wcmatch bname "Eingang*,Ausgang*")
|
||||
(wcmatch bname "GR_*")
|
||||
(wcmatch bname "VB_*,TV_*")
|
||||
(wcmatch bname "KF_*")
|
||||
(wcmatch bname "#*")
|
||||
)
|
||||
(ssadd ename ss-out)
|
||||
|
||||
+283
-4
@@ -72,11 +72,31 @@
|
||||
;; Block unter seinem effektiven, dim-suffigierten Namen und GIBT DIESEN ZURUECK,
|
||||
;; damit Aufrufer ihn zum Einfuegen (vla-InsertBlock/tblsearch) verwenden.
|
||||
;; Meldung nur bei Fehlschlag.
|
||||
(defun ensure-block-loaded (blockname / )
|
||||
(if (not (ssg-ils-block-laden blockname))
|
||||
(princ (ssg-textf "vfc-fehler-block-datei-fehlt" (list blockname)))
|
||||
;; Sonderfall Bloecke OHNE Dimensionssuffix (data/omniflo/<Dim>/, z.B. die
|
||||
;; Kettenfoerderer-Bausteine): ssg-ils-blockname wuerde "KF_UM_26" zu
|
||||
;; "KF_UM_26_2D" machen - das ist die Konvention der FLACHEN Ablage data/ils,
|
||||
;; die Omniflo-Ordner arbeiten stattdessen mit getrennten Verzeichnissen und
|
||||
;; unsuffigierten Namen. Liegt die Definition unter dem Rohnamen bereits in
|
||||
;; der Zeichnung und gibt es KEINE suffigierte Variante, wird der Rohname
|
||||
;; unveraendert verwendet. Die Bedingung ist bewusst eng gefasst (BEIDE Teile
|
||||
;; muessen zutreffen), damit die Dim-Aufloesung fuer alle data/ils-Bloecke
|
||||
;; unberuehrt bleibt: dort existiert die suffigierte Variante, sobald der
|
||||
;; Block geladen ist, und der erste Zweig greift nie.
|
||||
;; Realer Fehler, den das behebt: die KS-Messung eines KF-Bausteins lief ins
|
||||
;; Leere und meldete "KS_EIN/KS_AUS fehlt", obwohl beide KS im Block vorhanden
|
||||
;; waren - gesucht wurde nur ein Blockname, den es nicht gibt.
|
||||
(defun ensure-block-loaded (blockname / eff)
|
||||
(setq eff (ssg-ils-blockname blockname))
|
||||
(if (and (not (tblsearch "BLOCK" eff))
|
||||
(tblsearch "BLOCK" blockname))
|
||||
blockname
|
||||
(progn
|
||||
(if (not (ssg-ils-block-laden blockname))
|
||||
(princ (ssg-textf "vfc-fehler-block-datei-fehlt" (list blockname)))
|
||||
)
|
||||
eff
|
||||
)
|
||||
)
|
||||
(ssg-ils-blockname blockname)
|
||||
)
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
@@ -379,6 +399,265 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; KS-ORIENTIERUNG + SKALIERTE KS-EINFUEGUNG
|
||||
;; ------------------------------------------------------------
|
||||
;; Ergaenzt fuer den Kettenfoerderer (KettenFoerderer.lsp): dort ist die
|
||||
;; Neigung KEIN freier Parameter, sondern steckt fest in der Geometrie der
|
||||
;; Blockvarianten (KF_UM_26 gegen KF_UM_30). Der Einbauwinkel eines
|
||||
;; Folgebausteins ergibt sich darum aus der RICHTUNG des KS_AUS seines
|
||||
;; Vorgaengers. Dafuer reicht der bisher allein ausgewertete KS-URSPRUNG
|
||||
;; nicht - die X-Achse des KS muss mit gelesen werden. extract-ks-from-block
|
||||
;; liefert sie als (origin x-end y-end z-end) bereits mit, sie wurde bislang
|
||||
;; nur von keinem Aufrufer genutzt.
|
||||
|
||||
;; Winkel der X-Achse eines KS-Eintrags in der XY-Ebene, in Grad (-180..180).
|
||||
;; ks-eintrag = (origin x-end y-end z-end), also genau der cadr-Teil eines
|
||||
;; extract-ks-from-block-Ergebnisses. Rueckgabe nil, wenn die X-Achse keine
|
||||
;; XY-Laenge hat (senkrecht stehendes KS) oder der Eintrag unbrauchbar ist.
|
||||
(defun ks-xy-winkel (ks-eintrag / org xend dx dy)
|
||||
(if (and ks-eintrag (listp ks-eintrag) (>= (length ks-eintrag) 2)
|
||||
(listp (car ks-eintrag)) (listp (cadr ks-eintrag)))
|
||||
(progn
|
||||
(setq org (car ks-eintrag) xend (cadr ks-eintrag))
|
||||
(setq dx (- (car xend) (car org))
|
||||
dy (- (cadr xend) (cadr org)))
|
||||
(if (< (+ (* dx dx) (* dy dy)) 1e-12)
|
||||
nil
|
||||
(/ (* 180.0 (atan dy dx)) pi)))
|
||||
nil))
|
||||
|
||||
;; Winkel auf -180..180 Grad normalisieren. Reiner Rechenkern.
|
||||
(defun ks-winkel-normalisieren (w)
|
||||
(if (null w)
|
||||
nil
|
||||
(progn
|
||||
(setq w (float w))
|
||||
(while (> w 180.0) (setq w (- w 360.0)))
|
||||
(while (<= w -180.0) (setq w (+ w 360.0)))
|
||||
w)))
|
||||
|
||||
;; Lokalen KS_AUS-KS_EIN-Versatz eines Blocks als (dx dy dz) liefern.
|
||||
;; ks-data = Ergebnis von extract-ks-from-block/ks-block-messen.
|
||||
;; Rueckgabe nil, wenn eines der beiden KS fehlt.
|
||||
(defun ks-versatz (ks-data / ein aus)
|
||||
(setq ein (cadr (assoc "KS_EIN" ks-data))
|
||||
aus (cadr (assoc "KS_AUS" ks-data)))
|
||||
(if (and ein aus)
|
||||
(list (- (car (car aus)) (car (car ein)))
|
||||
(- (cadr (car aus)) (cadr (car ein)))
|
||||
(- (caddr (car aus)) (caddr (car ein))))
|
||||
nil))
|
||||
|
||||
;; Misst KS_EIN/KS_AUS eines Blocks, ohne eine bleibende Einfuegung zu
|
||||
;; hinterlassen: der Block wird bei Massstab 1 am Ursprung eingefuegt,
|
||||
;; vermessen und wieder geloescht. extract-ks-from-block cached das Ergebnis
|
||||
;; je Blockname, der zweite Aufruf kostet also nichts mehr.
|
||||
;; Rueckgabe wie extract-ks-from-block (Blockkoordinaten), sonst nil.
|
||||
(defun ks-block-messen (blockname / eff temp-obj daten)
|
||||
(setq eff (ensure-block-loaded blockname))
|
||||
(if (tblsearch "BLOCK" eff)
|
||||
(progn
|
||||
(setq temp-obj (vla-InsertBlock modelspace
|
||||
(vlax-3D-point '(0 0 0)) eff 1.0 1.0 1.0 0))
|
||||
(setq daten (extract-ks-from-block temp-obj))
|
||||
(if (not (vlax-erased-p temp-obj)) (vla-Delete temp-obj))
|
||||
daten)
|
||||
nil))
|
||||
|
||||
;; --- Block per KS_EIN/KS_AUS einfuegen, in X SKALIERT (nur Rz-Rotation) ---
|
||||
;; Wie insert-block-by-ks, zusaetzlich mit X-Massstab skala - fuer laengen-
|
||||
;; variable Zwischenstuecke (Kettenfoerderer KF_LAENGE, dieselbe Rolle wie
|
||||
;; die Staustrecke beim VarioFoerderer). Die lokalen KS-Punkte werden VOR der
|
||||
;; Rotation in X mitskaliert; nur so liegt KS_EIN exakt auf einfuegepunkt und
|
||||
;; der zurueckgegebene KS_AUS traegt den skalierten Versatz.
|
||||
;; Rueckgabe: Weltpunkt von KS_AUS (fuer die Verkettung), sonst einfuegepunkt.
|
||||
(defun insert-block-ks-skaliert (blockname einfuegepunkt hz skala /
|
||||
block-obj ks-data ks-ein ks-aus rad-h chv shv
|
||||
ein-x ein-y ein-z aus-x dx-loc dy-loc dz-loc
|
||||
offset ausgang)
|
||||
(if (or (null einfuegepunkt) (not (listp einfuegepunkt)))
|
||||
(progn
|
||||
(princ (ssg-textf "vfc-fehler-ungueltiger-einfuegepunkt" (list blockname)))
|
||||
(exit))
|
||||
)
|
||||
(if (or (null skala) (<= skala 0.0)) (setq skala 1.0))
|
||||
(setq blockname (ensure-block-loaded blockname))
|
||||
(if (not (tblsearch "BLOCK" blockname))
|
||||
(progn
|
||||
(princ (ssg-textf "vfc-fehler-block-nicht-in-bibliothek-abgebrochen" (list blockname)))
|
||||
(exit))
|
||||
)
|
||||
(princ (ssg-textf "vfc-fuege-block-ein-hz" (list blockname (rtos (float hz) 2 1) (chr 176))))
|
||||
(setq rad-h (* (float hz) (/ pi 180.0)))
|
||||
(setq chv (cos rad-h) shv (sin rad-h))
|
||||
;; KS am UNSKALIERTEN Block messen (der Cache arbeitet je Blockname), die
|
||||
;; lokalen Punkte danach selbst in X skalieren.
|
||||
(setq ks-data (ks-block-messen blockname))
|
||||
(setq ks-ein (cadr (assoc "KS_EIN" ks-data)))
|
||||
(setq ks-aus (cadr (assoc "KS_AUS" ks-data)))
|
||||
(setq block-obj (vla-InsertBlock modelspace
|
||||
(vlax-3D-point '(0 0 0))
|
||||
blockname skala 1.0 1.0 0))
|
||||
(ssg-ils-block-auf-ebene block-obj blockname)
|
||||
(if (> (abs hz) 0.0001)
|
||||
(vla-TransformBy block-obj (vlax-tmatrix
|
||||
(list (list chv (- shv) 0 0)
|
||||
(list shv chv 0 0)
|
||||
(list 0 0 1 0)
|
||||
(list 0 0 0 1))))
|
||||
)
|
||||
(if (and ks-ein ks-aus)
|
||||
(progn
|
||||
(setq ein-x (* skala (car (car ks-ein)))
|
||||
ein-y (cadr (car ks-ein))
|
||||
ein-z (caddr (car ks-ein)))
|
||||
(setq aus-x (* skala (car (car ks-aus))))
|
||||
(setq offset (list
|
||||
(- (car einfuegepunkt) (- (* chv ein-x) (* shv ein-y)))
|
||||
(- (cadr einfuegepunkt) (+ (* shv ein-x) (* chv ein-y)))
|
||||
(- (caddr einfuegepunkt) ein-z)))
|
||||
(vla-Move block-obj
|
||||
(vlax-3D-point '(0 0 0))
|
||||
(vlax-3D-point offset))
|
||||
(setq dx-loc (- aus-x ein-x))
|
||||
(setq dy-loc (- (cadr (car ks-aus)) ein-y))
|
||||
(setq dz-loc (- (caddr (car ks-aus)) ein-z))
|
||||
(setq ausgang (list
|
||||
(+ (car einfuegepunkt) (- (* chv dx-loc) (* shv dy-loc)))
|
||||
(+ (cadr einfuegepunkt) (+ (* shv dx-loc) (* chv dy-loc)))
|
||||
(+ (caddr einfuegepunkt) dz-loc)))
|
||||
(ssg-sepliste-dbg
|
||||
(strcat "insert-block-ks-skaliert " blockname
|
||||
" hz=" (rtos (float hz) 2 2) " skala=" (rtos (float skala) 2 4)
|
||||
" einfuegepunkt=" (ssg-sepliste-dbg-pt einfuegepunkt)
|
||||
" offset(=Gruppencode 10)=" (ssg-sepliste-dbg-pt offset)
|
||||
" ausgang=" (ssg-sepliste-dbg-pt ausgang)))
|
||||
(princ (ssg-textf "vfc-ks-aus-xyz"
|
||||
(list (rtos (car ausgang) 2 2) (rtos (cadr ausgang) 2 2) (rtos (caddr ausgang) 2 2))))
|
||||
ausgang
|
||||
)
|
||||
(progn
|
||||
(princ (ssg-text "vfc-warnung-ks-nicht-gefunden"))
|
||||
einfuegepunkt
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; FREI ROTIERTE KS-EINFUEGUNG (beliebige 3x3-Matrix)
|
||||
;; ------------------------------------------------------------
|
||||
;; Verallgemeinerung von insert-block-by-ks/insert-block-ks-skaliert: statt
|
||||
;; einer festen Rz- bzw. Rz*Ry-Drehung nimmt sie eine FERTIGE 3x3-Rotations-
|
||||
;; matrix entgegen. Noetig geworden fuer AUFRECHT eingebaute Baugruppen: der
|
||||
;; Kettenfoerderer ist in der XY-Ebene gezeichnet (X = Fahrtrichtung,
|
||||
;; Y = Hoehe), soll aber im Modell stehen - seine Hoehe muss also nach Z. Das
|
||||
;; ist eine Drehung um X, die weder insert-block-by-ks (nur Rz) noch
|
||||
;; ssg-rot-matrix-zy (Rz*Ry) erzeugen kann.
|
||||
;;
|
||||
;; Bewusst matrixbasiert statt mit einem weiteren Winkelparameter: die
|
||||
;; Aufrichtung ist nur EIN Anwendungsfall, und jeder weitere haette eine
|
||||
;; weitere Spezialfunktion gebraucht. Den Aufrufern bleibt freigestellt,
|
||||
;; welche Drehungen sie kombinieren (beim Kettenfoerderer
|
||||
;; Rz(basis) * Rx(90) * Rz(eigen), siehe kf-matrix-aufrecht).
|
||||
|
||||
;; Elementare Rotationsmatrizen (3x3, Winkel in GRAD).
|
||||
(defun ks-rot-x (grad / r c s)
|
||||
(setq r (* (float grad) (/ pi 180.0)) c (cos r) s (sin r))
|
||||
(list (list 1.0 0.0 0.0)
|
||||
(list 0.0 c (- s))
|
||||
(list 0.0 s c )))
|
||||
|
||||
(defun ks-rot-y (grad / r c s)
|
||||
(setq r (* (float grad) (/ pi 180.0)) c (cos r) s (sin r))
|
||||
(list (list c 0.0 s )
|
||||
(list 0.0 1.0 0.0)
|
||||
(list (- s) 0.0 c )))
|
||||
|
||||
(defun ks-rot-z (grad / r c s)
|
||||
(setq r (* (float grad) (/ pi 180.0)) c (cos r) s (sin r))
|
||||
(list (list c (- s) 0.0)
|
||||
(list s c 0.0)
|
||||
(list 0.0 0.0 1.0)))
|
||||
|
||||
;; 3x3-Rotation in die 4x4-Form bringen, die vla-TransformBy erwartet.
|
||||
(defun ks-mat3->mat4 (R)
|
||||
(list (append (car R) '(0.0))
|
||||
(append (cadr R) '(0.0))
|
||||
(append (caddr R) '(0.0))
|
||||
'(0.0 0.0 0.0 1.0)))
|
||||
|
||||
;; --- Block per KS_EIN/KS_AUS einfuegen, frei rotiert und in X skaliert ---
|
||||
;; blockname Rohname (wird ueber ensure-block-loaded aufgeloest)
|
||||
;; einfuegepunkt Weltpunkt, auf den KS_EIN zu liegen kommt
|
||||
;; R 3x3-Rotationsmatrix (Blockkoordinaten -> Welt)
|
||||
;; skala X-Massstab (1.0 = unskaliert)
|
||||
;; Rueckgabe: Weltpunkt von KS_AUS (fuer die Verkettung), sonst einfuegepunkt.
|
||||
;;
|
||||
;; Reihenfolge wie bei den uebrigen Primitiven: am Ursprung einfuegen,
|
||||
;; skalieren, drehen, dann so verschieben, dass das GEDREHTE KS_EIN exakt auf
|
||||
;; einfuegepunkt liegt. Die lokalen KS-Punkte werden dabei zuerst in X
|
||||
;; mitskaliert - sonst zeigt der zurueckgegebene KS_AUS am skalierten Block
|
||||
;; vorbei.
|
||||
(defun insert-block-ks-matrix (blockname einfuegepunkt R skala /
|
||||
block-obj ks-data ks-ein ks-aus
|
||||
ein-lok aus-lok ein-welt aus-welt offset ausgang)
|
||||
(if (or (null einfuegepunkt) (not (listp einfuegepunkt)))
|
||||
(progn
|
||||
(princ (ssg-textf "vfc-fehler-ungueltiger-einfuegepunkt" (list blockname)))
|
||||
(exit))
|
||||
)
|
||||
(if (or (null skala) (<= skala 0.0)) (setq skala 1.0))
|
||||
(setq blockname (ensure-block-loaded blockname))
|
||||
(if (not (tblsearch "BLOCK" blockname))
|
||||
(progn
|
||||
(princ (ssg-textf "vfc-fehler-block-nicht-in-bibliothek-abgebrochen" (list blockname)))
|
||||
(exit))
|
||||
)
|
||||
(setq ks-data (ks-block-messen blockname))
|
||||
(setq ks-ein (cadr (assoc "KS_EIN" ks-data)))
|
||||
(setq ks-aus (cadr (assoc "KS_AUS" ks-data)))
|
||||
(setq block-obj (vla-InsertBlock modelspace
|
||||
(vlax-3D-point '(0 0 0))
|
||||
blockname skala 1.0 1.0 0))
|
||||
(ssg-ils-block-auf-ebene block-obj blockname)
|
||||
(vla-TransformBy block-obj (vlax-tmatrix (ks-mat3->mat4 R)))
|
||||
(if (and ks-ein ks-aus)
|
||||
(progn
|
||||
;; lokale KS-Punkte, in X mitskaliert
|
||||
(setq ein-lok (list (* skala (car (car ks-ein)))
|
||||
(cadr (car ks-ein))
|
||||
(caddr (car ks-ein))))
|
||||
(setq aus-lok (list (* skala (car (car ks-aus)))
|
||||
(cadr (car ks-aus))
|
||||
(caddr (car ks-aus))))
|
||||
(setq ein-welt (mat3-mul-vec3 R ein-lok))
|
||||
(setq aus-welt (mat3-mul-vec3 R aus-lok))
|
||||
(setq offset (list (- (car einfuegepunkt) (car ein-welt))
|
||||
(- (cadr einfuegepunkt) (cadr ein-welt))
|
||||
(- (caddr einfuegepunkt) (caddr ein-welt))))
|
||||
(vla-Move block-obj
|
||||
(vlax-3D-point '(0 0 0))
|
||||
(vlax-3D-point offset))
|
||||
(setq ausgang (list (+ (car einfuegepunkt) (- (car aus-welt) (car ein-welt)))
|
||||
(+ (cadr einfuegepunkt) (- (cadr aus-welt) (cadr ein-welt)))
|
||||
(+ (caddr einfuegepunkt) (- (caddr aus-welt) (caddr ein-welt)))))
|
||||
(ssg-sepliste-dbg
|
||||
(strcat "insert-block-ks-matrix " blockname
|
||||
" skala=" (rtos (float skala) 2 4)
|
||||
" einfuegepunkt=" (ssg-sepliste-dbg-pt einfuegepunkt)
|
||||
" ks_ein_welt=" (ssg-sepliste-dbg-pt ein-welt)
|
||||
" ks_aus_welt=" (ssg-sepliste-dbg-pt aus-welt)
|
||||
" ausgang=" (ssg-sepliste-dbg-pt ausgang)))
|
||||
ausgang
|
||||
)
|
||||
(progn
|
||||
(princ (ssg-text "vfc-warnung-ks-nicht-gefunden"))
|
||||
einfuegepunkt
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; SEPLISTE: Separator-/AS-/ES-Reihenfolge als XDATA am fertigen Wrapper
|
||||
;; ------------------------------------------------------------
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
(load (strcat base-path "OmniModulInsert.lsp") "OmniModulInsert.lsp nicht gefunden")
|
||||
(load (strcat base-path "Tro_Edit.lsp") "Tro_Edit.lsp nicht gefunden")
|
||||
(load (strcat base-path "Connection_Edit.lsp") "Connection_Edit.lsp nicht gefunden")
|
||||
(load (strcat base-path "Jam_Edit.lsp") "Jam_Edit.lsp nicht gefunden")
|
||||
(load (strcat base-path "SSG_LIB_Commands.lsp") "SSG_LIB_Commands.lsp nicht gefunden")
|
||||
;; Werkzeuge: ssg_texttools nutzt ssg_blocktools, beide nutzen ssg_input
|
||||
(load (strcat base-path "ssg_blocktools.lsp") "ssg_blocktools.lsp nicht gefunden")
|
||||
|
||||
@@ -218,6 +218,102 @@
|
||||
(defun vf-motorseite-aktuell ( / )
|
||||
(if (member *vf-motorseite* '("links" "rechts")) *vf-motorseite* "rechts"))
|
||||
|
||||
;; ============================================================
|
||||
;; VF-HOEHE JE SEGMENT (Attribut VF_HOEHE_m, Sivas 4433-4437)
|
||||
;; ============================================================
|
||||
;; Sivas erwartet je Streckengruppe bis zu fuenf Variofoerderer-Hoehen. Ein
|
||||
;; Eintrag gehoert zu EINEM VF-Segment (Koerper) - nicht zu einer ganzen
|
||||
;; Foerdereinheit und nicht zur ganzen Kette (Nutzer-Korrektur 2026-10-21):
|
||||
;;
|
||||
;; Hoehe = Mittelwert aus KS_EIN und KS_AUS DIESES Segments.
|
||||
;;
|
||||
;; Eine Kette, die durch Vario-Boegen in drei Abschnitte geteilt ist, bekommt
|
||||
;; dadurch drei Werte - die Liste laeuft Eintrag fuer Eintrag parallel zu
|
||||
;; L_VF_m, VF_WINKEL und ANTRIEBFAHRTRICHTUNG.
|
||||
;;
|
||||
;; Erfasst wird an genau EINER Stelle: vfs-vf-koerper baut ein Segment, kennt
|
||||
;; dessen KS_EIN als Eingangspunkt und liefert dessen KS_AUS zurueck. Alle
|
||||
;; Modi (Standard, Etage, Linienzug) bauen ihre VF-Koerper darueber, deshalb
|
||||
;; muss der verzweigte Bau-Pfad selbst nicht angefasst werden.
|
||||
;;
|
||||
;; Einheit: Meter mit 3 Nachkommastellen (wie L_VF_m), kommagetrennt ueber
|
||||
;; vfl-join-komma - Reihenfolge = Bau-Reihenfolge.
|
||||
(if (not (boundp '*vf-acc-vfhoehe*)) (setq *vf-acc-vfhoehe* '()))
|
||||
|
||||
(defun vf-vfhoehe-reset ()
|
||||
(setq *vf-acc-vfhoehe* '()))
|
||||
|
||||
;; Ein VF-Segment erfassen: z-ein = Z des KS_EIN, z-aus = Z des KS_AUS (mm).
|
||||
;; Fehlt einer der Werte, wird NICHTS angehaengt - sonst verschoebe sich die
|
||||
;; Liste gegen L_VF_m/VF_WINKEL und im Export landete eine Hoehe beim falschen
|
||||
;; Foerderer.
|
||||
(defun vf-vfhoehe-segment (z-ein z-aus)
|
||||
(if (and (numberp z-ein) (numberp z-aus))
|
||||
(setq *vf-acc-vfhoehe*
|
||||
(append *vf-acc-vfhoehe* (list (vf-meter-3 (/ (+ z-ein z-aus) 2.0)))))))
|
||||
|
||||
;; Bequemes Paar fuer die Bau-Pfade: vor dem Einbau den Startpunkt merken,
|
||||
;; danach mit dem Endpunkt abschliessen. Beide geben ihren Punkt zurueck,
|
||||
;; lassen sich also ohne zusaetzliche lokale Variable einsetzen:
|
||||
;;
|
||||
;; (vf-vfhoehe-merke pt)
|
||||
;; (setq pt (insert-inclined-scaled-block ...))
|
||||
;; (vf-vfhoehe-schliesse pt)
|
||||
;;
|
||||
;; Noetig, weil die VF-Segmente NICHT alle ueber vfs-vf-koerper laufen: die
|
||||
;; horizontalen Zwischenstuecke und die Modus-2-Fuellstuecke bauen direkt mit
|
||||
;; insert-inclined-scaled-block. Wurde dort nicht erfasst, fehlten ihre
|
||||
;; Hoehen und VF_HOEHE_m war kuerzer als L_VF_m (realer Befund 2026-10-21:
|
||||
;; L_VF_m hatte drei Eintraege, VF_HOEHE_m nur einen).
|
||||
;;
|
||||
;; REGEL: Jede Stelle, die (vfl-acc-vf-seg ...) aufruft, MUSS auch eine Hoehe
|
||||
;; erfassen - sonst verschiebt sich die Liste gegen L_VF_m/VF_WINKEL und im
|
||||
;; Sivas-Export landet eine Hoehe beim falschen Foerderer.
|
||||
(if (not (boundp '*vf-vfhoehe-merk*)) (setq *vf-vfhoehe-merk* nil))
|
||||
|
||||
(defun vf-vfhoehe-merke (pt)
|
||||
(setq *vf-vfhoehe-merk* (if (listp pt) (caddr pt) nil))
|
||||
pt)
|
||||
|
||||
(defun vf-vfhoehe-schliesse (pt)
|
||||
(vf-vfhoehe-segment *vf-vfhoehe-merk* (if (listp pt) (caddr pt) nil))
|
||||
(setq *vf-vfhoehe-merk* nil)
|
||||
pt)
|
||||
|
||||
;; SONDERFALL Standard/Etage: Hoehe ueber die GANZE Kette.
|
||||
;;
|
||||
;; Diese beiden Typen haben nur EINEN Motor und nur EINEN geraden
|
||||
;; VF-Abschnitt (Nutzer-Vorgabe 2026-10-21). Statt des Segmentwerts gilt dort
|
||||
;; der Mittelwert der ganzen Anlage:
|
||||
;; Anfang = KS_EIN des AS-Elements (Startpunkt der Anlage)
|
||||
;; Ende = KS_AUS des ES-Elements (Rueckgabewert der Einfuegefunktion)
|
||||
;;
|
||||
;; ERSETZT die Liste bewusst, statt anzuhaengen: vfs-vf-koerper hat beim Bau
|
||||
;; bereits den Segmentwert gesammelt, der hier nicht gelten soll. Ergebnis ist
|
||||
;; genau ein Eintrag.
|
||||
;;
|
||||
;; Gerechnet wird aus der GEBAUTEN Geometrie, nicht aus der Soll-Vorgabe
|
||||
;; (anders als MONTAGEHOEHE_m, dessen hoehe-bis aus deltaH abgeleitet ist).
|
||||
;; Beide Hoehen in mm.
|
||||
(defun vf-vfhoehe-kette (z-anfang z-ende)
|
||||
(if (and (numberp z-anfang) (numberp z-ende))
|
||||
(setq *vf-acc-vfhoehe* (list (vf-meter-3 (/ (+ z-anfang z-ende) 2.0))))
|
||||
(setq *vf-acc-vfhoehe* '())))
|
||||
|
||||
;; Millimeter -> Meter als String mit GENAU 3 Nachkommastellen.
|
||||
;;
|
||||
;; (rtos x 2 3) allein genuegt nicht: je nach DIMZIN schneidet es nachfolgende
|
||||
;; Nullen ab und liefert "2.5" statt "2.500" bzw. "-1" statt "-1.000" (real
|
||||
;; beobachtet im Testlauf). Fuer eine Merkmalsliste ist die feste Stellenzahl
|
||||
;; aber gewollt, darum wird hier aufgefuellt - unabhaengig von der
|
||||
;; Zeichnungseinstellung.
|
||||
(defun vf-meter-3 (mm / s pos)
|
||||
(setq s (rtos (/ (float mm) 1000.0) 2 3))
|
||||
(if (not (vl-string-search "." s)) (setq s (strcat s ".")))
|
||||
(setq pos (vl-string-search "." s))
|
||||
(while (< (- (strlen s) pos 1) 3) (setq s (strcat s "0")))
|
||||
s)
|
||||
|
||||
;; ============================================================
|
||||
;; TEIL 5: KS_EIN/KS_AUS EXTRAKTION
|
||||
;; ============================================================
|
||||
@@ -977,6 +1073,9 @@
|
||||
(cons "L_VF_m" (rtos (/ L_VF 1000.0) 2 3))
|
||||
(cons "ANTRIEBFAHRTRICHTUNG" richtung)
|
||||
(cons "VF_WINKEL" (itoa best-winkel))
|
||||
;; Hoehe der (einen) Foerdereinheit - beim Standard-/Etage-Typ
|
||||
;; fuellen vfs-vf-entry/-exit genau einen Listeneintrag.
|
||||
(cons "VF_HOEHE_m" (vfl-join-komma *vf-acc-vfhoehe*))
|
||||
(cons "ANZAHL_SEPARATOR" "2")
|
||||
(cons "ANZAHL_SCANNER" (itoa n-scanner))
|
||||
(cons "GERUEST_EINZELMODUL" geruest-einzelmodul)
|
||||
@@ -1013,6 +1112,10 @@
|
||||
horizontal-info winkelwahl best-winkel L_GF L_VF L_GF1 L_GF2
|
||||
verteilung-modus n-scanner hoehe-von hoehe-bis lastEnt
|
||||
vf-insert vf-endpunkt staustrecke-basis)
|
||||
;; VF-Hoehen-Akkumulator pro Anlage zuruecksetzen - sonst erbte die naechste
|
||||
;; Anlage die Hoehen der vorherigen. (Im Linienzug erledigt das
|
||||
;; vfl-acc-reset; Standard/Etage laufen nicht darueber.)
|
||||
(vf-vfhoehe-reset)
|
||||
(setq berechne-fn (vf-registry-berechne-fn typ))
|
||||
(setq einfuege-fn (vf-registry-einfuege-fn typ))
|
||||
(setq ergebnis (apply berechne-fn (list deltaL deltaH richtung seite)))
|
||||
@@ -1064,6 +1167,15 @@
|
||||
(setq vf-endpunkt
|
||||
(apply einfuege-fn
|
||||
(list deltaL deltaH richtung best-winkel L_GF1 L_GF2 L_VF startpunkt seite hz)))
|
||||
;; VF_HOEHE_m fuer Standard/Etage: Mittelwert ueber die GANZE Kette
|
||||
;; (AS-KS_EIN = startpunkt, ES-KS_AUS = Rueckgabe der Einfuegefunktion),
|
||||
;; weil es hier nur einen Motor und nur einen geraden VF-Abschnitt
|
||||
;; gibt. Ersetzt den beim Bau gesammelten Segmentwert - siehe
|
||||
;; vf-vfhoehe-kette. Der Linienzug laeuft NICHT hier durch und behaelt
|
||||
;; daher seine Segmentliste.
|
||||
(vf-vfhoehe-kette (caddr startpunkt)
|
||||
(if (and vf-endpunkt (listp vf-endpunkt))
|
||||
(caddr vf-endpunkt) nil))
|
||||
(setq vf-insert
|
||||
(vf-block-erstellen typ seite vf-nummer n-scanner
|
||||
hoehe-von hoehe-bis deltaH deltaL L_VF L_GF1 L_GF2
|
||||
|
||||
+11
-4
@@ -101,8 +101,8 @@
|
||||
(if (null *vfk-etage-hz-winkel*) (setq *vfk-etage-hz-winkel* 30.0))
|
||||
|
||||
;; Eckwinkel-Toleranz bei der automatischen Pfad-Klassifizierung (Modus 3,
|
||||
;; vf-linienzug-modus3 -> vfl2-pruefe-eckwinkel). Aktiv referenziert in
|
||||
;; vf_linienzug.lsp (beide Aufrufstellen von vfl2-pruefe-eckwinkel).
|
||||
;; vf-linienzug-modus3 -> vfl-pfad-eckwinkel-pruefen). Aktiv referenziert in
|
||||
;; vf_linienzug.lsp (beide Aufrufstellen von vfl-pfad-eckwinkel-pruefen).
|
||||
(if (null *vfk-eckwinkel-toleranz*) (setq *vfk-eckwinkel-toleranz* 5.0))
|
||||
|
||||
;; Schwellwert (Grad), ab dem ein Frame noch als "flach" (~0 Grad) gilt.
|
||||
@@ -123,7 +123,7 @@
|
||||
;; (vf_etage.lsp Z.41)
|
||||
;; - Linienzug-Kettenende/Body-Abschluss (nur Motor+1 Separator, KEIN
|
||||
;; Umlenk-Anteil): 800 als rohes Literal an >10 Stellen in
|
||||
;; vf_linienzug.lsp (vfl-body-zerlegung, vfl3-waehle-winkel, ...)
|
||||
;; vf_linienzug.lsp (vfl-body-zerlegung, vfl-zsolve-winkel-waehlen, ...)
|
||||
;; Diese vier NICHT vereinheitlichen ohne sorgfaeltige Pruefung - sie
|
||||
;; entstehen aus unterschiedlicher Bauteil-Zusammensetzung (siehe jeweiliger
|
||||
;; Kommentar im Modul), keine Kopiergleichheit.
|
||||
@@ -166,7 +166,7 @@
|
||||
;; Mindestlaenge (mm) fuer die 3-Grad-GF-Anschlussstrecke (GF1 am Einlauf
|
||||
;; einer VF-Einheit). Bereits als *vfl-gf-min-laenge* in vf_linienzug.lsp
|
||||
;; benannt (Wert 400.0) - hier nur gespiegelt. Das fruehere rohe 400.0-
|
||||
;; Duplikat (br-gf1 in vfl3-*) referenziert jetzt *vfl-gf-min-laenge*.
|
||||
;; Duplikat (br-gf1 in vfl-zsolve-*) referenziert jetzt *vfl-gf-min-laenge*.
|
||||
(if (null *vfk-gf-anschluss-mindestlaenge*) (setq *vfk-gf-anschluss-mindestlaenge* 400.0))
|
||||
|
||||
;; ============================================================
|
||||
@@ -303,6 +303,13 @@
|
||||
;; Ueberschreiten, kein Abbruch. Aktiv referenziert.
|
||||
(if (null *vfk-vf-laenge-max*) (setq *vfk-vf-laenge-max* 25000.0))
|
||||
|
||||
;; Hoechstzahl Vario-Kurven INNERHALB einer VF-Einheit (zwischen Umlenk- und
|
||||
;; Motorstation) - Nutzer-Regel 2026-10-22. Zwei Kurven bedeuten hoechstens
|
||||
;; drei VF-Geraden im selben Lauf; danach muss die Einheit mit einer
|
||||
;; Motorstation schliessen und eine neue mit Umlenkstation beginnen.
|
||||
;; Geprueft in vfl-m2-lauf-grenzen (vf_linienzug.lsp, Modus 2).
|
||||
(if (null *vfk-vf-kurven-max*) (setq *vfk-vf-kurven-max* 2))
|
||||
|
||||
(setq *vfk-konstanten-geladen* t)
|
||||
(princ)
|
||||
(princ)
|
||||
|
||||
+2479
-252
File diff suppressed because it is too large
Load Diff
+47
-4
@@ -274,7 +274,18 @@
|
||||
((and (= (type v) 'STR) (= (strcase v) "AUTO")) (vsp-raus "NIL" nil))
|
||||
(T (vsp-zahl "REAL" v "eingang_hoehe"))))
|
||||
|
||||
(defun vsp-praeambel (kopf / punkt)
|
||||
;; Praeambel-Tokens: PT(Startpunkt) REAL(Starthoehe) STR(AS ja/nein)
|
||||
;; [STR(Winkel) STR(Seite) (PT|NIL)(Zufuehrungsachse)].
|
||||
;;
|
||||
;; Das Achsen-Feld "as_achse" ist OPTIONAL (Gegenstueck zu
|
||||
;; vfl-frage-as-winkel-seite-oder-achse und zu praeambel() in
|
||||
;; lib/vf_linienzug_grammatik.py):
|
||||
;; [x, y, z] -> PT (Zufuehrungsachse ueber einen zweiten Punkt)
|
||||
;; "ohne" -> NIL (bewusst ohne Achse gebaut)
|
||||
;; fehlt -> gar kein Token = Journalformat VOR 2026-10-21. Das replayt
|
||||
;; unveraendert; die Kettenrichtung kommt dann wie frueher aus
|
||||
;; dem naechsten Klick.
|
||||
(defun vsp-praeambel (kopf / punkt achse)
|
||||
(setq *vsp-wo* "start")
|
||||
(setq punkt (ssg-val kopf "start_punkt"))
|
||||
(if (and punkt (listp punkt) (>= (length punkt) 3))
|
||||
@@ -287,7 +298,13 @@
|
||||
(if (vsp-ja-p (ssg-val kopf "as"))
|
||||
(progn
|
||||
(vsp-wert-str (ssg-val kopf "as_winkel") "as_winkel")
|
||||
(vsp-code-raus *vsp-tab-seite* (ssg-val kopf "as_seite") "as_seite"))))
|
||||
(vsp-code-raus *vsp-tab-seite* (ssg-val kopf "as_seite") "as_seite")
|
||||
(setq achse (ssg-val kopf "as_achse"))
|
||||
(cond
|
||||
((and achse (listp achse) (>= (length achse) 3))
|
||||
(vsp-raus "PT" (mapcar 'float achse)))
|
||||
((equal achse "ohne") (vsp-raus "NIL" nil))
|
||||
))))
|
||||
|
||||
;; naechste: Felder der NAECHSTEN Top-Level-Sektion (oder nil) - wird nur fuer
|
||||
;; "Linie-GF" gebraucht (siehe dort). *vsp-es-verbraucht* (Ausgabe-Flag, vom
|
||||
@@ -664,6 +681,7 @@
|
||||
(setq *vsp-alt-headless* (if (boundp '*vfl-headless*) *vfl-headless*))
|
||||
(setq *vfl-wizard-mode* nil)
|
||||
(setq *vfl-headless* T)
|
||||
(setq *vsp-alt-gui* (if (boundp '*ssg-gui-aus*) *ssg-gui-aus*))
|
||||
(if (car (atoms-family 1 '("SSG-GUI-AUS"))) (ssg-gui-aus))
|
||||
(setq *vsp-prompts* 0)
|
||||
(princ))
|
||||
@@ -676,7 +694,9 @@
|
||||
alert *vsp-alt-alert*)
|
||||
(setq *vfl-wizard-mode* *vsp-alt-wizard*)
|
||||
(setq *vfl-headless* *vsp-alt-headless*)
|
||||
(if (car (atoms-family 1 '("SSG-GUI-AN"))) (ssg-gui-an))
|
||||
;; Vorzustand zurueck statt pauschal ssg-gui-an: unter SSG_RUN_ALL_TESTS
|
||||
;; muss die GUI fuer den Export danach aus bleiben.
|
||||
(setq *ssg-gui-aus* *vsp-alt-gui*)
|
||||
(princ))
|
||||
|
||||
|
||||
@@ -919,6 +939,29 @@
|
||||
;; sid = Kennung im Record, dim = "2D"/"3D" oder nil (Sitzung),
|
||||
;; fehler = Liste der Spec-Fehler (bei nil-Journal die Begruendung).
|
||||
;; Erwartet den Headless-Rahmen (vsp-headless-an) beim Aufrufer.
|
||||
;; Bau-Funktion AUS DEM JOURNAL ableiten (Rueckgabe: Funktions-Symbol).
|
||||
;; Bewusst abgeleitet statt als zusaetzliches Argument: vsp-bau-journal hat
|
||||
;; zwei Aufrufer, und AutoLISP verlangt exakte Argumentzahl - eine erweiterte
|
||||
;; Signatur muesste jeden davon nachziehen (siehe CLAUDE.md). Die Ableitung
|
||||
;; kann der Datenlage ausserdem nicht widersprechen, weil sie GENAU das
|
||||
;; Journal liest, das gleich abgespielt wird.
|
||||
;;
|
||||
;; Unterscheidung:
|
||||
;; kein SEGS -> Modus 1 (Fragenfluss, Menue-Codes)
|
||||
;; SEGS + STR "m2v2" -> Modus 2 (die Formatmarke schreibt nur
|
||||
;; vf-linienzug-modus2, vfl-m2-formatmarke)
|
||||
;; SEGS ohne "m2v2" -> Modus 3
|
||||
;; Ein Fehlgriff faellt sofort auf: der Ergebnis-Record meldet dann offene
|
||||
;; Eingaben bzw. glieder_soll <> glieder_ist.
|
||||
(defun vsp-bau-fn-fuer-journal (journal)
|
||||
(cond
|
||||
((not (vfl-journal-hat-segs-p journal)) 'vf-linienzug-modus)
|
||||
((vl-some (function (lambda (e)
|
||||
(and (equal (car e) "STR") (equal (cdr e) "m2v2"))))
|
||||
journal)
|
||||
'vf-linienzug-modus2)
|
||||
(t 'vf-linienzug-modus3)))
|
||||
|
||||
(defun vsp-bau-journal (sid journal dim fehler / rec vor-ent alt-error err
|
||||
offen hl meld ist-glieder soll-glieder diff
|
||||
ist-journal jdiff ent ed)
|
||||
@@ -958,7 +1001,7 @@
|
||||
(setq alt-error *error*)
|
||||
(vfl-journal-reset)
|
||||
(vfl-journal-replay-start journal)
|
||||
(setq err (vl-catch-all-apply 'vf-linienzug-modus '()))
|
||||
(setq err (vl-catch-all-apply (vsp-bau-fn-fuer-journal journal) '()))
|
||||
(setq offen (vsp-queue-rest))
|
||||
;; Diagnose VOR dem Reset sichern (vfl-journal-reset loescht sie).
|
||||
(setq ist-journal (reverse *vfl-journal*))
|
||||
|
||||
+22
-2
@@ -609,12 +609,30 @@
|
||||
;; EIN reines VF-Sub-Segment. Wichtig: es BEGINNT und ENDET auf der
|
||||
;; 3-Grad-Basisneigung, weil Ein- und Ausgangsbogen denselben Winkel haben.
|
||||
;; Dadurch lassen sich mehrere Sub-Segmente (und Vario-Kurven dazwischen)
|
||||
;; beliebig aneinanderreihen (siehe doc/VarioFoerderer_Linienzug_Prinzipien.md).
|
||||
;; beliebig aneinanderreihen.
|
||||
;;
|
||||
;; Die Regel dahinter: der Vertikalbogen am ENDE eines VF (vor der
|
||||
;; Motorstation) hat denselben Winkel wie der am ANFANG (nach der
|
||||
;; Umlenkstation), und der abschliessende Bogen bringt die Strecke auf 3 Grad
|
||||
;; NACH UNTEN - weil die Motorstation selbst mit 3 Grad geneigt eingebaut wird
|
||||
;; und der Anschluss sonst knickt. Dasselbe gilt am anderen Ende: Umlenkstation
|
||||
;; (VF-Start) und Separator+ES-Element (Kettenende) gibt es hardwareseitig nur
|
||||
;; fuer die Anfahrt auf dieser Standard-Fallend-Basis; eine Anfahrt auf
|
||||
;; STEIGENDER Basis ist physisch nicht vorgesehen.
|
||||
;; Anfang und Ende auf derselben Basis zu halten ist also keine Konvention,
|
||||
;; sondern die Voraussetzung dafuer, dass zwei Sub-Segmente ueberhaupt
|
||||
;; aneinanderpassen.
|
||||
;; best-winkel=0 => horizontales Sub-Segment (Boegen fest auf_3/ab_3).
|
||||
(defun vfs-vf-koerper (aktueller-punkt richtung best-winkel L_VF hz /
|
||||
bogen-name bogen-mass bogen-dx bogen-dz)
|
||||
bogen-name bogen-mass bogen-dx bogen-dz z-ein)
|
||||
(if (null hz) (setq hz 0.0))
|
||||
(setq hz (float hz))
|
||||
;; Hoehe DIESES VF-Segments (Attribut VF_HOEHE_m, Sivas 4433-4437):
|
||||
;; KS_EIN ist der Punkt beim Eintritt, KS_AUS der Rueckgabewert am Ende -
|
||||
;; der Mittelwert beider wird unten angehaengt. Eine Kette mit drei durch
|
||||
;; Vario-Boegen getrennten Abschnitten bekommt dadurch drei Werte, parallel
|
||||
;; zu L_VF_m und VF_WINKEL (Nutzer-Vorgabe 2026-10-21).
|
||||
(setq z-ein (caddr aktueller-punkt))
|
||||
|
||||
;; 5. 1. Vertikalbogen
|
||||
;; Sonderfall best-winkel=0 (horizontale Zwischenstrecke, siehe
|
||||
@@ -717,6 +735,8 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; Segment-Hoehe anhaengen: Mittelwert aus KS_EIN (z-ein) und KS_AUS.
|
||||
(vf-vfhoehe-segment z-ein (caddr aktueller-punkt))
|
||||
aktueller-punkt
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user