[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
|
||||
|
||||
+314
-18
@@ -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)
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
|
||||
@@ -2,62 +2,77 @@
|
||||
|
||||
AutoLISP-Makros (SSG_LIB) fuer BricsCAD Pro zur automatisierten Erstellung von Foerderanlagen-Layouts (ILS Kreisel, Omniflo, VarioFoerderer, Gefaellestrecke, Geruest).
|
||||
|
||||
**Einstieg:**
|
||||
|
||||
- [doc/faq.md](doc/faq.md) - haeufige Fragen und erste Schritte mit dem Programm
|
||||
- [doc/cad-datenaufbereitung.md](doc/cad-datenaufbereitung.md) - neue CAD-Bausteine anlegen: Koordinatensysteme, Platzierung, Datenablage
|
||||
|
||||
## Menustruktur (SSG_LIB)
|
||||
|
||||
```
|
||||
SSG_LIB
|
||||
├── ILS
|
||||
│ ├── Kreisel-Module
|
||||
│ │ ├── Einfuegen → KreiselInsert
|
||||
│ │ ├── Verbinden → KreiselConnect
|
||||
│ │ ├── Bearbeiten → KreiselEdit
|
||||
│ │ └── Eckrad → ILS_Eckrad
|
||||
│ │ ├── Einfuegen / Verbinden / Bearbeiten → KreiselInsert / KreiselConnect / KreiselEdit
|
||||
│ │ ├── Eckrad / Eckrad bearbeiten → ILS_Eckrad / EckradEdit
|
||||
│ │ └── Weichenpunkte ermitteln → KREISEL_WEICHEN
|
||||
│ ├── Zusatzmodul
|
||||
│ │ ├── BTMT-Beladung → ILS_BTMT_Beladung
|
||||
│ │ ├── BTMT-Entladung → ILS_BTMT_Entladung
|
||||
│ │ ├── Scanner einfuegen → ILS_SCANNER_INSERT
|
||||
│ │ └── Separator einfuegen → ILS_SEPARATOR_INSERT
|
||||
│ │ ├── BTMT-Beladung / -Entladung → ILS_BTMT_Beladung / ILS_BTMT_Entladung
|
||||
│ │ └── Scanner / Separator einfuegen → ILS_SCANNER_INSERT / ILS_SEPARATOR_INSERT
|
||||
│ ├── Foerderer
|
||||
│ │ ├── Standard → StandardVarioFoerderer / StandardVarioFoerderer3D
|
||||
│ │ ├── Etage → EtageVarioFoerderer / EtageVarioFoerderer3D
|
||||
│ │ ├── Streckengruppe (Linienzug) → LinienzugVarioFoerdererManuell / -Zielhoehe / -Stueckweise
|
||||
│ │ └── Vario_Kette_Merge / VARIOFOERDERER_NACHRUESTEN
|
||||
│ │ ├── Standard (Werte manuell / aus 3D-Linie) → StandardVarioFoerderer / StandardVarioFoerderer3D
|
||||
│ │ ├── Etage (Werte manuell / aus 3D-Linie) → EtageVarioFoerderer / EtageVarioFoerderer3D
|
||||
│ │ ├── Streckengruppe (Linienzug) → LinienzugVarioFoerdererManuell / -Zielhoehe / -Stueckweise
|
||||
│ │ └── Vario_Kette_Merge / VarioFoerderer nachruesten → Vario_Kette_Merge / VARIOFOERDERER_NACHRUESTEN
|
||||
│ └── Gefaellestrecke
|
||||
│ ├── einfach → GEFAELLESTRECKE_EINFACH
|
||||
│ ├── aus 3D-Linie → GEFAELLESTRECKE_3DLINIE
|
||||
│ └── aus Linienzug → GEFAELLESTRECKE_LINIENZUG
|
||||
│ ├── einfach / aus 3D-Linie / aus Linienzug → GEFAELLESTRECKE_EINFACH / _3DLINIE / _LINIENZUG
|
||||
│ └── QC Linie mit GF (auch U-Form) → QcLinieMitGf / QcLinieMitGfUForm
|
||||
├── Omniflo
|
||||
│ ├── Boegen APB110/APB60
|
||||
│ ├── Aluprofil Gerade (AP60/AP110/APG110)
|
||||
│ ├── Weichen (90/45/Parallel/Weichenkoerper/Weichenkombinationen)
|
||||
│ ├── TEF Elemente, Anbaugruppen, Verbinder, Boegen fuer Weichen
|
||||
│ ├── Element bearbeiten → OMNI_EDIT
|
||||
│ └── Ladeschleifen (AP110) → OMNI_LADESCHLEIFE_AP110
|
||||
│ ├── Fahrstrecke / Fahrstrecken beschriften → OMNI_FAHRSTRECKE / OMNI_FAHRSTRECKE_BESCHRIFTEN
|
||||
│ ├── Boegen APB110 / APB60, Aluprofil Gerade (AP60/AP110/APG110)
|
||||
│ ├── Weichen (90/45/Parallel/22.5, Delta, Star)
|
||||
│ ├── TEF Elemente (inkl. TEF Gerade auf Linie → TEF_FOERDERER_LINIE)
|
||||
│ ├── Anbaugruppen (Stopper, Scanner, Buerstenbremse)
|
||||
│ ├── Spez. Streckenelemente ▸ Tuerloesungen ▸ Schwenkschienen → OMNI_SCHW_400_*
|
||||
│ ├── KettenFoerderer → KETTENFOERDERER
|
||||
│ ├── Ladeschleifen → OMNI_LADESCHLEIFE_AP110
|
||||
│ ├── Verbinder → OMNI_TV_*
|
||||
│ ├── Boegen fuer Weichen (ausgegraut, Dummy) → OMNI_APBW_*
|
||||
│ └── Element bearbeiten → OMNI_EDIT
|
||||
├── Geruest
|
||||
│ ├── Rohr-Geruest-Traeger → GERUEST_TRAEGER
|
||||
│ ├── Saeulen / Rohrabhaenger / Wandbefestigung → GERUEST
|
||||
│ └── Funktionen ▸ Traeger beschriften → GERUEST_TRAEGER_BESCHRIFTEN
|
||||
│ ├── Rohr-Geruest-Traeger → GERUEST_TRAEGER
|
||||
│ ├── Saeulen / Rohrabhaenger / Wandbefestigung → GERUEST_SAEULEN / GERUEST_ROHRABHAENGER / GERUEST_WANDBEFESTIGUNG
|
||||
│ ├── Gattertraeger (Platzhalter) → GERUEST
|
||||
│ └── Funktionen ▸ Traeger beschriften → GERUEST_TRAEGER_BESCHRIFTEN
|
||||
├── SPS
|
||||
│ ├── TRO (Marker einfuegen/bearbeiten) → TRO_INSERT / TRO_EDIT
|
||||
│ └── Connections (einfuegen/bearbeiten, Eingang/Ausgang) → CONNECTION_INSERT / CONNECTION_EDIT / ILS_EINGANG_INSERT / ILS_AUSGANG_INSERT
|
||||
│ ├── TRO (Marker einfuegen/bearbeiten) → TRO_INSERT / TRO_EDIT
|
||||
│ ├── Connections (einfuegen/bearbeiten) → CONNECTION_INSERT / CONNECTION_EDIT
|
||||
│ └── Eingang / Ausgang → ILS_EINGANG_INSERT / ILS_AUSGANG_INSERT
|
||||
├── Export
|
||||
│ ├── Export Sivas → EXPORTSIVAS
|
||||
│ └── Export CSV → EXPORTCSV
|
||||
│ ├── Export Sivas → EXPORTSIVAS
|
||||
│ └── Export CSV → EXPORTCSV
|
||||
├── Konfiguration
|
||||
│ ├── Umschalten 2D und 3D → SSG_DIM_SWITCH
|
||||
│ ├── Sprache → SSG_SPRACHE
|
||||
│ └── Planquadrate an/aus → PLANQUADRATE_TOGGLE
|
||||
│ ├── Umschalten 2D und 3D → SSG_DIM_SWITCH
|
||||
│ ├── Alle Bloecke auf 2D / 3D → SSG_DIM_ALL_2D / SSG_DIM_ALL_3D
|
||||
│ ├── Sprache → SSG_SPRACHE
|
||||
│ ├── Planquadrate an/aus → PLANQUADRATE_TOGGLE
|
||||
│ └── CSV-Export → CSV_EXPORT_KONFIG
|
||||
├── Werkzeuge
|
||||
│ ├── Bloecke zaehlen/loeschen, Attribute ersetzen → ssg_blocktools
|
||||
│ └── Text ersetzen/parallel/Hoehe/Stil → ssg_texttools
|
||||
└── Tests (Testsuiten ausfuehren und exportieren)
|
||||
│ ├── Bloecke zaehlen / loeschen, Attribute ersetzen → SSG_BLOCK_COUNT / SSG_BLOCK_DELETE / SSG_ATTR_ERSETZEN
|
||||
│ ├── Text ersetzen / parallel / Hoehe / Stil → SSG_TEXT_ERSETZEN / _PARALLEL / _HOEHE / _STIL
|
||||
│ ├── Faehnchen + Stueckliste aus Zeichnung → SSG_FAEHNCHEN_STUECKLISTE
|
||||
│ └── Din Formate → DIN_FORMATE
|
||||
└── Tests (alle Testsuiten, einzelne Szenarien, Export CSV/Sivas ALL, KS 2D/3D pruefen)
|
||||
```
|
||||
|
||||
Doppelklick auf einen Block ruft `SSG_BLOCKEDIT` auf und verzweigt nach Blockname
|
||||
(Kreisel, Eckrad, VF_/GF_, KF_, Omniflo, GR_, TRO_, CONNECTION_, JAM_ → passender Edit-Befehl).
|
||||
|
||||
Vollstaendige, laufend aktualisierte Befehls-/Modulzuordnung: siehe `CLAUDE.md` (Abschnitt "Modulzuordnung im Menue") und `menu/SSG_LIB.mnu`.
|
||||
|
||||
## Lademechanismus
|
||||
|
||||
Module werden per Lazy-Loading ueber das Menuesystem geladen (`ssg-ensure` in `SSG_LIB.mnl`). Einmalige Einrichtung pro BricsCAD-Installation:
|
||||
Die Module werden beim Laden des Menues ueber `SSG_LIB.mnl` initialisiert (`ssg-ensure`, ueberspringt bereits geladene Module; einzelne Module wie `DrawPlanquadrate`, `DinFormate`, `Tro_Edit`, `Jam_Edit` werden erst beim ersten Aufruf nachgeladen). Einmalige Einrichtung pro BricsCAD-Installation:
|
||||
|
||||
1. `bin/setenv.bat` ausfuehren (setzt `DXFM_LISP` u.a.)
|
||||
2. BricsCAD starten
|
||||
@@ -70,16 +85,18 @@ Details und die Core-Ladereihenfolge: siehe `CLAUDE.md` Abschnitt "Lademechanism
|
||||
```text
|
||||
dxfmakros/
|
||||
├── Lisp/ # AutoLISP-Makros und Kernbibliotheken (Details: Lisp/README.md)
|
||||
├── bin/ # Hilfs-Skripte (setenv.bat, start_briscad.bat)
|
||||
├── bin/ # Hilfs-Skripte (setenv, start_briscad, run_tests, Python-Wrapper)
|
||||
├── cfg/ # Konfigurationsdateien
|
||||
├── data/ # JSON-Daten, DXF-Quellen, Block-Libraries - nicht im Git
|
||||
├── data/ # JSON-Komponentendaten, DWG-/DXF-Bloecke, Block-Libraries
|
||||
├── dcl/ # DCL-Dialogdefinitionen
|
||||
├── doc/ # Dokumentation (doc/plan Architektur/Analysen, doc/todo offene Fahrplaene)
|
||||
├── lang/ # Benutzertexte de_DE.json / en_GB.json (ssg-text)
|
||||
├── lib/ # Python-Skripte (DXF-Bearbeitung, Export)
|
||||
├── log/ # Logdateien - nicht im Git
|
||||
├── logs/ # Logdateien und .dbg-Ausgaben (DXFM_LOG) - nicht im Git
|
||||
├── menu/ # BricsCAD-Menudefinition (SSG_LIB.mnu, SSG_LIB.mnl)
|
||||
├── results/ # Ergebnisse / Exporte - nicht im Git
|
||||
├── tests/ # Testskripte und Referenzdaten
|
||||
├── tools/ # Einmal-Werkzeuge (z.B. Migration der Sprachtexte)
|
||||
├── LICENSE
|
||||
├── README.md
|
||||
└── requirements.txt
|
||||
@@ -110,11 +127,18 @@ Headless-Unit-Tests (file- und zeichnungsfrei):
|
||||
bin\run_tests.bat --lisp
|
||||
```
|
||||
|
||||
Python-Tests (in der `.venv`):
|
||||
|
||||
```bat
|
||||
pytest tests/
|
||||
bin\run_tests.bat --check
|
||||
```
|
||||
|
||||
Zeichnungs-/Szenario-Tests laufen interaktiv in BricsCAD ueber das Menue `Tests` bzw. `SSG_RUN_ALL_TESTS`. Details: `doc/LispTests.md`, `tests/README.md`.
|
||||
|
||||
## Dokumentation
|
||||
|
||||
Ausfuehrliche Modul- und Befehlsdokumentation: `CLAUDE.md` (Projektanweisungen) und `Lisp/README.md`. Weitere Anwender-/Entwickler-Themen direkt in `doc/` (u.a. `variofoerderer.md`, `csv-export.md`, `faq.md`, `kommandos.md`). Architektur-Analysen und Planungsdokumente in `doc/plan/` (u.a. `translate.md`, `Entwicklungsplan.md`), offene Fahrplaene/TODOs in `doc/todo/`.
|
||||
Ausfuehrliche Modul- und Befehlsdokumentation: `CLAUDE.md` (Projektanweisungen) und `Lisp/README.md`. Weitere Anwender-/Entwickler-Themen direkt in `doc/` (u.a. `kommandos.md` - Uebersicht aller Befehle und Skripte, `variofoerderer.md`, `vf_linienzug_modus1_anleitung.md`, `csv-export.md`, `json-input-lisp.md`, `faq.md`). Architektur-Analysen und Planungsdokumente in `doc/plan/` (u.a. `translate.md`, `Entwicklungsplan.md`), alle offenen TODOs gesammelt in `doc/todo.md` (Detail-Fahrplaene in `doc/todo/`).
|
||||
|
||||
## Lizenz
|
||||
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
@echo off
|
||||
REM ================================================================
|
||||
REM create_tests.bat - ILS Testlauf
|
||||
REM
|
||||
REM Ablauf:
|
||||
REM 1. Umgebung setzen
|
||||
REM 2. Python: ILStest.dxf mit Linien erzeugen
|
||||
REM 3. BricsCAD: Kreisel einfuegen, exportieren, speichern
|
||||
REM 4. Python: Ergebnisse gegen Referenzen validieren
|
||||
REM ================================================================
|
||||
|
||||
call "%~dp0setenv.bat"
|
||||
|
||||
echo.
|
||||
echo ================================================================
|
||||
echo ILS TEST - Schritt 1: Basis-DXF erzeugen
|
||||
echo ================================================================
|
||||
python "%DXFM_TESTS%\create_ILStest_dxf.py" "%DXFM_TESTS%\ILStest.dxf"
|
||||
if errorlevel 1 (
|
||||
echo FEHLER: DXF-Erzeugung fehlgeschlagen!
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo.
|
||||
echo ================================================================
|
||||
echo ILS TEST - Schritt 2: BricsCAD starten und Kreisel erzeugen
|
||||
echo ================================================================
|
||||
echo BricsCAD wird gestartet mit dem Testskript...
|
||||
echo Nach Abschluss des Tests BricsCAD schliessen.
|
||||
echo.
|
||||
REM /b = Skript ausfuehren (NICHT /s - das ist der Support-Ordner-Schalter).
|
||||
start /wait "" "%BRICSCAD%" /b "%DXFM_TESTS%\ILS_test.scr"
|
||||
|
||||
echo.
|
||||
echo ================================================================
|
||||
echo ILS TEST - Schritt 3: Ergebnisse validieren
|
||||
echo ================================================================
|
||||
python "%DXFM_TESTS%\validate_tests.py" "%DXFM_RESULTS%" "%DXFM_TESTS%\references"
|
||||
|
||||
echo.
|
||||
pause
|
||||
@@ -86,6 +86,19 @@ if %DO_LISP%==1 (
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM Laufende BricsCAD-Instanz? Dann NICHT starten: BricsCAD reicht einen
|
||||
REM /b-Start an die offene Instanz weiter, das Skript liefe in der
|
||||
REM Sitzung des Benutzers und das abschliessende _.QUIT haengt dort an
|
||||
REM der Speichern-Rueckfrage bzw. beendet die Sitzung.
|
||||
REM findstr statt find: steht Git-Bash im PATH, ist "find" das Unix-find.
|
||||
tasklist /FI "IMAGENAME eq bricscad.exe" /NH 2>nul | findstr /i "bricscad.exe" >nul
|
||||
if not errorlevel 1 (
|
||||
echo FEHLER: BricsCAD laeuft bereits. Der Testlauf wuerde in dieser
|
||||
echo Sitzung landen und sie am Ende mit QUIT beenden.
|
||||
echo Bitte BricsCAD schliessen und erneut starten.
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM Altes Ergebnis loeschen - fehlender Report = fehlgeschlagener Lauf
|
||||
if exist "%DXFM_TESTOUT%\unit_results.txt" del "%DXFM_TESTOUT%\unit_results.txt"
|
||||
|
||||
|
||||
Binary file not shown.
@@ -76,6 +76,15 @@
|
||||
# erkennt sie wie alle Omniflo-Teile ueber TEILEART "Omniflo ..." und schreibt
|
||||
# je Nummer aus ARTINR eine Omniflo-Zeile.
|
||||
#
|
||||
# pattern_kettenfoerderer: Kettenfoerderer/Schraegfoerderer Stahl
|
||||
# (KettenFoerderer.lsp, KF_<n>). Eine selbst zusammengebaute Baugruppe wie
|
||||
# GR_*, mit eigenen Attributen TEILEART ("Omniflo Kettenfoerderer ...") und
|
||||
# ARTINR - erkannt wird sie darum im allgemeinen Omniflo-Zweig von
|
||||
# export_sivas.py. Die drei Bausteine darin (Umlenkstation, skaliertes
|
||||
# Zwischenstueck, Antriebsstation) werden NICHT einzeln gezaehlt. Die im
|
||||
# Dialog gewaehlten Verbindungselemente stehen als Attribut
|
||||
# VERBINDUNGSELEMENTE am Block und landen im Merkmale-/details-JSON.
|
||||
#
|
||||
# pattern_nested_bogen/_streckenelement/_umlenkstation/_motorstation: die
|
||||
# uebrigen Bausteine einer VF_n/GF_n-Kette (Boegen, gerade Foerderer-/
|
||||
# Gefaellestrecken-Segmente, Umlenk-/Motorstation). Wie pattern_schleuselement
|
||||
@@ -136,6 +145,7 @@ pattern_gerade= AP110*, AP_110*, AP60*
|
||||
# Gerüst
|
||||
pattern_geruest= GR_*
|
||||
pattern_verbinder= VB_*, TV_*
|
||||
pattern_kettenfoerderer= KF_*
|
||||
|
||||
[python]
|
||||
# Interpreter fuer die Export-Skripte (lib/export_csv.py, lib/export_sivas.py).
|
||||
|
||||
@@ -168,6 +168,13 @@ gf_beschriftung = GF_Beschriftung, 7
|
||||
# Lisp/DrawPlanquadrate.lsp (DRAW_PLANQUADRATE).
|
||||
planquadrate = ZZ_Planquadrate, 8
|
||||
|
||||
# Kettenfoerderer (Schraegfoerderer Stahl), aus Umlenkstation + skaliertem
|
||||
# Zwischenstueck + Antriebsstation zusammengebauter Block KF_n - siehe
|
||||
# Lisp/KettenFoerderer.lsp (KETTENFOERDERER). Wie VF_n/GF_n eine
|
||||
# ZUSAMMENGEBAUTE Baugruppe ohne eigene Blockdatei, der Layer muss darum hier
|
||||
# stehen. Die drei Bausteine darin behalten ihre eigenen Layer.
|
||||
kettenfoerderer = Omni_Kettenfoerderer, 4
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Lagerplanung (LagerInsert.lsp, Bloecke LG_*)
|
||||
|
||||
+97
-4
@@ -28,19 +28,45 @@
|
||||
# (TRANSFORMS-Dict), die den ermittelten Rohwert
|
||||
# (Attribut- oder Default-Wert) in die Sivas-Anzeige
|
||||
# umwandelt (z.B. "0"/"1" -> "Ja"/"Nein"). Bekannte Namen:
|
||||
# ja_nein, geruest_typ_anzeige. Ein unbekannter Name
|
||||
# ja_nein, geruest_typ_anzeige, mm_zu_m, as_es_vorhanden,
|
||||
# as_es_winkel, as_seite, es_seite. Ein unbekannter Name
|
||||
# bricht NICHT ab, der Rohwert wird unveraendert
|
||||
# uebernommen (siehe sivas_mapping.anwenden).
|
||||
# Soll ein Merkmal ohne eigenes Attribut nur per Transform
|
||||
# entstehen, braucht die Zeile trotzdem den ":" vor dem
|
||||
# "|" ("WINKEL_AS : | as_es_vorhanden") - sonst gilt der
|
||||
# Transform-Name als Fallback-Attributname.
|
||||
# Transforms, die mit @braucht_attribs markiert sind
|
||||
# (as_seite/es_seite), sehen zusaetzlich alle uebrigen
|
||||
# Attribute des Blocks - noetig, wenn ein Merkmal von
|
||||
# einem ZWEITEN Attribut abhaengt (Seite nur, wenn der
|
||||
# zugehoerige Winkel ueberhaupt ein Element ausweist).
|
||||
#
|
||||
# Abschnittsnamen entsprechen den bisherigen build_*_details-Funktionen in
|
||||
# export_sivas.py: [gefaellestrecke], [kreisel], [eckrad], [geruest]. Die
|
||||
# geruest-typ-Anzeige-Tabelle (ASCII-Attributwert -> Sivas-Klartext mit
|
||||
# Umlauten) UND SEPARATOR_BEARBEITUNG_ANZEIGE bleiben eigene, kleine
|
||||
# Abschnitte weiter unten.
|
||||
# Anzeige-Tabellen (ASCII-Attributwert -> Sivas-Klartext/Optionswert:
|
||||
# [geruest_typ_anzeige], [as_es_winkel_anzeige]) UND
|
||||
# SEPARATOR_BEARBEITUNG_ANZEIGE bleiben eigene, kleine Abschnitte weiter
|
||||
# unten.
|
||||
#
|
||||
# [gefaellestrecke] und [variofoerderer] fuehren die AS-/ES-Merkmale
|
||||
# (4427-4432) absichtlich DOPPELT: GF_N- und VF_N-Bloecke tragen dieselben
|
||||
# Attribute des gemeinsamen Strecken-Schemas, und jeder Abschnitt soll fuer
|
||||
# sich lesbar bleiben. Aenderungen dort bitte in beiden nachziehen (der Test
|
||||
# tests/test_export_sivas_as_es.py::test_zuordnung_steht_in_der_config wacht
|
||||
# darueber).
|
||||
# ============================================================
|
||||
|
||||
[gefaellestrecke]
|
||||
2950= MONTAGEHOEHE_m : 0
|
||||
# AS-/ES-Element, Reihenfolge wie die Sivas-Hierarchie (identisch in
|
||||
# [variofoerderer]): 4431/4432 Ja/Nein schalten Winkel und Seite frei.
|
||||
4431= WINKEL_AS : | as_es_vorhanden
|
||||
4427= WINKEL_AS : | as_es_winkel
|
||||
4428= SEITE_AS : | as_seite
|
||||
4432= WINKEL_ES : | as_es_vorhanden
|
||||
4429= WINKEL_ES : | as_es_winkel
|
||||
4430= SEITE_ES : | es_seite
|
||||
4384= : Gefällestrecke
|
||||
4318= L_GF_m
|
||||
4391= GF_WINKEL
|
||||
@@ -79,12 +105,55 @@
|
||||
[geruest]
|
||||
Farbe= FARBE
|
||||
|
||||
[kettenfoerderer]
|
||||
# Kettenfoerderer / Schraegfoerderer Stahl (KF_n, Lisp/KettenFoerderer.lsp).
|
||||
# Merkmalnummern laut Merkmalstamm des Schraegfoerderers.
|
||||
#
|
||||
# 350 kommt aus FOERDERERTYP (Bauart im Klartext). Der Default greift nur
|
||||
# bei Altbestands-Bloecken ohne das Attribut.
|
||||
# 359 kommt aus WINKEL, das den Neigungswinkel als nackte Zahl fuehrt
|
||||
# ("26"/"30"); die Anzeige-Tabelle [kf_typ_anzeige] weiter unten macht
|
||||
# daraus den Sivas-Optionstext mit Gradzeichen. Grund fuer die
|
||||
# Zweiteilung: Block-Attribute bleiben laut Projektkonvention ASCII.
|
||||
# 353 (Anzahl der gleichen KF) steht ABSICHTLICH NICHT hier: der Wert
|
||||
# entsteht erst aus der Gruppierung baugleicher Bloecke
|
||||
# (kettenfoerderer_signature in export_sivas.py) und ist damit kein
|
||||
# flaches Attribut-Mapping - gleiche Bauart wie 3510/3512 beim Kreisel.
|
||||
# 356 und 361 nutzen den vorhandenen Transform ja_nein, die Attribute
|
||||
# fuehren "1"/"0".
|
||||
# 357 "Antriebsart" ist beim Kettenfoerderer FEST (1.1 kW): im Dialog ein
|
||||
# Dropdown mit genau einer, zwingend gewaehlten Option - das Attribut gibt es trotzdem, damit der Wert am
|
||||
# Block steht und nicht nur im Export auftaucht.
|
||||
# 354 "Farbe Foerderer" und 355 "Antriebsmotor Foerderer" sind ZWEI getrennte
|
||||
# Merkmale (nicht ein kombinierter Text) - im Dialog darum auch zwei
|
||||
# Felder, Attribute FARBE und ANTRIEBSMOTOR.
|
||||
# 354/355/391 tragen bereits den vollen Sivas-Optionstext im Attribut (die
|
||||
# Auswahllisten in data/json/kettenfoerderer.json liefern ihn so) -
|
||||
# darum kein Transform.
|
||||
350= FOERDERERTYP : Schrägförderer Stahl
|
||||
359= WINKEL : 26 | kf_typ_anzeige
|
||||
361= STANDARD_STEUERUNG : 0 | ja_nein
|
||||
354= FARBE : RAL 7035
|
||||
355= ANTRIEBSMOTOR : Europa 50 Hz
|
||||
357= ANTRIEBSART : 1.1 kW
|
||||
356= MOVIMOT : 0 | ja_nein
|
||||
360= H_EINBAUHOEHE_mm : 0
|
||||
391= VERBINDUNGSELEMENTE : Nein
|
||||
|
||||
[variofoerderer]
|
||||
# Nur die von der Segmentanzahl UNABHAENGIGEN Top-Level-Felder einer VF_N-
|
||||
# Streckengruppe (siehe build_variofoerderer_details in export_sivas.py).
|
||||
# Die Gefaelle-/Vario-Segmentpaare (4312-4392, 4353/4354/4386) haengen an der
|
||||
# Listenlaenge von L_GF_m/L_VF_m und bleiben Code.
|
||||
2950= MONTAGEHOEHE_m : 0
|
||||
# AS-/ES-Element, Reihenfolge wie die Sivas-Hierarchie (identisch in
|
||||
# [gefaellestrecke]): 4431/4432 Ja/Nein schalten Winkel und Seite frei.
|
||||
4431= WINKEL_AS : | as_es_vorhanden
|
||||
4427= WINKEL_AS : | as_es_winkel
|
||||
4428= SEITE_AS : | as_seite
|
||||
4432= WINKEL_ES : | as_es_vorhanden
|
||||
4429= WINKEL_ES : | as_es_winkel
|
||||
4430= SEITE_ES : | es_seite
|
||||
4329= GF_Bogen_L_90 : 0
|
||||
4330= GF_Bogen_L_60 : 0
|
||||
4331= GF_Bogen_L_30 : 0
|
||||
@@ -103,11 +172,35 @@ Farbe= FARBE
|
||||
3992= GERUEST_EINZELMODUL : 0 | ja_nein
|
||||
3993= GERUEST_TYP : Schoenenberger Geruest | geruest_typ_anzeige
|
||||
|
||||
[as_es_winkel_anzeige]
|
||||
# Attributwert WINKEL_AS/WINKEL_ES -> Optionswert der Sivas-Auswahlliste zu
|
||||
# Merkmal 4427/4429. Im Merkmalstamm heissen die Optionen "30 °"/"90 °" (mit
|
||||
# Leerzeichen vor dem Gradzeichen) - das Attribut in der Zeichnung bleibt die
|
||||
# nackte Zahl. Gleiche Bauart wie [geruest_typ_anzeige]: steht ein Winkel
|
||||
# hier NICHT drin, wird er unveraendert uebernommen.
|
||||
#
|
||||
# >>> Falls Sivas den Import mit "30 °" ablehnt, ist DIESE Tabelle die
|
||||
# >>> einzige Stelle zum Nachziehen (z.B. auf "30°" ohne Leerzeichen oder
|
||||
# >>> auf die nackte Zahl) - der Code bleibt unberuehrt.
|
||||
30= 30 °
|
||||
90= 90 °
|
||||
|
||||
[geruest_typ_anzeige]
|
||||
# ASCII-Attributwert (GERUEST_TYP) -> Sivas-Klartext mit Umlauten/Sonder-
|
||||
# zeichen (Attribute selbst bleiben ASCII, siehe CLAUDE.md-Konvention).
|
||||
Schoenenberger Geruest= Schönenberger-Gerüst
|
||||
|
||||
[kf_typ_anzeige]
|
||||
# Attributwert WINKEL (Neigungswinkel als nackte Zahl) -> Optionswert der
|
||||
# Sivas-Auswahlliste zu Merkmal 359. Gleiche Bauart wie
|
||||
# [geruest_typ_anzeige]/[as_es_winkel_anzeige]: steht ein Wert hier NICHT
|
||||
# drin, wird er unveraendert uebernommen.
|
||||
#
|
||||
# >>> Lehnt Sivas den Import ab, ist DIESE Tabelle die einzige Stelle zum
|
||||
# >>> Nachziehen (z.B. "26 °" mit Leerzeichen) - der Code bleibt unberuehrt.
|
||||
26= Schrägförderer Stahl 26°
|
||||
30= Schrägförderer Stahl 30°
|
||||
|
||||
[weichen]
|
||||
# ILS 2.0 Weiche (6216): eine Summenzeile, Werte aus den Kreisel-Beruehr-
|
||||
# punkten des LISP-Exports (kreisel_weichen.json). Ein Beruehrpunkt ist eine
|
||||
|
||||
@@ -8,7 +8,8 @@ der Wahrheit ist der Code in `lib/export_sivas.py` - diese Datei ist ein
|
||||
Backup/Nachschlagewerk, bei Aenderungen am Code bitte hier nachziehen.
|
||||
|
||||
Stand: abgeglichen mit `lib/export_sivas.py` nach der Umstellung von
|
||||
beschreibenden JSON-Keys auf reine Merkmalnummern (Sept. 2026).
|
||||
beschreibenden JSON-Keys auf reine Merkmalnummern (Sept. 2026), ergaenzt um
|
||||
die AS-/ES-Element-Merkmale 4427-4432 (Okt. 2026).
|
||||
|
||||
## ILS 2.0 Kreisel (SivasNr 6200, Dispogruppe 20)
|
||||
|
||||
@@ -59,6 +60,7 @@ immer 1. Sivas kennt je Streckengruppe nur EIN Gefaelle-Segment-Paar
|
||||
| 4381 | Streckengruppe - Anzahl der Separatoren - Variofoerderer | `ANZAHL_SEPARATOR` | **voller Blockwert** (Aufteilung noch offen, siehe 4337) |
|
||||
| 4382 | (dieselbe Bezeichnung wie 4338 im Merkmalstamm) | - | fest `SEPARATOR_BEARBEITUNG_ANZEIGE` |
|
||||
| 4383 | Streckengruppe - Anzahl der Scanner (Vario-Anteil) | `ANZAHL_SCANNER` | **voller Blockwert** |
|
||||
| 4427-4432 | AS-/ES-Element (vorhanden/Winkel/Seite) | `WINKEL_AS`/`SEITE_AS`/`WINKEL_ES`/`SEITE_ES` | siehe eigener Abschnitt unten |
|
||||
| 3992 | Geruest fuer Einzelmodul | `GERUEST_EINZELMODUL` | wie Kreisel |
|
||||
| 3993 | Geruestoption fuer Einzelmodul | `GERUEST_TYP` | wie Kreisel |
|
||||
|
||||
@@ -86,9 +88,56 @@ Stueckzahl der Gruppe steht im Merkmal 4311.
|
||||
| 4337 | Streckengruppe - Anzahl der Separatoren - Gefaellestrecke | `ANZAHL_SEPARATOR` | direkt (kein Split noetig, kein Vario-Anteil vorhanden) |
|
||||
| 4338 | Streckengruppe - Bearbeitung Gefaellestreckenteilstueck fuer Separator (829516050) | - | fest `SEPARATOR_BEARBEITUNG_ANZEIGE` |
|
||||
| 4339 | Streckengruppe - Anzahl der Scanner | `ANZAHL_SCANNER` | direkt |
|
||||
| 4427-4432 | AS-/ES-Element (vorhanden/Winkel/Seite) | `WINKEL_AS`/`SEITE_AS`/`WINKEL_ES`/`SEITE_ES` | siehe eigener Abschnitt unten |
|
||||
| 3992 | Geruest fuer Einzelmodul | `GERUEST_EINZELMODUL` | wie Kreisel |
|
||||
| 3993 | Geruestoption fuer Einzelmodul | `GERUEST_TYP` | wie Kreisel |
|
||||
|
||||
Die Gruppierung (`gefaellestrecke_signature`) beruecksichtigt AS-/ES-Element
|
||||
mit: zwei sonst baugleiche Gefaellestrecken mit AS links bzw. AS rechts
|
||||
bleiben getrennte Zeilen, sonst zeigte die gemeinsame Zeile nur die Seite des
|
||||
ersten Blocks.
|
||||
|
||||
## AS-/ES-Element (4427-4432) - gilt fuer VF_N UND GF_N
|
||||
|
||||
Die Zuordnung steht vollstaendig in `cfg/sivas.cfg` - mit denselben sechs
|
||||
Zeilen in `[gefaellestrecke]` UND `[variofoerderer]`, weil beide Blockarten
|
||||
dieselben Attribute des gemeinsamen Strecken-Schemas tragen
|
||||
(`*strecke-attr-front*` in `ssg_core.lsp`). In `export_sivas.py` stehen nur
|
||||
die Transform-Funktionen.
|
||||
|
||||
Sivas-Hierarchie (Merkmalstamm): 4431/4432 (`"Ja"`/`"Nein"`) sind die
|
||||
Oberknoten, Winkel und Seite haengen als Unterknoten darunter - darum auch
|
||||
diese Reihenfolge in der Config.
|
||||
|
||||
| Merkmalnr | Bezeichnung (Merkmalstamm) | Block-Attribut | Transform | Berechnung |
|
||||
|---|---|---|---|---|
|
||||
| 4431 | AS-Element | `WINKEL_AS` | `as_es_vorhanden` | `"Ja"`, wenn ein Winkel gesetzt ist, sonst `"Nein"` |
|
||||
| 4427 | AS-Element - Winkel | `WINKEL_AS` | `as_es_winkel` | Optionswert der Auswahlliste (`"30"` -> `"30 °"`, Tabelle `[as_es_winkel_anzeige]`); leer, wenn kein AS-Element |
|
||||
| 4428 | AS-Element - Seite | `SEITE_AS` | `as_seite` | kleingeschrieben (`"links"`/`"rechts"`); leer, wenn kein AS-Element |
|
||||
| 4432 | ES-Element | `WINKEL_ES` | `as_es_vorhanden` | wie 4431 |
|
||||
| 4429 | ES-Element - Winkel | `WINKEL_ES` | `as_es_winkel` | wie 4427 |
|
||||
| 4430 | ES-Element - Seite | `SEITE_ES` | `es_seite` | wie 4428 |
|
||||
|
||||
**Warum der Winkel ueber das Vorhandensein entscheidet und nicht die Seite:**
|
||||
das Schema laesst `WINKEL_AS`/`WINKEL_ES` leer, wenn kein Element gewaehlt
|
||||
wurde, waehrend `SEITE_AS`/`SEITE_ES` mit `"rechts"` immer einen Vorgabewert
|
||||
tragen. Ohne Element bleiben darum Winkel UND Seite leer - sonst stuende in
|
||||
Sivas eine Seite unter einem `"Nein"`-Knoten.
|
||||
|
||||
**Winkel-Schreibweise:** die Sivas-Auswahlliste fuehrt `"30 °"`/`"90 °"` (mit
|
||||
Leerzeichen vor dem Gradzeichen), das Block-Attribut dagegen die nackte Zahl.
|
||||
Die Uebersetzung steht als Tabelle `[as_es_winkel_anzeige]` in `sivas.cfg`
|
||||
(gleiche Bauart wie `[geruest_typ_anzeige]`) - weicht Sivas davon ab, ist das
|
||||
die einzige Stelle zum Nachziehen. Ein Winkel ohne Eintrag dort wird
|
||||
unveraendert uebernommen.
|
||||
|
||||
**Neu im Mapping-Mechanismus:** `4428`/`4430` brauchen ein ZWEITES Attribut
|
||||
(die Seite haengt am Winkel). Dafuer gibt es in `sivas_mapping.py` den
|
||||
Dekorator `@braucht_attribs` - ein so markierter Transform wird als
|
||||
`fn(wert, attribs)` statt `fn(wert)` aufgerufen und sieht damit die uebrigen
|
||||
Attribute des Blocks. Ohne diese Klammer muessten bedingte Merkmale wieder
|
||||
als Python-Code aus der Config herauswandern.
|
||||
|
||||
## ILS 2.0 Zusatzmodul (SivasNr 6215, Dispogruppe 20)
|
||||
|
||||
BTMT-Beladestationen UND Abwurfstationen (Klammerbuegel-Entladung) in EINER
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"kettenfoerderer": {
|
||||
"id": "Kettenfoerderer",
|
||||
"titel": "Kettenfoerderer (Schraegfoerderer Stahl)",
|
||||
"layer": "kettenfoerderer",
|
||||
"teileart": "Schraegfoerderer Stahl",
|
||||
"foerderertyp": "Schrägförderer Stahl",
|
||||
|
||||
"einbauhoehe": { "vorgabe": 1500, "min": 300, "max": 8000 },
|
||||
"laenge": { "min": 100, "max": 20000 },
|
||||
|
||||
"_hinweis_ansicht": "KF_2D liegt DECKUNGSGLEICH mit der Kette (KS_EIN auf KS_EIN der Umlenkung, KS_AUS auf KS_AUS des Antriebs) - die Baugruppe ist EIN Koerper. Den frueheren Versatz (versatz_y) gibt es nicht mehr, seit die Kette aufgerichtet eingebaut wird.",
|
||||
"ansicht_2d": { "block": "KF_2D" },
|
||||
|
||||
"_hinweis_antriebsart": "Merkmal 357 ist beim Kettenfoerderer FEST: die Liste hat genau EINEN Eintrag, der im Dialog als Dropdown erscheint und zwingend gewaehlt ist. Weitere Antriebsarten (z.B. 0.55 kW) waeren einfach eine weitere Zeile.",
|
||||
"antriebsart": [
|
||||
{ "name": "1.1 kW", "wert": "1.1 kW" }
|
||||
],
|
||||
|
||||
"farbe": [
|
||||
{ "name": "RAL 7035", "wert": "RAL 7035" },
|
||||
{ "name": "RAL 2000", "wert": "RAL 2000" },
|
||||
{ "name": "RAL 5018", "wert": "RAL 5018" },
|
||||
{ "name": "Sonderfarbe", "wert": "Sonderfarbe" }
|
||||
],
|
||||
|
||||
"antriebsmotor": [
|
||||
{ "name": "Europa 50 Hz", "wert": "Europa 50 Hz" }
|
||||
],
|
||||
|
||||
"movimot": [
|
||||
{ "name": "Nein", "wert": "0" },
|
||||
{ "name": "Ja", "wert": "1" }
|
||||
],
|
||||
|
||||
"standard_steuerung": [
|
||||
{ "name": "Nein", "wert": "0" },
|
||||
{ "name": "Ja", "wert": "1" }
|
||||
],
|
||||
|
||||
"verbindungselemente": [
|
||||
{ "name": "Verbindungselemente an AP", "wert": "Verbindungselemente an AP" },
|
||||
{ "name": "Verbindungselemente an ST", "wert": "Verbindungselemente an ST" },
|
||||
{ "name": "Nein", "wert": "Nein" }
|
||||
],
|
||||
|
||||
"varianten": [
|
||||
{
|
||||
"name": "Schraegfoerderer Stahl 26 Grad",
|
||||
"winkel": 26,
|
||||
"standard": true,
|
||||
"block_umlenkung": "KF_UM_26",
|
||||
"block_laenge": "KF_LAENGE",
|
||||
"block_antrieb": "KF_AN_26",
|
||||
"sivas_id": "6120"
|
||||
},
|
||||
{
|
||||
"name": "Schraegfoerderer Stahl 30 Grad",
|
||||
"winkel": 30,
|
||||
"block_umlenkung": "KF_UM_30",
|
||||
"block_laenge": "KF_LAENGE",
|
||||
"block_antrieb": "KF_AN_30",
|
||||
"sivas_id": "6120"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,52 @@
|
||||
// ============================================================
|
||||
// jam_edit.dcl - Staubereich bearbeiten
|
||||
// Aendert Foerderer und laufende Nummer eines JAM_AREA-Blocks, den die
|
||||
// Beschriftung aus sps_skel (lib/tro_annotate.py --anlage) eingefuegt hat.
|
||||
// Aufruf ueber c:JAM_EDIT (Lisp/Jam_Edit.lsp).
|
||||
// ============================================================
|
||||
|
||||
jam_edit : dialog {
|
||||
label = "Staubereich bearbeiten";
|
||||
|
||||
: column {
|
||||
|
||||
: text {
|
||||
key = "bereich";
|
||||
label = "";
|
||||
width = 50;
|
||||
}
|
||||
|
||||
: edit_box {
|
||||
key = "conveyor";
|
||||
label = "Foerderer (NNNN):";
|
||||
edit_width = 8;
|
||||
}
|
||||
|
||||
: edit_box {
|
||||
key = "number";
|
||||
label = "Laufende Nummer:";
|
||||
edit_width = 8;
|
||||
}
|
||||
|
||||
: row {
|
||||
: text {
|
||||
key = "auto";
|
||||
label = "";
|
||||
width = 30;
|
||||
}
|
||||
: button {
|
||||
key = "reset";
|
||||
label = "Abgeleitet uebernehmen";
|
||||
}
|
||||
}
|
||||
|
||||
: text {
|
||||
key = "hinweis";
|
||||
label = "";
|
||||
width = 50;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ok_cancel;
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
// ============================================================
|
||||
// kettenfoerderer.dcl - Kettenfoerderer (Schraegfoerderer Stahl)
|
||||
// Verwendet von KettenFoerderer.lsp (kf-dialog, Befehl KETTENFOERDERER).
|
||||
//
|
||||
// VORLAGE mit Markerzeilen: nur der Varianten-Block ist datenabhaengig und
|
||||
// wird zur Laufzeit an //@VARIANTEN@ eingesetzt (kf-dcl-ersetzungen ->
|
||||
// ssg-dcl-vorlage-fuellen in ssg_core, Temp-Datei). Grund: DCL kann
|
||||
// radio_button-Tiles weder zur Laufzeit erzeugen noch ihre Labels per
|
||||
// set_tile aendern - gleiches Vorgehen wie geruest_traeger.dcl.
|
||||
//
|
||||
// Varianten bewusst als Radiobuttons statt popup_list: es sind nur zwei
|
||||
// Werte (26/30 Grad), beide sollen ohne Aufklappen sichtbar sein.
|
||||
// Die Gruppenbeschriftung steht am boxed_row - ein zusaetzliches Label am
|
||||
// Tile waere doppelt gemoppelt.
|
||||
//
|
||||
// Die Beschriftungen folgen dem Sivas-Merkmalstamm, damit Dialog und
|
||||
// Stueckliste dieselbe Sprache sprechen (Merkmalnummer in Klammern):
|
||||
// Schraegfoerderer Stahl Typ (359) H - Einbauhoehe Schraegfoerderer (360)
|
||||
// Farbe Foerderer (354) Antriebsmotor Foerderer (355)
|
||||
// Antrieb mit Movimot (356) Verbindungselemente (391)
|
||||
// Farbe und Antriebsmotor sind dabei ZWEI eigenstaendige Merkmale
|
||||
// (Attribute FARBE und ANTRIEBSMOTOR), nicht ein kombinierter Text.
|
||||
//
|
||||
// Kein Geruest-Bereich: der Kettenfoerderer traegt sich selbst.
|
||||
// ============================================================
|
||||
|
||||
kettenfoerderer : dialog {
|
||||
label = "Kettenfoerderer";
|
||||
width = 62;
|
||||
|
||||
: boxed_radio_row {
|
||||
key = "variante";
|
||||
label = "Schraegfoerderer Stahl Typ";
|
||||
//@VARIANTEN@
|
||||
}
|
||||
|
||||
: boxed_column {
|
||||
label = "Geometrie";
|
||||
|
||||
: row {
|
||||
: edit_box {
|
||||
key = "hoehe";
|
||||
label = "H - Einbauhoehe Schraegfoerderer [ mm ]:";
|
||||
edit_width = 12;
|
||||
}
|
||||
// Zweite Eingabeart: Hoehe aus zwei gewaehlten Punkten messen.
|
||||
// Der Knopf schliesst den Dialog (done_dialog 2), der Aufrufer pickt
|
||||
// die Punkte und zeigt ihn mit dem Ergebnis erneut - aus einem
|
||||
// action_tile heraus laesst sich kein getpoint aufrufen.
|
||||
: button {
|
||||
key = "hoehe_messen";
|
||||
label = "aus 2 Punkten messen";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
: boxed_column {
|
||||
label = "Ausfuehrung";
|
||||
|
||||
// Reihenfolge wie im Sivas-Merkmalstamm: 361 vor 354 - Dialog,
|
||||
// Attributschema und Merkmalstamm bleiben damit in derselben Folge.
|
||||
: popup_list {
|
||||
key = "standard_steuerung";
|
||||
label = "mit Standard Steuerung:";
|
||||
width = 40;
|
||||
}
|
||||
|
||||
: popup_list {
|
||||
key = "farbe";
|
||||
label = "Farbe Foerderer:";
|
||||
width = 40;
|
||||
}
|
||||
|
||||
: popup_list {
|
||||
key = "antriebsmotor";
|
||||
label = "Antriebsmotor Foerderer:";
|
||||
width = 40;
|
||||
}
|
||||
|
||||
// Antriebsart (Merkmal 357): Dropdown mit genau EINER Option, die immer
|
||||
// gewaehlt ist - beim Kettenfoerderer ist sie fest 1.1 kW. Als Dropdown
|
||||
// statt als Textzeile, damit alle Merkmale gleich aussehen; kommt spaeter
|
||||
// eine zweite Antriebsart dazu, ist es nur eine weitere Zeile in der JSON.
|
||||
: popup_list {
|
||||
key = "antriebsart";
|
||||
label = "Antriebsart 0,55 / 1,1 kW:";
|
||||
width = 40;
|
||||
}
|
||||
|
||||
: popup_list {
|
||||
key = "movimot";
|
||||
label = "Antrieb mit Movimot:";
|
||||
width = 40;
|
||||
}
|
||||
|
||||
: popup_list {
|
||||
key = "verbindung";
|
||||
label = "Verbindungselemente:";
|
||||
width = 40;
|
||||
}
|
||||
}
|
||||
|
||||
ok_cancel;
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
// ============================================================
|
||||
// stueckliste.dcl - Optionen fuer Positionen + Stueckliste
|
||||
// Aufruf ueber c:SSG_FAEHNCHEN_STUECKLISTE (Lisp/ssg_stueckliste.lsp,
|
||||
// ssg-sl-dialog). Vorbelegung aus cfg/stueckliste.json bzw. dem letzten Lauf.
|
||||
// ============================================================
|
||||
|
||||
stueckliste : dialog {
|
||||
label = "Positionen + Stueckliste";
|
||||
|
||||
: boxed_column {
|
||||
label = "Layer der Positionen";
|
||||
: radio_column {
|
||||
key = "modus";
|
||||
: radio_button { key = "m_suffix"; label = "Bauteil-Layer + Suffix"; }
|
||||
: radio_button { key = "m_fest"; label = "Fester Layer"; }
|
||||
}
|
||||
: edit_box { key = "suffix"; label = "Suffix:"; edit_width = 20; }
|
||||
: edit_box { key = "fest"; label = "Fester Layer:"; edit_width = 20; }
|
||||
: text { label = "Regeln je Bauteiltyp: cfg/stueckliste.json"; }
|
||||
}
|
||||
|
||||
: boxed_column {
|
||||
label = "Stueckliste";
|
||||
: edit_box { key = "tab_layer"; label = "Tabellen-Layer:"; edit_width = 20; }
|
||||
: edit_box { key = "titel"; label = "Titel:"; edit_width = 30; }
|
||||
}
|
||||
|
||||
: boxed_column {
|
||||
label = "Nummerierung / Darstellung";
|
||||
: edit_box { key = "startnr"; label = "Erste Positionsnummer:"; edit_width = 10; }
|
||||
: edit_box { key = "faktor"; label = "Massstabsfaktor:"; edit_width = 10; }
|
||||
: toggle { key = "alle_pos";
|
||||
label = "Alle Positionen in der Fahne (100|101|...), jede Art.-Nr. nummeriert"; }
|
||||
}
|
||||
|
||||
: errtile { key = "error"; }
|
||||
ok_cancel;
|
||||
}
|
||||
+118
-7
@@ -181,6 +181,84 @@ vflw_as : dialog {
|
||||
}
|
||||
}
|
||||
|
||||
// Wie vflw_as, aber ZUSAETZLICH mit der Zufuehrungsachse (2. Punkt) in
|
||||
// DEMSELBEN Bildschirm - nur fuer das AS-Element am Kettenanfang von Modus 1
|
||||
// (Nutzer-Vorgabe 2026-10-21: "Achse und links/rechts gehoeren in ein
|
||||
// Fenster", beide zusammen legen AS-Lage UND Kettenrichtung fest: der 2.
|
||||
// Punkt gibt die KS_EIN-Achse, links/rechts die AS-Variante und damit die
|
||||
// KS_AUS-Richtung). Eigener Dialog statt einer dauerhaft ausgegrauten
|
||||
// Punkt-Zeile in vflw_as - denselben Dialog nutzt auch das ES-Element am
|
||||
// Kettenende, wo es gar keine Zufuehrungsachse gibt (gleiche Begruendung wie
|
||||
// bei vflw_winkel_seite vs. vflw_winkel_seite_30_90).
|
||||
// Punktwahl-Zeile nach dem Muster von vflw_punkt_zahl: der Button schliesst
|
||||
// den Dialog (done_dialog 2), danach laeuft (getpoint) auf der
|
||||
// Kommandozeile, danach wird der Dialog neu gezeigt - darum nutzt "back"
|
||||
// hier Code 3.
|
||||
vflw_as_achse : dialog {
|
||||
label = "VarioFoerderer Assistent";
|
||||
|
||||
: column {
|
||||
: text {
|
||||
key = "kopf";
|
||||
label = "";
|
||||
width = 60;
|
||||
}
|
||||
: toggle {
|
||||
key = "setzen";
|
||||
label = "Ja, setzen";
|
||||
}
|
||||
: boxed_radio_column {
|
||||
label = "Winkel:";
|
||||
key = "winkel";
|
||||
: radio_button { key = "winkel_90"; label = "90 Grad"; value = "1"; }
|
||||
: radio_button { key = "winkel_30"; label = "30 Grad"; }
|
||||
}
|
||||
// Beschriftungen bewusst NEUTRAL: derselbe Dialog dient dem AS-Element
|
||||
// am Kettenanfang (vorwaerts) UND dem ES-Element am Kettenende
|
||||
// (rueckwaerts bauen, 2026-10-22). Welches Element gemeint ist, sagt die
|
||||
// Kopfzeile ("kopf").
|
||||
: boxed_radio_column {
|
||||
label = "Seite (Element schleust nach):";
|
||||
key = "seite";
|
||||
: radio_button { key = "seite_links"; label = "Links"; value = "1"; }
|
||||
: radio_button { key = "seite_rechts"; label = "Rechts"; }
|
||||
}
|
||||
: boxed_column {
|
||||
label = "Fahrtrichtung (2. Punkt):";
|
||||
// Startpunkt der Kette - er ist der Sitz des AS-Elements UND der
|
||||
// Ausgangspunkt der Achse; waehrend der Punktwahl haengt das
|
||||
// Gummiband an ihm (vfl-getpoint mit Basispunkt).
|
||||
: text {
|
||||
key = "start_anzeige";
|
||||
label = "";
|
||||
width = 46;
|
||||
}
|
||||
: row {
|
||||
: button {
|
||||
key = "pick";
|
||||
label = "2. Punkt waehlen...";
|
||||
fixed_width = true;
|
||||
width = 20;
|
||||
}
|
||||
: text {
|
||||
key = "pt_anzeige";
|
||||
label = "(ohne Achse: Richtung aus dem naechsten Klick)";
|
||||
width = 46;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
: row {
|
||||
alignment = centered;
|
||||
: button { key = "back"; label = "Zurueck"; fixed_width = true; width = 12; }
|
||||
spacer;
|
||||
: button { key = "accept"; label = "Ok Weiter"; is_default = true; fixed_width = true; width = 12; }
|
||||
spacer;
|
||||
: button { key = "cancel"; label = "Abbrechen"; is_cancel = true; fixed_width = true; width = 12; }
|
||||
}
|
||||
}
|
||||
|
||||
// Winkel (30/60/90) + Seite - fuer GF-Bogen, wo alle drei Winkel geometrisch
|
||||
// gueltig sind. Fuer AS-/ES-Element (wo 60 Grad NIE gueltig ist) stattdessen
|
||||
// vflw_winkel_seite_30_90 verwenden (siehe vflw-gruppe-winkel-seite-impl/
|
||||
@@ -402,6 +480,12 @@ vflw_gf_laenge_modus : dialog {
|
||||
: radio_button { key = "modus_hoehe"; label = "Zielhoehe festlegen (Laenge wird berechnet)"; }
|
||||
: radio_button { key = "modus_steigend"; label = "Steigende GF (Sonderfall, bis 3 Grad)"; }
|
||||
: radio_button { key = "modus_qc"; label = "QC Linie mit GF (automatische Auf-Ab-Berechnung)"; }
|
||||
// Nur am Kettenanfang mit AS-Element UND festgelegter Zufuehrungsachse
|
||||
// waehlbar - sonst fehlt die Bezugsachse fuer den Abstand. Wird in
|
||||
// vflw-gruppe-gf-laenge-modus-impl per mode_tile deaktiviert (anders
|
||||
// als eine NIE waehlbare Kachel ist diese kontextabhaengig, siehe
|
||||
// "sepnach" in vflw_sep_gf).
|
||||
: radio_button { key = "modus_parallel"; label = "Parallel zum Kreisel weiterbauen (Abstand)"; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,9 +547,19 @@ vflw_sep_gf : dialog {
|
||||
key = "sepvor";
|
||||
label = "Separator VOR dieser Gefaellestrecke";
|
||||
}
|
||||
: toggle {
|
||||
key = "sepnach";
|
||||
label = "Separator NACH dieser Gefaellestrecke";
|
||||
// Steht am Kettenende ein ES-Element, ist "Separator NACH" gesperrt -
|
||||
// der Hinweis dahinter sagt warum, in EINER Zeile mit dem Ankreuzfeld
|
||||
// (gleiche Anordnung wie in vflw_seg_linie_m2). Sonst leer (set_tile "").
|
||||
: row {
|
||||
: toggle {
|
||||
key = "sepnach";
|
||||
label = "Separator NACH dieser Gefaellestrecke";
|
||||
}
|
||||
: text {
|
||||
key = "sephinweis";
|
||||
label = "";
|
||||
width = 62;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1006,7 +1100,13 @@ vflw_seg_linie_m2 : dialog {
|
||||
: boxed_column {
|
||||
label = "Separator (nur bei GF):";
|
||||
: toggle { key = "sep_vor"; label = "Separator VOR diesem GF-Stueck"; }
|
||||
: toggle { key = "sep_nach"; label = "Separator NACH diesem GF-Stueck"; }
|
||||
// Begruendung, wenn "NACH" gesperrt ist (ES folgt direkt), in EINER
|
||||
// Zeile hinter dem Ankreuzfeld - sonst liest sie sich wie eine eigene
|
||||
// Aussage statt wie die Erklaerung zu genau diesem Feld. Sonst leer.
|
||||
: row {
|
||||
: toggle { key = "sep_nach"; label = "Separator NACH diesem GF-Stueck"; }
|
||||
: text { key = "sephinweis"; label = ""; width = 62; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1116,13 +1216,24 @@ vflw_m2_lauf_anfang : dialog {
|
||||
label = "";
|
||||
width = 60;
|
||||
}
|
||||
// Reihenfolge nach Haeufigkeit (Nutzer-Wunsch 2026-10-23): der
|
||||
// Regelfall zuerst, der Sonderfall "offener Anfang" zuletzt. Die
|
||||
// radio_button-KEYS bleiben dabei unveraendert; journalisiert wird der
|
||||
// am Key haengende WERT ("mit-gf1"/"direkt"/"ohne", siehe
|
||||
// vfl-m2-anfang-norm), nicht die Position - Umsortieren und Umnummerieren
|
||||
// sind damit folgenlos fuer bestehende Ketten.
|
||||
: boxed_radio_column {
|
||||
label = "Lauf beginnen mit:";
|
||||
key = "anfang";
|
||||
: radio_button { key = "anfang_offen"; label = "Ohne Umlenkstation (offener Anfang, spaeter fortsetzen)"; }
|
||||
: radio_button { key = "anfang_umlenk"; label = "Umlenkstation direkt (kein GF1/Separator)"; }
|
||||
: radio_button { key = "anfang_umlenk_gf1"; label = "Umlenkstation mit GF1 + Separator"; value = "1"; }
|
||||
// Nummern wie in der Konsolenausgabe, damit Dialog und Protokoll
|
||||
// dieselbe Option gleich benennen.
|
||||
: radio_button { key = "anfang_umlenk_gf1"; label = "1 - Umlenkstation mit GF1 + Separator"; value = "1"; }
|
||||
: radio_button { key = "anfang_umlenk"; label = "2 - Umlenkstation direkt (kein GF1/Separator)"; }
|
||||
: radio_button { key = "anfang_offen"; label = "3 - Ohne Umlenkstation (offener Anfang, spaeter fortsetzen/verschmelzen)"; }
|
||||
}
|
||||
// Begruendung, wenn "Ohne Umlenkstation" gesperrt ist (AS gesetzt).
|
||||
// Breit genug fuer den vollen Satz - bei width = 60 wurde er abgeschnitten.
|
||||
: text { key = "anfanghinweis"; label = ""; width = 76; }
|
||||
}
|
||||
|
||||
ok_cancel;
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
# Datenaufbereitung der CAD-Bausteine
|
||||
|
||||
Kurzanleitung fuer alle, die neue CAD-Modelle (DWG/DXF-Bausteine) fuer die
|
||||
SSG_LIB-Makros anlegen oder bestehende ersetzen.
|
||||
|
||||
Hier finden Sie Antworten auf folgende Fragen:
|
||||
|
||||
1. [Wo sind Koordinatensysteme anzusetzen?](#1-wo-sind-koordinatensysteme-anzusetzen)
|
||||
2. [Wie muessen sie heissen?](#2-wie-muessen-die-koordinatensysteme-heissen)
|
||||
3. [Wie werden 3D-Modelle anhand der 2.5D-Skelette platziert?](#3-grundidee-platzierung-ueber-das-25d-skelett)
|
||||
4. [Wo und wie werden die Dateien abgelegt?](#4-datenablage-und-benennung)
|
||||
|
||||
Am Ende steht eine [Checkliste](#5-checkliste-fuer-ein-neues-modell).
|
||||
|
||||
---
|
||||
|
||||
## 1. Wo sind Koordinatensysteme anzusetzen?
|
||||
|
||||
Ein Koordinatensystem (KS) markiert einen **Anschlusspunkt**: die Stelle, an
|
||||
der ein Baustein an seinen Vorgaenger bzw. Nachfolger andockt. Es sitzt
|
||||
immer **auf der Mittellinie der Foerderstrecke** (dem Skelett, siehe
|
||||
Abschnitt 3), genau am Uebergang zum Nachbarteil.
|
||||
|
||||
**Aufbau eines KS** - ein kleiner Block mit drei LINEs, alle ab demselben
|
||||
Ursprung:
|
||||
|
||||
| Achse | Farbe | Laenge | Richtung |
|
||||
|---|---|---|---|
|
||||
| X | rot (1) | 1 | Foerderrichtung (bzw. Anschlussrichtung, siehe unten) |
|
||||
| Y | gruen (3) | 2 | quer dazu, nach links |
|
||||
| Z | blau (5) | 3 | nach oben, aus der Zeichenebene |
|
||||
|
||||
Die Makros erkennen die Achsen **nur an der Linienlaenge** (1 = X, 2 = Y,
|
||||
3 = Z; X darf auch 100 lang sein). Farben dienen nur der Lesbarkeit. Der
|
||||
KS-Block liegt auf Layer `_KOORDINATENSYSTEME` und muss **direkt** (eine
|
||||
Ebene tief) im Baustein eingefuegt sein, nicht in einem weiteren Unterblock.
|
||||
|
||||
### ILS-Kettenbausteine (Vario, Gefaelle, AS/ES, Staustrecke, Separator ...)
|
||||
|
||||
- **`KS_EIN`** am Einlauf, **`KS_AUS`** am Auslauf.
|
||||
- Bei **beiden** zeigt die X-Achse **in Foerderrichtung**. Beim Verketten
|
||||
kommt das `KS_EIN` des Nachfolgers auf das `KS_AUS` des Vorgaengers; die
|
||||
Richtung des Folgebausteins wird aus der X-Achse von `KS_AUS` gemessen
|
||||
(z.B. beim Kettenfoerderer).
|
||||
- Laengenvariable Teile (Staustrecke, `KF_LAENGE`) liegen entlang **+X** und
|
||||
werden in X skaliert - `KS_EIN` bei X=0, `KS_AUS` am Ende der
|
||||
Referenzlaenge (z.B. 1000 mm).
|
||||
|
||||
### Omniflo-Boegen und -Weichen
|
||||
|
||||
- Anschluss-KS heissen **`K1` bis `K4`**. Die X-Achse zeigt jeweils **in
|
||||
das Element hinein** (tangential zur Linie).
|
||||
- Zuordnung:
|
||||
|
||||
| KS | Boegen | Weichen |
|
||||
|---|---|---|
|
||||
| K1 | Beginn der obersten waagerechten Linie, X nach rechts | Beginn der untersten senkrechten Linie, X nach oben |
|
||||
| K2 | anderes Kettenende | Ende des linken Bogenzweigs |
|
||||
| K3 | - | Ende des rechten Bogenzweigs (nur bei 2+ Boegen) |
|
||||
| K4 | - | oberes Ende der K1-Linie (nicht bei Doppel-/Dreifach-/Deltaweiche) |
|
||||
|
||||
- K1-K4 muessen nicht von Hand gezeichnet werden: `lib/set_koords.py --set-all`
|
||||
setzt sie geometrisch, vorher setzt `bin\set_einfuegepunkt.bat`
|
||||
(`lib/set_einfuegepkt.py`) den Einfuegepunkt. Details: [tools.md](tools.md).
|
||||
|
||||
### Bausteine ohne KS
|
||||
|
||||
Einzeln frei platzierte Teile (Kreisel-Raeder `AN8`/`SP8`, BTMT-Stationen,
|
||||
Scanner, Eingang/Ausgang, Geruestteile) brauchen kein KS. Hier zaehlt nur
|
||||
der **Einfuegepunkt** (Basispunkt der DWG), siehe Abschnitt 3.
|
||||
|
||||
---
|
||||
|
||||
## 2. Wie muessen die Koordinatensysteme heissen?
|
||||
|
||||
| Name | Verwendung |
|
||||
|---|---|
|
||||
| `KS_EIN` | Einlauf eines ILS-Kettenbausteins |
|
||||
| `KS_AUS` | Auslauf eines ILS-Kettenbausteins |
|
||||
| `K1` ... `K4` | Anschluesse von Omniflo-Boegen/-Weichen |
|
||||
|
||||
- Genau diese Schreibweise, **ohne** `_2D`/`_3D`-Suffix (die KS-Bloecke sind
|
||||
dimensionsunabhaengig und in 2D- und 3D-Variante identisch).
|
||||
- Je Baustein jedes KS **nur einmal**.
|
||||
- `KSYS_EIN`/`KSYS_AUS` werden aus Altbestaenden noch gelesen, fuer neue
|
||||
Modelle aber nicht mehr verwenden.
|
||||
|
||||
---
|
||||
|
||||
## 3. Grundidee: Platzierung ueber das 2.5D-Skelett
|
||||
|
||||
**Skelett** = die Mittellinie der Foerderstrecke als einfache Linien/Boegen.
|
||||
"2.5D", weil es eine flache Grundriss-Geometrie ist, deren Punkte zusaetzlich
|
||||
eine Hoehe (Z) tragen - keine echte 3D-Konstruktion.
|
||||
|
||||
Das Prinzip hat zwei Seiten:
|
||||
|
||||
**a) Im Baustein selbst** ist das Skelett die Bezugsgeometrie:
|
||||
|
||||
- Die 2D-Variante *ist* das Skelett (plus Symbolik).
|
||||
- Das 3D-Modell enthaelt **dieselben 2D-Skelettlinien** in seiner
|
||||
Grundebene. Einfuegepunkt und KS liegen auf diesem Skelett - deshalb
|
||||
sind sie in 2D- und 3D-Variante **deckungsgleich** und die Varianten
|
||||
beliebig austauschbar. Die Omniflo-Werkzeuge (`set_einfuegepkt.py`,
|
||||
`set_koords.py`) werten genau diese Skelettlinien aus; ohne sie
|
||||
funktionieren sie bei 3D-Dateien nicht.
|
||||
- Gezeichnet wird in der Lage "Foerderrichtung = +X, Z nach oben". Einzige
|
||||
Ausnahme: aufrecht eingebaute Teile wie der Kettenfoerderer (`KF_*`)
|
||||
sind in XY gezeichnet (Y = Hoehe) und werden vom Makro aufgerichtet.
|
||||
|
||||
**b) In der Anlage** liefert der Anwender bzw. das Makro das Skelett
|
||||
(geklickte Punkte, gezeichneter Linienzug, Hoehen). Die Makros setzen die
|
||||
Bausteine darauf nacheinander:
|
||||
|
||||
1. `KS_EIN` des Bausteins auf den aktuellen Skelettpunkt legen.
|
||||
2. Drehen: um Z nach der Grundriss-Richtung des Segments, um Y nach dessen
|
||||
Neigung (Rz * Ry).
|
||||
3. Laengenteile in X auf die Segmentlaenge skalieren.
|
||||
4. Weltlage von `KS_AUS` lesen = Startpunkt des naechsten Bausteins.
|
||||
|
||||
Freistehende Teile ohne KS werden nur mit Einfuegepunkt + Drehung gesetzt
|
||||
(z.B. `AN8` mit dem Basispunkt in der Radmitte).
|
||||
|
||||
Weil 3D-Modell und 2D-Symbol am selben Skelett haengen, kann jede Anlage
|
||||
wahlweise in 2D oder 3D aufgebaut und spaeter umgeschaltet werden.
|
||||
|
||||
---
|
||||
|
||||
## 4. Datenablage und Benennung
|
||||
|
||||
Grundregeln:
|
||||
|
||||
- **Eine Datei je Baustein**, Dateiname = Blockname.
|
||||
- Namen nur **ASCII, ohne Umlaute und Leerzeichen** (`ae`/`oe`/`ue`, `_`
|
||||
als Trenner).
|
||||
- Der Basispunkt der DWG ist der Einfuegepunkt (s. Abschnitt 3).
|
||||
|
||||
| Bereich | Ablage | Benennung |
|
||||
|---|---|---|
|
||||
| ILS (Kreisel, Vario, Gefaelle, AS/ES, Stationen, Sensoren) | `data/ils/` **flach** | `<Name>_2D.dwg` und `<Name>_3D.dwg`, z.B. `AS_Element_30_links_3D.dwg`. Fehlt die 2D-Datei, wird automatisch die 3D-Datei genommen |
|
||||
| Omniflo-Boegen/-Weichen | `data/omniflo/2D/` bzw. `data/omniflo/3D/` | Sivas-Nummer, `.dxf`, z.B. `821104024.dxf`; Kombinationen mit `+`, z.B. `821104024+0_B10081.dxf` |
|
||||
| Omniflo-Verbinder | `data/omniflo/Verbinder/` | dimensionsunabhaengig, z.B. `TV_AP60-ST_kpl.dwg` |
|
||||
| Kettenfoerderer | `data/omniflo/2D/` | ohne Suffix: `KF_UM_26`, `KF_AN_30`, `KF_LAENGE`, `KF_2D` |
|
||||
| Geruest | `data/geruest/` | Artikelnummer, z.B. `821006031.dwg`; Platzhalter `dummy_*.dwg` |
|
||||
| DIN-Rahmen/Schriftkoepfe | `cfg/rahmen/` | `A0.DWG` ... `Kopf11.dwg` |
|
||||
|
||||
**Zugehoerige Daten** (Masse, Sivas-/Artikelnummern, Auswahllisten) liegen
|
||||
nicht in der DWG, sondern in `data/json/` - z.B. `omniflo_boegen.json`,
|
||||
`omniflo_weichen.json`, `geruest.json`, `kettenfoerderer.json`. Ein neues
|
||||
Omniflo- oder Geruestteil ist erst auswaehlbar, wenn es dort eingetragen ist.
|
||||
|
||||
**Attribute und Layer:**
|
||||
|
||||
- Bloecke, die nur eingefuegt werden, tragen ihren Ziel-Layer als Attribut
|
||||
**`LAYER`** (Vorgaben je Block in `data/ils/allocations.json`, z.B.
|
||||
`AN8_2D` -> `ILS_ANTR`, `AN8_3D` -> `_3D_ILS_ANTR`).
|
||||
- Ein leeres **`ID`**-Attribut mit anlegen - nur dann kann die automatische
|
||||
ID-Vergabe fuer den Export es befuellen.
|
||||
- Omniflo-Teile brauchen fuer den Export `TEILEART` (`Omniflo ...`) und
|
||||
`ARTINR`.
|
||||
- Layer/Farbe zusammengebauter Baugruppen (`KREISEL_n`, `VF_n`, `GF_n`)
|
||||
stehen nicht im Modell, sondern in `cfg/layer.cfg`.
|
||||
|
||||
---
|
||||
|
||||
## 5. Checkliste fuer ein neues Modell
|
||||
|
||||
- [ ] Dateiname nach Tabelle in Abschnitt 4, ASCII, im richtigen Ordner
|
||||
- [ ] ILS: 2D- **und** 3D-Variante, Basispunkt und KS deckungsgleich
|
||||
- [ ] 3D-Modell enthaelt die 2D-Skelettlinien
|
||||
- [ ] Foerderrichtung entlang +X, Z nach oben
|
||||
- [ ] Kettenbaustein: `KS_EIN`/`KS_AUS` direkt im Block, X in Foerderrichtung,
|
||||
Achslaengen 1/2/3
|
||||
- [ ] Omniflo: `set_einfuegepkt.py` und `set_koords.py --set-all` gelaufen,
|
||||
Kontrolle per `--show-omniflo`
|
||||
- [ ] Attribute `LAYER` und leeres `ID` vorhanden (Omniflo zusaetzlich
|
||||
`TEILEART`, `ARTINR`)
|
||||
- [ ] Eintrag in der passenden JSON unter `data/json/` bzw. `allocations.json`
|
||||
- [ ] In BricsCAD einmal ueber das Menue einfuegen/verketten und pruefen,
|
||||
dass der Anschluss sauber sitzt
|
||||
@@ -7,8 +7,7 @@ und die Treiber in `tests/test_*.lsp`, die sie lesen.
|
||||
|
||||
Die zugehoerigen LISP-Routinen mit Signaturen stehen in
|
||||
[lisp_methods.md](lisp_methods.md). Diese Seite ersetzt das fruehere
|
||||
`tests/testdata/object_data.md` (geloescht in Commit `e147b89`, auf das Code-
|
||||
Kommentare teilweise noch verweisen).
|
||||
`tests/testdata/object_data.md` (geloescht in Commit `e147b89`).
|
||||
|
||||
**Feldnamen als Python-Konstanten**: `lib/testdata_schema.py` buendelt die
|
||||
Feldnamen/festen Werte der Abschnitte 1 (Kreisel), 2 (Einzelbloecke), 3 (VF
|
||||
|
||||
+34
-7
@@ -37,7 +37,9 @@ Gross-/Kleinschreibung spielt an der Kommandozeile keine Rolle.
|
||||
| `KreiselLabelSetup` | Beschriftung einstellen (Hoehe, Farbe, Abstand, Schriftart) |
|
||||
| `KreiselLabelPos` | Versatz der Beschriftung (dx/dy) einstellen |
|
||||
| `KreiselLabelHoehe` | Texthoehe der Beschriftung einstellen |
|
||||
| `ILS_Eckrad` | Eckrad an einem Tangentenpunkt mit Richtung einfuegen |
|
||||
| `ILS_Eckrad` | Eckrad einfuegen (Dialog `eckrad_edit.dcl`, ohne GUI Konsolen-Rueckfall) |
|
||||
| `EckradEdit` | Bestehendes Eckrad per Dialog bearbeiten (auch per Doppelklick) |
|
||||
| `KREISEL_WEICHEN` | Beruehrpunkte/Weichen und Kollisionen aller Kreisel/Eckraeder gleicher Hoehe ermitteln, Marker setzen |
|
||||
|
||||
### VarioFoerderer (`VarioFoerderer.lsp` -> `vf_core`/`vf_standard`/`vf_etage`/`vf_linienzug`/`vf_spec`)
|
||||
|
||||
@@ -97,18 +99,28 @@ Gross-/Kleinschreibung spielt an der Kommandozeile keine Rolle.
|
||||
| `OMNI_WKomb_Delta_1400`, `OMNI_WKomb_Delta_1600`, `OMNI_WKomb_Star` | Weichenkombinationen (Delta, Stern) |
|
||||
| `OMNI_APBW_R400_45_140`, `OMNI_APBW_R400_675_260`, `OMNI_APBW_R550_45_77`, `OMNI_APBW_R550_45_194`, `OMNI_APBW_R550_225_360`, `OMNI_APBW_R550_225_410A`/`B`/`C`, `OMNI_APBW_R550_675_58`/`_125`/`_208`/`_360`, `OMNI_APBW_R650_90_300`, `OMNI_APBW_R750_90_200` | Boegen fuer Weichen (fest, ohne Dialog) |
|
||||
| `OMNI_TEF_UmlenkL`/`R`, `OMNI_TEF_AntriebL`/`R`, `OMNI_TEF_Gerade` | TEF-Elemente (fest, ohne Drehung) |
|
||||
| `OMNI_SCHW_400_L`/`_R`, `OMNI_SCHW_400_L_SENSORIK`/`_R_SENSORIK` | Schwenkschienen fuer Schiebetueren (Menue Spez. Streckenelemente -> Tuerloesungen) |
|
||||
| `OMNI_STOPPER`, `OMNI_SCANNER`, `OMNI_BUERSTENBREMSE` | Anbaugruppen |
|
||||
| `OMNI_TV_W_W`, `OMNI_TV_W_AP60`, `OMNI_TV_W_AP60_KPL`, `OMNI_TV_W_AP110`, `OMNI_TV_W_AP110_W`, `OMNI_TV_50`, `OMNI_TV_80`, `OMNI_TV_ENDPLATTE`, `OMNI_TV_ANSCHLAG`, `OMNI_TV_MUFFE`, `OMNI_TV_A_AP110_AP60`, `OMNI_TV_A_AP60_ST`, `OMNI_TV_A_AP110_ST`, `OMNI_TV_SW_II_SW_SW`, `OMNI_TV_SW_I_AP110`, `OMNI_TV_SW_III_AP110_SW`, `OMNI_TV_SW_IV_AP60`, `OMNI_TV_SW_IV_ST` | Verbinder |
|
||||
| `OMNI_LADESCHLEIFE_AP110` | Ladeschleife (Dialog `omniflo_ladeschleifen.dcl`) |
|
||||
| `OMNI_KettenFoerderer` | Platzhalter (noch ohne Funktion) |
|
||||
| `OMNI_EDIT` | Omniflo-Element per Dialog bearbeiten; auch per Doppelklick |
|
||||
| `OMNI_FAHRSTRECKE` (`GeruestInsert.lsp`) | Omniflo-Fahrstrecke mit Linien-Logik wie `GERUEST_TRAEGER` (Dialog `fahrstrecke.dcl`) |
|
||||
| `OMNI_FAHRSTRECKE_BESCHRIFTEN` | Alle Fahrstrecken der Zeichnung neu beschriften |
|
||||
|
||||
### Kettenfoerderer (`KettenFoerderer.lsp`)
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
|---|---|
|
||||
| `KETTENFOERDERER` | Kettenfoerderer/Schraegfoerderer Stahl per Dialog (`kettenfoerderer.dcl`) als Block `KF_<n>` bauen; Menue Omniflo -> KettenFoerderer |
|
||||
| `KF_EDIT` | `KF_n`-Block bearbeiten und neu aufbauen; auch per Doppelklick |
|
||||
| `KF_KS_PRUEFEN` | Diagnose (nicht im Menue): KS-Lage der Kettenfoerderer-Bausteine pruefen |
|
||||
|
||||
### Geruest (`GeruestInsert.lsp`)
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
|---|---|
|
||||
| `GERUEST` | Geruest-Dialog (Bereich frei waehlbar) |
|
||||
| `GERUEST_SAEULEN` / `GERUEST_ROHRABHAENGER` / `GERUEST_WANDBEFESTIGUNG` | Derselbe Dialog, im jeweiligen Bereich geoeffnet |
|
||||
| `GERUEST_SAEULEN` / `GERUEST_ROHRABHAENGER` / `GERUEST_WANDBEFESTIGUNG` | Je eigener Dialog aus der Vorlage `geruest.dcl` (keine Umschaltung zwischen den Bereichen) |
|
||||
| `GERUEST` | Ohne Bereich nur ein Hinweis; im Menue Platzhalter fuer den Gattertraeger |
|
||||
| `GERUEST_TRAEGER` | Rohr-Geruest-Traeger: Dialog (`geruest_traeger.dcl`), danach Start-/Endpunkt oder Laenge bis ESC/Enter |
|
||||
| `GERUEST_TRAEGER_BESCHRIFTEN` | Alle Traeger der Zeichnung neu beschriften, verwaiste Beschriftungen entfernen |
|
||||
|
||||
@@ -120,6 +132,7 @@ Gross-/Kleinschreibung spielt an der Kommandozeile keine Rolle.
|
||||
| `TRO_EDIT` | ID/TYPE eines TRO-Markers per Dialog aendern |
|
||||
| `CONNECTION_INSERT` | Verbindungspfeil (Fluss) zwischen zwei Elementen zeichnen |
|
||||
| `CONNECTION_EDIT` | Quelle/Ziel einer Verbindung aendern |
|
||||
| `JAM_EDIT` (`Jam_Edit.lsp`) | Staubereich (`JAM_AREA` aus sps_skel) bearbeiten: Foerderer und laufende Nummer; auch per Doppelklick |
|
||||
|
||||
### Export und IDs (`export.lsp`, `ssg_id.lsp`, `count_sep_scan.lsp`, `check_hoehen.lsp`)
|
||||
|
||||
@@ -132,7 +145,7 @@ Gross-/Kleinschreibung spielt an der Kommandozeile keine Rolle.
|
||||
| `IDSCHECK` | Alle Bloecke auf doppelte IDs pruefen und korrigieren |
|
||||
| `IDGENERATE` | Gewaehltem Block eine neue ID zuweisen |
|
||||
| `ZAEHLE_SEP_SCAN` | Scanner/Separatoren je Kreisel/VF/GF zaehlen und in ANZAHL_SCANNER/ANZAHL_SEPARATOR schreiben (laeuft auch automatisch vor jedem Export) |
|
||||
| `HOEHEN_CHECK` | Hoehen von Kreiseln/VF/GF messen und in HOEHE/HOEHE_VON_mm/HOEHE_BIS_mm/MONTAGEHOEHE_m schreiben |
|
||||
| `HOEHEN_CHECK` | Hoehen von Kreiseln/VF/GF messen und in HOEHE/HOEHE_VON_mm/HOEHE_BIS_mm/MONTAGEHOEHE_m schreiben; Phase 3: Buehnenabzug einmal pro Kreisel-Familie (beruehrende Kreisel gleicher Hoehe), wirkt auf Kreisel und die VF/GF der Familie |
|
||||
| `CALLPYTHON` (`external_call.lsp`) | Test des LISP->Python-Aufrufs (`lib/testpycall.py`) |
|
||||
|
||||
### Konfiguration, Planquadrate, Doppelklick
|
||||
@@ -145,9 +158,22 @@ Gross-/Kleinschreibung spielt an der Kommandozeile keine Rolle.
|
||||
| `DRAW_PLANQUADRATE` | Planquadrat-Raster (Block `ZZ_PLANQUADRATE`) zeichnen bzw. neu aufbauen |
|
||||
| `DELETE_PLANQUADRATE` | Planquadrat-Raster entfernen |
|
||||
| `PLANQUADRATE_TOGGLE` | Raster an/aus (zeichnen, falls keins existiert, sonst entfernen) |
|
||||
| `SSG_BLOCKEDIT` | Doppelklick-/Kontextmenue-Dispatcher: Kreisel, Omniflo, GF_*, VF_*, GR_*, TRO_* auf den passenden Edit-Befehl |
|
||||
| `SSG_BLOCKEDIT` | Doppelklick-/Kontextmenue-Dispatcher: Kreisel, Eckrad, Omniflo, GF_*, VF_*, KF_*, GR_*, TRO_*, JAM_* auf den passenden Edit-Befehl |
|
||||
| `EATTEDIT` | Ueberschreibt den nativen Befehl, leitet an `SSG_BLOCKEDIT` weiter (Fallback `_.EATTEDIT`) |
|
||||
|
||||
### Werkzeuge (`ssg_blocktools.lsp`, `ssg_texttools.lsp`, `ssg_stueckliste.lsp`, `DinFormate.lsp`)
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
|---|---|
|
||||
| `SSG_BLOCK_COUNT` | Blockeinfuegungen im aktuellen Layout zaehlen (Pick, Muster oder Statistik) |
|
||||
| `SSG_BLOCK_DELETE` | Alle Einfuegungen eines Blocks loeschen (mit Rueckfrage) |
|
||||
| `SSG_ATTR_ERSETZEN` | Attributwerte zeichnungsweit oder in einer Auswahl suchen und ersetzen |
|
||||
| `SSG_TEXT_ERSETZEN` | Suchen/Ersetzen in TEXT, MTEXT und Attributen |
|
||||
| `SSG_TEXT_PARALLEL` | Text parallel zu Linie/Polylinie/Bogen setzen |
|
||||
| `SSG_TEXT_HOEHE` / `SSG_TEXT_STIL` | Texthoehe bzw. Textstil aendern |
|
||||
| `SSG_FAEHNCHEN_STUECKLISTE` | Positions-Faehnchen und Stuecklistentabelle aus den gewaehlten Elementen der Zeichnung |
|
||||
| `DIN_FORMATE` | DIN-Rahmen (A0-A4) und optional Schriftkopf einfuegen |
|
||||
|
||||
### Layer-Werkzeuge (`ssg_layer.lsp`)
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
@@ -202,6 +228,8 @@ Aus dem Menue "Tests" bzw. der Kommandozeile; Details in `doc/LispTests.md`.
|
||||
| `TEST_MUBEA` | Mubea-Nachbau aus `tests/testdata/mubea.json` |
|
||||
| `TEST_DEMATIC_ARVATO` | Dematic/Arvato-Nachbau (Flowpuffer/Kreisel) |
|
||||
| `TEST_SHOWROOM_ILS` | ILS-3.0-Showroom-Nachbau (Kreisel, Gefaellestrecken; Hoehen noch Platzhalter) |
|
||||
| `TEST_LASTENT` | `ssg-lastent-ohne-attribute` (kopierter Attribut-Block verliert keine Attribute) |
|
||||
| `TEST_STUECKLISTE` | Faehnchen + Stueckliste aus der Zeichnung |
|
||||
| `TEST_TEST_SYSTEM` | Testanlage `test_system` nachbauen (9 Kreisel, Separatoren, BTMT) - Vorlage fuer sps_skel |
|
||||
|
||||
---
|
||||
@@ -218,7 +246,6 @@ Alle Skripte rufen zuerst `setenv.bat` (bzw. `setenv.sh`) auf.
|
||||
| `install_py.bat` / `install_py.sh` | `.venv` anlegen und `requirements.txt` installieren (nur wenn noch nicht vorhanden) |
|
||||
| `activate_venv.bat` / `activate_venv.sh` | `.venv` aktivieren, Python-Version und Pakete anzeigen |
|
||||
| `run_tests.bat` | Testausfuehrung, siehe unten |
|
||||
| `create_tests.bat` | Kompletter ILS-Testlauf: Basis-DXF erzeugen, BricsCAD mit `ILS_test.scr`, Ergebnisse validieren |
|
||||
| `set_einfuegepunkt.bat [schalter]` | Wrapper fuer `lib/set_einfuegepkt.py` (siehe `doc/tools.md`) |
|
||||
| `set_coords.bat [schalter]` | Wrapper fuer `lib/set_koords.py` (siehe `doc/tools.md`) |
|
||||
| `dbg2lsp.bat [argumente]` | Wrapper fuer `lib/dbg2lsp.py` (siehe `doc/dbg2lsp.md`) |
|
||||
|
||||
@@ -1,33 +1,38 @@
|
||||
# Kapitel 1: Meilensteinplanung
|
||||
|
||||
Status-Stand: 2026-10-26 (DONE = im Menue nutzbar und im Sivas-/CSV-Export erfasst).
|
||||
|
||||
## Meilenstein 1: ILS für die Projektierung
|
||||
- ILS Kreisel DONE
|
||||
- ILS Eckrad DONE
|
||||
- ILS Varioförder DONE
|
||||
- ILS Gefällestrecke
|
||||
- ILS Weichen
|
||||
- ILS Horizontalvariobögen (30,60,90 r und l, innen und aussen angetrieben)
|
||||
- ILS Gefällebögen (30,60,90 r und l)
|
||||
- ILS Varioförder DONE (Standard, Etage, Streckengruppe/Linienzug Modus 1-3, QC-Linie mit GF)
|
||||
- ILS Gefällestrecke DONE (einfach, aus 3D-Linie, aus Linienzug; Doppelklick-Edit)
|
||||
- ILS Weichen TEILWEISE (Weichenpunkte zwischen Kreiseln ermitteln: KREISEL_WEICHEN, Export Merkmal 4403 + Weichenzeile; keine eigene Weichen-Geometrie)
|
||||
- ILS Horizontalvariobögen (30,60,90 r und l, innen und aussen angetrieben) TEILWEISE (als Vario-Kurve innerhalb der Streckengruppe; die frueheren Einzelbefehle ILS_K* wurden entfernt)
|
||||
- ILS Gefällebögen (30,60,90 r und l) TEILWEISE (als GF-Bogen innerhalb von Streckengruppe/Gefaellestrecke-Linienzug)
|
||||
- BTMT Beladung und Entladung DONE (Einfuegen + Sivas-/CSV-Export)
|
||||
- CSV Export aller ILS Elemente
|
||||
- CSV Export aller ILS Elemente DONE (EXPORTCSV / EXPORTSIVAS)
|
||||
|
||||
## Meilenstein 2: Ersatz von Bihler Gerüst
|
||||
- Gerüst
|
||||
+ Abhänger (3 Quetschung, 6 Abhängung oben, 4 Abhängung unten, 4 Befestiung oben, 3 Farben, Variable Länge)
|
||||
+ T-Abhänger mit Flansch-Rohr (3 Spannpratze, 3 Farben, Variable Länge)
|
||||
+ Säulen (2 Arten, 3 Farben, 2 Einbauwinkel Platte, 5 Haltearm, 4 Einbauwinkel Arm, 8 Klemmring, Länge Bodensäule)
|
||||
+ Wandbefestigung (4 Varianten, 3 Befestigungen)
|
||||
+ Träger (RT/DRT) - (4 Varianten, 3 Farben, Muffe, Längenabzug Anfang/Ende)
|
||||
- CSV Export aller Gerüst Komponenten
|
||||
+ Abhänger (3 Quetschung, 6 Abhängung oben, 4 Abhängung unten, 4 Befestiung oben, 3 Farben, Variable Länge) DONE (GERUEST_ROHRABHAENGER)
|
||||
+ T-Abhänger mit Flansch-Rohr (3 Spannpratze, 3 Farben, Variable Länge) DONE (Variante der Rohrabhaenger)
|
||||
+ Säulen (2 Arten, 3 Farben, 2 Einbauwinkel Platte, 5 Haltearm, 4 Einbauwinkel Arm, 8 Klemmring, Länge Bodensäule) DONE (GERUEST_SAEULEN)
|
||||
+ Wandbefestigung (4 Varianten, 3 Befestigungen) DONE (GERUEST_WANDBEFESTIGUNG)
|
||||
+ Träger (RT/DRT) - (4 Varianten, 3 Farben, Muffe, Längenabzug Anfang/Ende) DONE (GERUEST_TRAEGER inkl. Beschriftung)
|
||||
+ Gatterträger OFFEN (Menue-Platzhalter)
|
||||
- CSV Export aller Gerüst Komponenten DONE (`pattern_geruest = GR_*`)
|
||||
- TOS von Gerüst-Import ins Sivas
|
||||
|
||||
## Meilenstein 3: Ersatz von Bihler Omniflo
|
||||
- Omniflo Bögen (27) DONE
|
||||
- Omniflo Weichen (80) DONE
|
||||
- Omniflo Verbinder (18 Varianten)
|
||||
- Kettenförderer (3 Teile: Ein/Auslauf und Verbindung)
|
||||
- TEF Geraden aus Omniflo Geraden (Umwandlungsmakro)
|
||||
- CSV Export aller Omniflo Elemente
|
||||
- Omniflo Verbinder (18 Varianten) DONE (OMNI_TV_*)
|
||||
- Kettenförderer (3 Teile: Ein/Auslauf und Verbindung) DONE (KETTENFOERDERER / KF_EDIT)
|
||||
- TEF Geraden aus Omniflo Geraden (Umwandlungsmakro) TEILWEISE (TEF_FOERDERER_LINIE belegt eine Linie mit TEF-Geraden; Umwandlung bestehender Omniflo-Geraden fehlt)
|
||||
- Omniflo Fahrstrecke, Ladeschleifen, Schwenkschienen DONE
|
||||
- Bögen für Weichen (OMNI_APBW_*) OFFEN (Dummy, im Menue ausgegraut)
|
||||
- CSV Export aller Omniflo Elemente DONE
|
||||
|
||||
## Meilenstein 4: Flex
|
||||
- Erstellung der .dwg Dateien von Bögen, Geraden, Förderer
|
||||
@@ -46,7 +51,7 @@
|
||||
- Erzeugung eines Puffers aus einer Flächenangabe/Recheck
|
||||
- Positionierung von Separatoren und Scannern aus dem Streckenverlauf/Fördereranbindung
|
||||
- Makro zur Erzeugung eines Arbeitsplatzes (Varioförderer ab, 180 Grad Bogen, Varoförderer auf)
|
||||
- Varioförder als Etagenförderer (anderer ES und AS Elemente)
|
||||
- Varioförder als Etagenförderer (anderer ES und AS Elemente) DONE (VF-Typ Etage)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ Erweiterung (AutoLISP-Konvention: Alist statt echtem Struct):
|
||||
| `vfl-modus-abbruch-sichern` | vf_linienzug.lsp | 9 |
|
||||
| `vf-winkel-solve` | vf_core.lsp | 8 |
|
||||
| `vfs-mitte-teil`, `vfl-vf-einheit`, `vfl-vf-einheit-abschluss` | standard/linienzug | je 7 |
|
||||
| `vfs-vf-koerper`, `vfl-insert-es-element`, `vfl3-es-fueller` | standard/linienzug | je 5-6 |
|
||||
| `vfs-vf-koerper`, `vfl-insert-es-element`, `vfl-zsolve-es-fueller` | standard/linienzug | je 5-6 |
|
||||
| die vier `insert-hz-*`-Funktionen | vf_etage.lsp | je 4-6 |
|
||||
|
||||
## Struct-Kandidaten
|
||||
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
# Offene TODOs
|
||||
|
||||
Zentrale Sammlung aller offenen Punkte. Wo ein eigener Fahrplan in `doc/todo/`
|
||||
existiert, steht hier nur die Kurzfassung mit Verweis. Erledigtes wird
|
||||
entfernt (Historie steht in git), nicht abgehakt stehen gelassen.
|
||||
|
||||
Stand: 2026-10-26. Wird woechentlich (freitags) mit der Doku geprueft, siehe
|
||||
`CLAUDE.md` -> Konventionen.
|
||||
|
||||
---
|
||||
|
||||
## 1. VarioFoerderer / Linienzug
|
||||
|
||||
- **Stufe 3 Winkelwahl: "Ab"-Zweig** (`vf_standard.lsp`, Kommentar bei der
|
||||
Fuellstueck-Berechnung): nur "Auf" implementiert, "Ab" bleibt bewusst offen,
|
||||
bis ein konkreter Bedarfsfall vorliegt. Ebenso `schon-flach` in Stufe 3.
|
||||
|
||||
## 2. Export / Sivas
|
||||
|
||||
- **Separator-/Scanner-Aufteilung GF/VF** in Streckengruppen: Merkmale
|
||||
4337/4339 (Gefaelle-Anteil) stehen fest auf `"0"`, 4381/4383 (Vario-Anteil)
|
||||
tragen den kompletten Blockwert. Haengt an einer Ueberarbeitung der
|
||||
Separator-/Scanner-Zuordnung im Zeichnungsmodell.
|
||||
-> `cfg/sivas_merkmal_zuordnung.md` ("Offener Punkt")
|
||||
- **TOS von Geruest-Import ins Sivas** (Entwicklungsplan Meilenstein 2).
|
||||
|
||||
## 3. Geruest
|
||||
|
||||
- **Gattertraeger**: nur Menue-Platzhalter auf `GERUEST` (zeigt einen Hinweis).
|
||||
Daten sollen spaeter in `data/json/geruest_traeger.json`.
|
||||
- **Edit-Pfad `GERUEST_EDIT`** fehlt: Doppelklick auf `GR_*` oeffnet nur
|
||||
`EATTEDIT`, kein Neuaufbau ueber den Dialog.
|
||||
|
||||
## 4. Omniflo
|
||||
|
||||
- **Boegen fuer Weichen `OMNI_APBW_*`** (14 Befehle): Dummy, im Menue
|
||||
ausgegraut.
|
||||
- **TEF-Geraden aus Omniflo-Geraden** (Umwandlungsmakro): bisher nur
|
||||
`TEF_FOERDERER_LINIE` (Linie mit TEF-Geraden belegen), keine Umwandlung
|
||||
bestehender Omniflo-Geraden.
|
||||
|
||||
## 5. ILS
|
||||
|
||||
- **ILS-Weichen als Geometrie**: Weichenpunkte werden ermittelt und exportiert
|
||||
(`KREISEL_WEICHEN`), eine eigene Weichen-Geometrie gibt es nicht.
|
||||
- **Horizontal-Variobogen / Gefaellebogen als eigenstaendige Befehle**: nur
|
||||
innerhalb der Streckengruppe (Vario-Kurve, GF-Bogen); die frueheren
|
||||
Dummy-Befehle `ILS_K*` sind entfernt.
|
||||
|
||||
## 6. Tests
|
||||
|
||||
- **`tests/test_vf_geometrie.py`** braucht BricsCAD-erzeugte DXF-Referenzdaten,
|
||||
die headless fehlen -> schlaegt ohne vorherigen CAD-Lauf fehl.
|
||||
- CAD-Laeufe `TEST_VF_SPEC` und `VF_SPEC_BAU` + `tests/test_vf_spec.py`
|
||||
gegen `tests/output/hundm05_results.json` (Beweis "Spec-Pfad ==
|
||||
Journal-Pfad" auf Geometrie-Ebene). -> `doc/todo/plan-vf-interactive.md`
|
||||
|
||||
## 7. Spaetere Meilensteine (Entwicklungsplan)
|
||||
|
||||
Nur Ueberschriften, Details in `doc/plan/Entwicklungsplan.md`:
|
||||
|
||||
- Meilenstein 4: Flex (DWGs, Produktprogramm, CSV-Export, TOS)
|
||||
- Meilenstein 5: 3D-Modelle (Omniflo Bogen/Weiche, Geruest-Modelle)
|
||||
- Meilenstein 6: Metafunktionen (Geruest ueber Bereich, Strecke aus Polylinie,
|
||||
Kreisel-Verbindung auf unterschiedlicher Hoehe, Puffer aus Flaeche,
|
||||
Separator-/Scanner-Positionierung, Arbeitsplatz-Makro)
|
||||
@@ -0,0 +1,124 @@
|
||||
# VF-Linienzug ohne GUI/Konsole - Stufe 2 (Funktionstrennung)
|
||||
|
||||
**Stand:** 2026-10-29 · **ZURUECKGESTELLT** - aus `doc/todo.md` entfernt, die
|
||||
Datei bleibt als Fahrplan liegen.
|
||||
|
||||
## Warum zurueckgestellt
|
||||
|
||||
Stufe 2 sollte den **Journal-Replay-Umweg** ueberfluessig machen: Bauteile
|
||||
direkt mit Daten aufrufen statt Fragen aus einer Queue beantworten zu lassen.
|
||||
Dieser Umweg ist aber keiner mehr. Ein Linienzug-Journal traegt mit `SEGS` die
|
||||
komplette Segment-Essenz und laesst sich OHNE Zeichnung abspielen - mit
|
||||
derselben Begruendung wurde am 2026-10-27 bereits der Spec-Uebersetzer fuer
|
||||
Modus 2/3 gestrichen (4a19ac0, `doc/todo/spec-modus2-3.md`). Die
|
||||
Modus-2-Regressionstests (`c:TEST_LINIENZUG_MODUS2`, seit 2026-10-29 fuenf
|
||||
Faelle) laufen headless ueber genau diesen Replay-Pfad: er ist nicht der
|
||||
Engpass, sondern die funktionierende Loesung.
|
||||
|
||||
Dazu kommt das Risiko. Die offenen Schritte 5c/6/8/9/10 fassen den Code an, in
|
||||
dem die REIHENFOLGE SELBST GEOMETRIE IST (siehe "Warum es heikel ist" unten) -
|
||||
und ein Teil dieser Fehler ist in der Zeichnung unsichtbar und faellt erst im
|
||||
Sivas-Export auf. Hoher Einsatz, kein Funktionsgewinn.
|
||||
|
||||
**Wieder aufnehmen, wenn** einer dieser Faelle eintritt:
|
||||
- einzelne Bauteile sollen ohne Journal aufrufbar sein (z.B. ein Generator,
|
||||
der Ketten aus Fremddaten baut und die Frage-Reihenfolge nicht kennen will);
|
||||
- der Replay-Pfad wird zu langsam oder zu fehleranfaellig;
|
||||
- `vfl-spec-ausfuehren` wird von irgendwo erwartet (heute: nirgends).
|
||||
|
||||
**Prioritaet beim Wiederaufnehmen:** niedrig - bringt Architektur, keine neue
|
||||
Funktion.
|
||||
|
||||
Herausgeloester Arbeitsauftrag aus dem Gesamtplan
|
||||
[plan-vf-interactive.md](plan-vf-interactive.md) (Teil 5 "Stufe 2: echte
|
||||
Funktionstrennung"). Dort stehen die ausfuehrliche Begruendung, die
|
||||
Knotenform und die Risikoliste; diese Datei ist die Abarbeitungsliste.
|
||||
|
||||
## Ausgangslage (Stufe 1, fertig)
|
||||
|
||||
Linienzug-Ketten lassen sich bereits ohne Dialog bauen (`VF_SPEC_BAU`,
|
||||
[vf_spec.lsp](../../Lisp/vf_spec.lsp)) - allerdings ueber einen Umweg:
|
||||
|
||||
1. Die **Spec** (Kette in Domaenenwerten) wird von `vsp-journal` in ein
|
||||
Eingabe-Journal uebersetzt - also in die Antworten, die ein Anwender
|
||||
gegeben haette.
|
||||
2. `vsp-bau-journal` startet per `vfl-journal-replay-start` den ganz normalen
|
||||
interaktiven Bau `vf-linienzug-modus` ([vf_linienzug.lsp](../../Lisp/vf_linienzug.lsp)).
|
||||
3. Jede Frage wird aus der Replay-Queue beantwortet.
|
||||
|
||||
Das funktioniert und ist per `TEST_HUNDM05` im CAD verifiziert - der Bau
|
||||
selbst "weiss" aber nichts von Daten, er fragt weiter, nur antwortet die Queue.
|
||||
|
||||
## Ziel (Stufe 2)
|
||||
|
||||
Die Funktionen in `vf_linienzug.lsp` mischen **Fragen** und **Geometrie
|
||||
bauen**. Stufe 2 trennt das:
|
||||
|
||||
- **reiner Bauteil** (Suffix `-bauen` bzw. `-setzen`): nimmt Parameter,
|
||||
baut Geometrie, fragt nichts;
|
||||
- die **Frage-Schale** behaelt den bisherigen Namen und ruft den Bauteil auf
|
||||
- dadurch aendert sich keine Aufrufstelle in Modus 1/2/3.
|
||||
|
||||
Am Ende ruft `vfl-spec-ausfuehren` die Bauteile direkt mit den Spec-Werten
|
||||
auf, ohne Journal-Replay.
|
||||
|
||||
## Stand der Schritte
|
||||
|
||||
Zeilennummern Stand 2026-10-26 (die `:NNNN`-Angaben im Gesamtplan sind
|
||||
veraltet).
|
||||
|
||||
| Schritt | Inhalt | Stand |
|
||||
|---|---|---|
|
||||
| 0 | `vfl-ziel-report` (vf_linienzug.lsp:7864) aus zwei identischen Bloecken gezogen | erledigt |
|
||||
| 1 | Winkelwahl `vfl-winkel-gueltige` (:3071) / `vfl-winkel-nach-index` + Kanal `*vfl-winkel-idx-vorgabe*` | erledigt |
|
||||
| 2 | `vfl-es-masse-setzen` (:7557) | erledigt |
|
||||
| 3 | `vfl-hor-koerper-bauen` (:5989), Schale `vfl-baue-horizontal-koerper` (:6152) | erledigt |
|
||||
| 4 | `vfl-body-abschluss-bauen` (:6502) | erledigt |
|
||||
| 5a/5b | VF-Einheit Eingang/Ausgang: `vfl-vf-eingang-bauen` (:6728), `vfl-vf-ausgang-bauen` (:6742) | erledigt |
|
||||
| **5c** | Schleifenrumpf von `vfl-vf-einheit` (:6772) - die Sub-Stuecke der VF-Einheit als Bauteil | **offen** |
|
||||
| **6** | Daten-Executor fuer die VF-Einheit (baut sie direkt aus Daten) | **offen** |
|
||||
| 7 | Spec + Serializer + Assertion: `vsp-journal-diff` (vf_spec.lsp:900) prueft Spec-Journal gegen das beim Bau aufgezeichnete Token fuer Token | Assertion erledigt |
|
||||
| **8** | Einheit-Abschluss: `vfl-vf-einheit-abschluss` (:7889) | **offen** |
|
||||
| **9** | Kettenebene, ein Glied-Zweig pro Commit: GF-Bogen -> ES -> Horizontal-VF -> Linie-GF -> Linie-VF -> Linie | **offen** |
|
||||
| **10** | `vfl-spec-ausfuehren` - der direkte Daten-Pfad (existiert noch nicht) | **offen** |
|
||||
| 11 | Dasselbe fuer Modus 2 | **Vorbedingung erfuellt 2026-10-27**: zwei echte Modus-2-Journale liegen als `tests/testdata/linienzug_modus2_{variokurve,gfbogen}.json` vor, abgespielt von `c:TEST_LINIENZUG_MODUS2`. Der Schritt selbst ist noch offen |
|
||||
|
||||
## Warum es heikel ist
|
||||
|
||||
Bei den offenen Schritten ist die **Reihenfolge selbst Geometrie**
|
||||
(Gesamtplan, Abschnitt "Wo Geometrie still kippen kann"), u.a.:
|
||||
|
||||
- die dL-Subtraktionskette ist je Schritt mit
|
||||
`(max *vfk-restlaenge-min-clamp* ...)` geklammert, also
|
||||
reihenfolgeabhaengig;
|
||||
- die `vfl-acc-*`-Aufrufe muessen an derselben Stelle in derselben
|
||||
Reihenfolge bleiben, sonst vertauschen sich `L_VF_m`/`L_GF_m`/`GF_WINKEL`
|
||||
- in der Zeichnung unsichtbar, im Sivas-Export falsch;
|
||||
- `*vfl-as-winkel*`/`*vfl-es-winkel*` werden lazy von den Blocknamen-Bauern
|
||||
gelesen - spaeter gesetzt heisst falscher Block;
|
||||
- `ziel-gf2` vs. `L_GF2-bau` im Ausgang - geht es verloren, entsteht still
|
||||
die falsche GF2 hinter dem Motor.
|
||||
|
||||
Ausdruecklich nicht anfassen: siehe Gesamtplan, Abschnitt "Ausdruecklich
|
||||
nicht anfassen" (u.a. alle Journal-Konsumenten, `vfl-in-*`-Wrapper,
|
||||
Wizard-Schicht, Abbruch-Pfad).
|
||||
|
||||
## Ablauf je Schritt
|
||||
|
||||
1. Umbauen (Frage-Schale behaelt Namen, Bauteil wortwoertlich umziehen,
|
||||
keine Umsortierung).
|
||||
2. CAD-Lauf: `TEST_HUNDM05` (save dxf), `TEST_VF_SPEC`, `TEST_LINIENZUG`.
|
||||
3. `pytest tests/test_vf_geometrie.py` gegen
|
||||
`tests/reference/hundm05_attribute.json` - nennt bei Abweichung Kette
|
||||
und Feld. Referenz nur nach geprueftem Lauf auffrischen
|
||||
(`lib/dxf_vf_abbild.py --schreibe-referenz`).
|
||||
4. Nach Geometrie-Schritten (5c, 9) zusaetzlich DXF-Diff und
|
||||
Sivas-Export-Vergleich.
|
||||
5. Ein Schritt pro Commit - sonst ist ein Fehler keinem Schritt mehr
|
||||
zuzuordnen.
|
||||
|
||||
## Wann angehen
|
||||
|
||||
Erst bei konkretem Bedarf: einzelne Bauteile ohne Journal aufrufen, oder der
|
||||
Replay-Umweg wird zu langsam bzw. zu fehleranfaellig. Bis dahin genuegt
|
||||
Stufe 1.
|
||||
@@ -1,7 +1,21 @@
|
||||
# TODO: Modus-2-Solver auf achsenweise Laengen-Bilanz umstellen
|
||||
# Modus-2-Solver: achsenweise Laengen-Bilanz
|
||||
|
||||
Status: **Vorschlag / noch nicht umgesetzt** (2026-09-18). Mit dem Entwickler zu
|
||||
besprechen, bevor der Solver angefasst wird. Reiner Plan - kein Code geaendert.
|
||||
Status: **ERLEDIGT 2026-10-29.** Gefaltete Laeufe (U-Form) werden gebaut; am
|
||||
selben Pfad gemessen 0.56 mm (9 Grad) und 0.7 mm (12 Grad) quer, beide
|
||||
Regressionsketten weiter OK. Der Abschnitt "Stand 2026-10-29" und der "Nachtrag
|
||||
2026-10-29" am Ende beschreiben Loesung und Herleitung.
|
||||
|
||||
Die Datei bleibt BEWUSST liegen, obwohl der Auftrag abgeschlossen ist: vier
|
||||
Kommentare in `Lisp/vf_linienzug.lsp` verweisen auf diesen Pfad (Suche nach
|
||||
`modus2-achsenweise-bilanz`). Sie dokumentiert damit nicht mehr einen Plan,
|
||||
sondern WARUM der Solver so bilanziert, wie er es tut - einschliesslich der
|
||||
fehlgeschlagenen Versuche, damit sie niemand ein zweites Mal unternimmt.
|
||||
|
||||
Alles unterhalb dieser Zeile ist der urspruengliche Plan von 2026-09-18 und
|
||||
seine Zwischenstaende. Die dort genannten Zeilennummern sind veraltet; Phase B
|
||||
von `vf-linienzug-modus2` findet man per Suche nach `climber-span`. Die damals
|
||||
vorgeschlagene Zwischenloesung (gefaltete Laeufe mit Meldung abweisen) wurde
|
||||
NICHT umgesetzt und ist gegenstandslos - solche Laeufe funktionieren jetzt.
|
||||
|
||||
## Kurzfassung
|
||||
|
||||
@@ -44,7 +58,7 @@ ganze Hoehe traegt, und rechnet die geneigte Laenge skalar:
|
||||
|
||||
```lisp
|
||||
;; vf_linienzug.lsp:9990 - Solver bekommt die SKALARE Spanne
|
||||
(setq wahl3 (vfl3-waehle-winkel climber-span dH-adj feste-vf))
|
||||
(setq wahl3 (vfl-zsolve-winkel-waehlen climber-span dH-adj feste-vf))
|
||||
;; feste-vf = Umlenk + Separator (+ Motor) -- ein fester Fussabdruck
|
||||
|
||||
;; vf_linienzug.lsp:10070 - Kletterer bekommt br-lvf proportional
|
||||
@@ -120,3 +134,260 @@ Gefaltete VF-Laeufe (mehr als eine Achsenrichtung im VF-Bereich, z.B. U-Form)
|
||||
erkennen und mit klarer Meldung abweisen, statt still falsche Geometrie zu
|
||||
bauen - analog zur bereits vorhandenen "nur EIN VF-Lauf"-Abweisung
|
||||
(`vfl-m3-vf-lauf-alert`). Macht das Limit ehrlich sichtbar, kleiner Eingriff.
|
||||
|
||||
---
|
||||
|
||||
## Stand 2026-10-27 (nach Commit ce4ad0f)
|
||||
|
||||
**Teilweise entschaerft, Kern bleibt offen.**
|
||||
|
||||
Die Budget-Arbeit vom 26./27.10. hat genau das Prinzip eingefuehrt, das
|
||||
dieses Dokument fordert - aber nur fuer DREI Posten. Sie werden jetzt dem
|
||||
Segment zugeschlagen, auf dem sie physisch stehen, statt skalar von der
|
||||
Gesamtspanne abgezogen zu werden:
|
||||
|
||||
| Posten | wie | Stelle |
|
||||
|---|---|---|
|
||||
| AS-Element | gemessener Fussabdruck, nur `vf-start` | `as-along-fix` |
|
||||
| Abschlussbogen + Motorstation | nur `vf-ende` | `abschluss-fp` |
|
||||
| Eck-Differenz (gezeichneter Bogen gegen Bauteil) | Alist je Segmentindex | `vfl-eck-korrekturen` / `vfl-eck-extra` |
|
||||
|
||||
`vfl-eck-extra` ist dabei bereits die hier geforderte Form: ein Zuschlag **je
|
||||
Segment**, nicht ein Skalar fuer den ganzen Lauf. Er fliesst in alle vier
|
||||
Budgets (Spannweite, Kletterer, Fueller, Rueckanker).
|
||||
|
||||
**Skalar geblieben sind genau die zwei Posten, die den U-Form-Fehler
|
||||
verursachen:**
|
||||
|
||||
- `feste-vf` (Umlenkstation 500 + Separator 300, ggf. + Motor) - wird in
|
||||
`vfl-zsolve-winkel-waehlen` als EIN Wert uebergeben
|
||||
- `gf-total` (GF1) - bei "alles am Einlauf" gross, und genau diese Summe
|
||||
fehlt dem Kletterer im anderen Schenkel
|
||||
|
||||
Das oben beschriebene Symptom (dY = +2645 mm) bleibt daher bestehen. Der
|
||||
naechste Schritt waere, diese beiden ebenfalls dem Segment zuzuordnen, auf
|
||||
dem sie stehen - also dieselbe Umstellung wie bei AS und Motorstation, nur
|
||||
fuer den Lauf-EINGANG.
|
||||
|
||||
Hinweis zur Fehlersuche: Seit ce4ad0f meldet die Konsole jeden Zuschlag
|
||||
namentlich (`AS-Fussabdruck ... von Segment N abgezogen`,
|
||||
`Abschluss-Fussabdruck ...`, `Eck-Korrektur ... auf Segment N`). Eine
|
||||
FEHLENDE Zeile ist das Warnsignal - so wurde ein 2,4-mm-Rest gefunden. Fuer
|
||||
die U-Form-Diagnose sind diese Zeilen der schnellste Einstieg.
|
||||
|
||||
---
|
||||
|
||||
## Stand 2026-10-28: Fueller-Seite geloest, Solver-Seite offen
|
||||
|
||||
### Geloest und gemessen
|
||||
|
||||
`vfl-m2-eingang-fp`: GF1 + Separator + Umlenkstation + Uebergangsbogen stehen
|
||||
auf dem Segment `vf-start`. Ist dieses Segment ein FUELLER (der Kletterer
|
||||
liegt hinter einer Kurve), bekam der Fueller bisher die volle Restlaenge, als
|
||||
staende dort nichts. Jetzt werden sie abgezogen.
|
||||
|
||||
Ist das Eingangs-Segment selbst der Kletterer - der gerade Normalfall -, gibt
|
||||
die Funktion hart 0.0 zurueck; der funktionierende Fall kann sich also nicht
|
||||
aendern. Gemessen am U-Form-Testfall: **Querabweichung 8005 -> 1424 mm**,
|
||||
Segment 1 danach auf 0,2 mm genau belegt.
|
||||
|
||||
### Noch offen: der Solver rechnet GF und Stationen gegen die falsche Achse
|
||||
|
||||
Rest 1424 mm. Segment 5 (Kletterer) legt 6475,5 mm zurueck, verfuegbar waeren
|
||||
7899,8 - der Solver reserviert dort Platz fuer Umlenkstation, Separator und
|
||||
den GF1-Anteil, die auf Segment 1 stehen.
|
||||
|
||||
### Fehlgeschlagene Versuche (nicht wiederholen)
|
||||
|
||||
Drei Anlaeufe am 2026-10-27/28, jeder an einer anderen Kopplung gescheitert:
|
||||
|
||||
1. **`feste-vf` kleiner uebergeben.** Geht nicht: `feste-hz` fliesst in
|
||||
`vf-winkel-AB` (vf_standard.lsp:241/245) sowohl als `feste*cos3` in die
|
||||
LAENGE als auch als `feste*sin3` in die HOEHE. Die Hoehe ist real - die
|
||||
Teile senken die Kette ab, egal auf welchem Schenkel sie stehen. Nur der
|
||||
Laengenanteil darf verschoben werden.
|
||||
2. **Spanne vorab korrigieren und iterieren.** Geht nicht direkt:
|
||||
`vfl-zsolve-winkel-waehlen` enthaelt die WINKELFRAGE an den Nutzer - eine
|
||||
Iteration wuerde mehrfach fragen. Und die Korrektur ist pro Winkel
|
||||
verschieden, weil jeder Winkel ein anderes `L_GF` ergibt.
|
||||
3. **Stiller Nachrechner nach der GF-Verteilungsfrage** (Code vorhanden, per
|
||||
`(setq nachrechnen-k 4)` deaktiviert). Technisch sauber: kein Dialog,
|
||||
Fragenfolge und Journal unveraendert, Konvergenz in 4 Runden
|
||||
(3278 -> 4372 -> 4737 -> 4859 -> 4899 mm). ABER er kollidiert mit
|
||||
**`filler-A-len`**: dieser Fueller belegt im Kletter-Segment genau den
|
||||
Platz, den das halbe GF1 dort frei laesst. Nimmt man GF1 aus der
|
||||
Kletterer-Spanne heraus, wird Fueller-A trotzdem gebaut - zusaetzlich zum
|
||||
echten GF1 auf demselben Segment. Gemessen: Fueller nach der
|
||||
Umlenkstation -369 mm (auf 100 geklemmt), Kette 746 mm daneben.
|
||||
Kleinerer Endfehler, aber entartete Geometrie - deshalb zurueckgenommen.
|
||||
|
||||
### Daraus fuer den naechsten Anlauf
|
||||
|
||||
Der Nachrechner ist vermutlich der richtige Weg, aber **`filler-A-len` muss
|
||||
mitbehandelt werden**: er gehoert zur Annahme "GF1 liegt im Kletter-Segment"
|
||||
und darf bei gefaltetem Lauf nicht mehr entstehen. Wer das angeht, sollte
|
||||
beide Mechanismen zusammen betrachten, nicht nacheinander.
|
||||
|
||||
Testfall vorhanden: U-Form 5855 / 270 / 7806 mm (Kletterer hinter zwei
|
||||
90-Grad-Kurven), Soll-Querabweichung ~0, Stand heute 1424 mm. Die beiden
|
||||
geraden Referenzketten in `c:TEST_LINIENZUG_MODUS2` schuetzen den Normalfall.
|
||||
|
||||
---
|
||||
|
||||
## Stand 2026-10-29: Eingangs-Segment exakt, Kletterer-Segment offen
|
||||
|
||||
### Zusaetzlich geloest (gegenueber dem Stand vom 2026-10-28)
|
||||
|
||||
**Fueller-A entfaellt bei gefaltetem Lauf**, und `vfl-m2-eingang-fp` zieht
|
||||
seitdem `br-gf1` ab statt `gf-total`. Beides gehoert zusammen:
|
||||
|
||||
`filler-A-len` fuellt den Platz, den ein halbiertes GF1 auf DERSELBEN Achse
|
||||
frei laesst - er gehoert zur Annahme "GF1 und GF2 liegen auf einer Geraden".
|
||||
Bei gefaltetem Lauf wurde er auf dem Eingangs-Segment ZUSAETZLICH zu GF1
|
||||
gebaut; zusammen mit GF2 im Kletterer-Schenkel entstanden damit 1.5 x
|
||||
gf-total Gefaellestrecke bei einem Budget von gf-total.
|
||||
|
||||
Ergebnis, am U-Form-Testfall nachgerechnet (9 Grad, Verteilung 1/2+1/2):
|
||||
|
||||
```
|
||||
Segment 1: AS 425,8 + GF1 1370,3 + Sep 299,6 + Umlenk 499,3
|
||||
+ Bogen 199,9 + Fueller 3153,7 = 5948,6 mm
|
||||
Budget: 5855 + 93,8 (Eck-Korrektur) = 5948,8 mm
|
||||
```
|
||||
|
||||
Das Eingangs-Segment ist damit **auf 0,2 mm exakt belegt**, und im Protokoll
|
||||
steht nur noch EIN Fueller statt zwei.
|
||||
|
||||
### Was offen bleibt
|
||||
|
||||
Das KLETTERER-Segment. Gemessen im selben Lauf: Segment 5 belegt 6965,8 mm,
|
||||
verfuegbar waeren 7899,8 - es fehlen **934 mm**, exakt die Endabweichung.
|
||||
|
||||
Der Solver bekommt als Spanne 7704,16 mm und verplant darin u.a. GF1
|
||||
(1370,3) sowie Umlenkstation + Separator (798,9) - Teile, die auf Segment 1
|
||||
stehen. Umgekehrt enthaelt seine Spanne NICHT den Abschluss-Fussabdruck
|
||||
(ab_3 + Motorstation, 695 mm), weil dieser nur von FUELLER-Segmenten
|
||||
abgezogen wird (`fill-len`) und das Kletterer-Segment keines ist.
|
||||
|
||||
**Der Restfehler skaliert mit `L_GF`** und damit mit dem gewaehlten Winkel -
|
||||
unabhaengig bestaetigt durch zwei Laeufe auf demselben Pfad:
|
||||
|
||||
| Winkel | L_GF | Querabweichung |
|
||||
|---|---|---|
|
||||
| 6 Grad | 1093 | 90 mm |
|
||||
| 9 Grad | 2744 | 934 mm |
|
||||
|
||||
Praktische Folge: Mit flachem Winkel ist der gefaltete Lauf heute brauchbar,
|
||||
mit steilem nicht.
|
||||
|
||||
### Hinweis zur Methodik fuer den naechsten Anlauf
|
||||
|
||||
Zwei Laeufe sind nur vergleichbar, wenn **Winkel UND GF-Verteilung gleich**
|
||||
sind. Mehrere Messreihen dieser Sitzung waren nicht deutbar, weil sich
|
||||
zwischendurch der Winkel geaendert hatte und der Restfehler mit `L_GF`
|
||||
skaliert. Vor einer Aenderung also eine feste Kombination festlegen
|
||||
(Vorschlag: 12 Grad, Verteilung 1/2+1/2) und nur die vergleichen.
|
||||
|
||||
---
|
||||
|
||||
## Nachtrag 2026-10-29: Loesungsansatz vom Nutzer
|
||||
|
||||
Der Abschnitt darueber beschreibt den Stand VOR dem folgenden Umbau; er bleibt
|
||||
als Herleitung stehen.
|
||||
|
||||
Nutzer-Vorgabe: *"nach der zweiten VF-Kurve den passenden Winkel neu aus dem
|
||||
KS_AUS der Kurve und dem Zielpunkt rechnen"* und *"da GF2 feststeht, steht auch
|
||||
die fuer Auf/Ab verbleibende Laenge fest - passender Winkel plus eine
|
||||
ausgleichende GF"*.
|
||||
|
||||
Das ist die Umkehrung der bisherigen Logik und trifft den Kern: bisher wurde
|
||||
ALLES vorab global verplant und der aufgelaufene Fehler landete am Kettenende.
|
||||
Richtig ist, die letzten freien Groessen aus der GEMESSENEN Ist-Lage zu
|
||||
bestimmen. Je nachdem, was das letzte Segment ist, sind das verschiedene
|
||||
Groessen:
|
||||
|
||||
| Letztes Segment | feste Groesse | freie Groessen |
|
||||
|---|---|---|
|
||||
| flacher Fueller | - | Richtung + Fuellerlaenge |
|
||||
| Auf/Ab-Koerper (U-Form) | Laenge (aus dem Pfad) | Winkel (diskret) + GF-Ausgleich |
|
||||
|
||||
### Umgesetzt
|
||||
|
||||
**1. Flacher Fueller als Schlussstueck** - neue Funktion
|
||||
`vfl-zsolve-schluss-ziel`. Bisher loeste `vfl-zsolve-es-fueller` nur die LAENGE
|
||||
und uebernahm die Richtung aus dem gezeichneten Pfad. Eine Laenge verschiebt die
|
||||
Kette aber nur ENTLANG ihrer Achse - steht der reale Kurvenausgang seitlich
|
||||
NEBEN der gezeichneten Geraden, laeuft die gebaute Achse parallel zur Zielachse
|
||||
und der Querversatz ist unerreichbar. Gibt man die Richtung mit frei, stehen
|
||||
zwei Unbekannte zwei Gleichungen (X und Y) gegenueber, geschlossen loesbar:
|
||||
|
||||
```
|
||||
D = Ziel - KS_AUS(letzte Kurve)
|
||||
A = sqrt(|D|^2 - P^2) ; P = Querversatz des ES-Fussabdrucks
|
||||
fill = A - C
|
||||
hz = Winkel(D) - atan2(P, A)
|
||||
```
|
||||
|
||||
`C` und `P` sind von `hz` unabhaengig, weil `vfl-zsolve-es-vektor` Vektor und
|
||||
Bezugsrahmen um denselben Winkel dreht - deshalb ist keine Iteration noetig.
|
||||
Scheitert der Solve (Ziel naeher als `P`), bleibt der bisherige Weg. Unit-Tests:
|
||||
`tu-tests-vfl-schluss` (file-frei ueber `es-block = nil`).
|
||||
|
||||
**2. Eingangs-Hardware bei gefaltetem Lauf** - der am 2026-10-28 zurueck-
|
||||
genommene Spannen-Zuschlag ist wieder da. Begruendung fuer die Ruecknahme war
|
||||
die Kollision mit `filler-A-len`; dieser Blocker ist entfallen, seit Fueller-A
|
||||
bei gefaltetem Lauf gar nicht mehr entsteht. Zugeschlagen wird weiterhin NUR
|
||||
der Laengenanteil (`entry-fixed * cos3`), nie `feste-vf` selbst - dessen
|
||||
`sin3`-Hoehenanteil ist real.
|
||||
|
||||
**3. Abschluss-Hardware auf dem Kletterer** (`kletter-ende-fp`) - endet der Lauf
|
||||
auf einem FUELLER, zieht `vfl-zsolve-es-fueller` Motorstation + Separator + ES
|
||||
beim Loesen der Fuellerlaenge selbst ab. Endet er auf einem KLETTERER, gibt es
|
||||
diesen Fueller nicht: die drei Teile werden dort gebaut, standen aber in keinem
|
||||
Budget. Abgezogen wird dasselbe wie in dessen Konstante `cc`, OHNE den
|
||||
ab_3-Bogen (der steckt in diesem Fall schon in `uebergang-fp`).
|
||||
|
||||
**4. GF1-Fremdanteil** (Nachrechner wieder aktiv, 8 statt 4 Runden) - `gf-total`
|
||||
ist ein ERGEBNIS des Winkel-Solves, sein auf dem Eingangs-Schenkel stehender
|
||||
Teil laesst sich dort noch nicht abziehen (Henne-Ei). Der Nachrechner loest bei
|
||||
UNVERAENDERTEM Winkel neu und konvergiert mit Faktor ~1/3.
|
||||
|
||||
### Der entscheidende Punkt: 3 und 4 wirken nur GEMEINSAM
|
||||
|
||||
| Posten | im Budget des Solvers | steht real auf dem Kletterer |
|
||||
|---|---|---|
|
||||
| GF1 | ja | nein - liegt im Eingangs-Schenkel |
|
||||
| Motor + Separator + ES | nein | ja |
|
||||
|
||||
Die beiden Betraege heben sich TEILWEISE auf. Wer nur einen davon korrigiert,
|
||||
verschiebt den Fehler bloss in die andere Richtung - genau das war der
|
||||
746-mm-Befund vom 2026-10-28, der damals wie eine Verschlechterung aussah.
|
||||
Gemessen am 9-Grad-Lauf: GF1 1636.9 - (Motor+Sep+ES) 1235.1 = 401.8 mm, exakt
|
||||
die damalige Restabweichung von 401.7 mm.
|
||||
|
||||
### Messergebnis
|
||||
|
||||
| Lauf | vorher | nachher |
|
||||
|---|---|---|
|
||||
| U-Form 9 Grad | 1424 -> 934 mm | **0.56 mm** |
|
||||
| U-Form 12 Grad | - | **0.7 mm** |
|
||||
| Variante A (Vario-Kurve) | OK | OK |
|
||||
| Variante B (GF-Bogen) | OK | OK |
|
||||
|
||||
Zwei verschiedene Winkel auf demselben Pfad - der Restfehler skaliert also
|
||||
nicht mehr mit `L_GF`, die Bilanz selbst stimmt.
|
||||
|
||||
### Regression auf dem Weg dorthin (Lehrstueck)
|
||||
|
||||
`kletter-ende-fp` schlug zunaechst auch in Variante B zu und verkuerzte deren
|
||||
Segment 1 um 798.9 mm. Dort ist `vf-start = vf-ende = 0`: der VF-Lauf besteht
|
||||
aus EINEM Segment, die Segmente 2..5 sind Back-Lauf. Damit ist der Kletterer
|
||||
zugleich Laufende, der Abzug griff - obwohl ohne flache Zone die Motorstation
|
||||
bereits in `feste-vf` steckt und Separator + ES vom Back-Lauf reserviert werden.
|
||||
Die drei Bedingungen am `if` (`hor-pairs > 0`, `vf-ende = n-1`, `es-vorhanden`)
|
||||
sind deshalb keine Vorsichtsmassnahme, sondern benennen genau die Faelle, in
|
||||
denen sonst doppelt gebucht wird.
|
||||
|
||||
Auffindbar war die Ursache nur, weil Segment 1 von Variante B bei `hz=0` liegt:
|
||||
eine Verkuerzung dieses Segments uebersetzt sich 1:1 in `dX`, und `IST - SOLL =
|
||||
(-799.11 | -104.68)` aus `logs/vfl_modus2.dbg` zeigte die reine X-Verschiebung.
|
||||
|
||||
@@ -5,6 +5,14 @@
|
||||
verifiziert, `TEST_HUNDM05` aktiv in `tests/alltests.json`; Stufe 2
|
||||
Schritte 0-4 + 7-Assertion fertig, 5/6/8/9/10 offen, 11 zurueckgestellt.
|
||||
**Herkunft:** Planungslauf (Plan-Modus) vom 2026-09-02, hier eingecheckt zur Nachverfolgung.
|
||||
**Pruefung 2026-10-26:** Stand unveraendert - Stufe 2 Schritte 5c/6/8/9/10
|
||||
(u.a. `vfl-spec-ausfuehren`) und die Spec-Uebersetzer fuer Modus 2/3 sind
|
||||
weiterhin nicht gebaut. Die Spec-Uebersetzer fuer Modus 2/3 (auf
|
||||
`SEGS`-Basis, Abschnitt 4.4 ersetzt) sind ausgelagert nach
|
||||
[spec-modus2-3.md](spec-modus2-3.md).
|
||||
**Abarbeitungsliste Stufe 2:** herausgeloest nach
|
||||
[linienzug-ohne-gui.md](linienzug-ohne-gui.md) (aktuelle Zeilennummern,
|
||||
Ablauf je Schritt); Teil 5 hier bleibt die ausfuehrliche Referenz.
|
||||
|
||||
## Fortschritt
|
||||
|
||||
@@ -88,9 +96,9 @@ Doppelklick-Edit, `SSG_DIM_SWITCH`) ist unveraendert. Das `"disabled": true`
|
||||
der hundm05-Zeile in `tests/alltests.json` ist weg, der Test laeuft aktiv
|
||||
mit.
|
||||
|
||||
**Bewusst nicht umgestellt**: `vfl-konvertiere-ent` (Batch-2D/3D) laeuft
|
||||
weiter ohne `*vfl-headless*` - eine Live-Rueckfrage ist dort bisher gewolltes
|
||||
Verhalten. Kandidat fuer Stufe 1, wenn der Ergebnis-Record steht.
|
||||
**Nachtrag 2026-10-26**: `vfl-konvertiere-ent` (Batch-2D/3D) laeuft jetzt
|
||||
ebenfalls unter `*vfl-headless*`; der alte Block wird erst nach erfolgreichem
|
||||
Neubau geloescht (Details `doc/variofoerderer.md`, Abschnitt Headless).
|
||||
|
||||
## Kontext
|
||||
|
||||
@@ -149,8 +157,11 @@ Modus-uebergreifende Blocker:
|
||||
- **`ATTREQ`/`ATTDIA`**: ohne `0` fragt das `(command "_.INSERT" ...)` in den
|
||||
Einfuegeprimitiven nach Attributwerten - der wahrscheinlichste Haenger.
|
||||
|
||||
Namensfalle: die `vfl3-*`-Helfer (:5093-5276) gehoeren zu **Modus 2**, die
|
||||
`vfl2-*`-Helfer (:4703-4804) zu **Modus 3**.
|
||||
Namensschema (seit 2026-10-22 rollenbasiert statt nach Modus-Nummer, die
|
||||
frueheren Praefixe `vfl3-`/`vfl2-` waren zur Menue-Nummerierung vertauscht):
|
||||
die `vfl-zsolve-*`-Helfer rechnen die Hoehen durch und gehoeren zu **Modus 2**;
|
||||
die `vfl-pfad-*`-Helfer arbeiten auf dem gezeichneten Pfad und werden von
|
||||
**Modus 2 UND Modus 3** genutzt.
|
||||
|
||||
---
|
||||
|
||||
@@ -339,6 +350,11 @@ gesammelten Meldungen aus P1.
|
||||
|
||||
### 4.4 Modus 2 und Modus 3
|
||||
|
||||
> **Ueberholt (2026-10-26):** Modus 2/3 journalisieren seit 2026-09-18
|
||||
> `SEGS` statt `OBJS`, Modus 3 hat Journal + Doppelklick-Edit. Aktueller
|
||||
> Entwurf und Schritte: [spec-modus2-3.md](spec-modus2-3.md). Der folgende
|
||||
> Text bleibt nur als Historie.
|
||||
|
||||
Modus 2: Spec traegt `("pfad-handles" ...)` (Entity-Handles der LINE/ARC-Trasse)
|
||||
plus `("segmente" ...)` in Pfadreihenfolge. Vor dem Bau wird die Segmentzahl
|
||||
gegen die aufgeloesten Handles geprueft und bei Fehlbestand abgebrochen - die
|
||||
@@ -695,7 +711,7 @@ Architektur, nicht Funktion.
|
||||
|
||||
### Ausdruecklich nicht anfassen
|
||||
|
||||
`vf-linienzug-modus3` + alle `vfl2-*`; die `vfl-in-*`-Wrapper und `vfl-menu*`;
|
||||
`vf-linienzug-modus3` + alle `vfl-pfad-*`; die `vfl-in-*`-Wrapper und `vfl-menu*`;
|
||||
`vfl-entry->string` und das XDATA-Layout/die Marker; **alle Journal-Konsumenten**
|
||||
(brauchen sie Aenderungen, ist die Invariante gebrochen - das ist der
|
||||
Lackmustest); die reinen `vfs-*`/`berechne-*` in `vf_standard.lsp` (via
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
# TODO: Spec-Uebersetzer fuer VF-Linienzug Modus 2 und 3
|
||||
|
||||
> **Stand 2026-10-27: Auftrag weitgehend erledigt bzw. bewusst gestrichen.**
|
||||
> Siehe Abschnitt "Entscheidung 2026-10-27" am Ende. Der Text darunter ist
|
||||
> die urspruengliche Planung und bleibt als Begruendung stehen - er
|
||||
> beschreibt NICHT mehr den offenen Stand.
|
||||
|
||||
**Stand:** 2026-10-26 · **Prioritaet:** mittel - einzige fehlende
|
||||
FUNKTION im Daten-Pfad (Modus-2/3-Ketten sind nur interaktiv baubar).
|
||||
|
||||
Herausgeloester Rest von Stufe 1 aus [plan-vf-interactive.md](plan-vf-interactive.md)
|
||||
(dort Abschnitt 4.4, der hiermit ersetzt ist). Schwester-Auftrag:
|
||||
[linienzug-ohne-gui.md](linienzug-ohne-gui.md) (Stufe 2).
|
||||
|
||||
## Ausgangslage
|
||||
|
||||
Der Daten-Pfad `VF_SPEC_BAU` ([vf_spec.lsp](../../Lisp/vf_spec.lsp)) kann nur
|
||||
Modus 1:
|
||||
|
||||
- `vsp-journal` (vf_spec.lsp:568) kennt nur den Fragenfluss/die Menue-Codes
|
||||
von `vf-linienzug-modus` (z.B. `*vsp-tab-gf-laenge-modus*`, :56).
|
||||
- `vsp-bau-journal` (:939) ruft fest `vf-linienzug-modus` auf (:978).
|
||||
|
||||
Modus 2 (`vf-linienzug-modus2`, Pfad + Zielhoehe, Marker `"linienzug2"`) und
|
||||
Modus 3 (`vf-linienzug-modus3`, Vorwaerts-Nachbau, Marker `"linienzug3"`)
|
||||
fragen grundlegend anders: erst Pfad-Auswahl (`vfl-in-segmente`), dann je
|
||||
Segment ein Klassifizierungs-Dialog (`vflw_seg_linie_m2`/`_m3`,
|
||||
`vflw_seg_bogen`). Dafuer gibt es weder Uebersetzer noch Bau-Aufruf.
|
||||
|
||||
Doppelklick-Edit/Neuaufbau funktioniert fuer beide Modi bereits
|
||||
(`vfl-edit-ent-voll`) - es fehlt nur der Bau aus einer Spec-Datei.
|
||||
|
||||
## Korrektur des alten Entwurfs (Plan 4.4, Stand 2026-09-02)
|
||||
|
||||
| alter Entwurf | heute (seit 2026-09-18) |
|
||||
|---|---|
|
||||
| Modus-2-Spec traegt `pfad-handles` (Entity-Handles, Journal-Art `OBJS`), vor dem Bau gegen die reale Zeichnung geprueft | Modus 2 UND 3 journalisieren die **Segment-Essenz** als Journal-Art `SEGS`: je Segment 9 Felder `typ hz laenge bwinkel bseite spx spy epx epy` (`vfl-segs->string`/`vfl-string->segs`, vf_linienzug.lsp). Die Kette ist selbst-enthalten, die Original-LINE/ARC werden nicht mehr gebraucht |
|
||||
| Modus 3 ohne Journal-XDATA, kein Doppelklick-Edit, keine 2D/3D-Konvertierung; Nachruestung zurueckgestellt | Modus 3 schreibt Marker `"linienzug3"` und ist per Doppelklick editierbar |
|
||||
| "Eine Gerade direkt nach einer Vario-Kurve wird nicht gefragt - der Uebersetzer leitet das ab" | gilt vermutlich weiter, am echten Journal pruefen |
|
||||
|
||||
Folge fuer den Entwurf: Die Spec fuer Modus 2/3 traegt eine **Segmentliste**
|
||||
statt Objekt-Handles plus die Klassifizierung je Segment (Typ, GF-Neigung
|
||||
bzw. Wert, Bogen-Variante) und die Praeambel (Startpunkt, Starthoehe,
|
||||
AS/ES). Sie ist damit wie Modus 1 **ohne Zeichnung** pruefbar.
|
||||
|
||||
## Schritte
|
||||
|
||||
Die Stand-Spalte ist auf 2026-10-29 nachgezogen (sie fuehrte bis dahin
|
||||
faelschlich noch alle sieben Schritte als offen, obwohl der Kopf dieser Datei
|
||||
das Gegenteil sagt).
|
||||
|
||||
| Schritt | Inhalt | Stand |
|
||||
|---|---|---|
|
||||
| 1 | Referenz-Journale erzeugen: in BricsCAD 2-3 typische Ketten je Modus (2 und 3) bauen, Zeichnung unter `tests/testdata/` ablegen. Abdecken: GF- und VF-Segmente, Bogen, AS/ES ja/nein, bei Modus 3 altes und neues AS/ES-Format | **fuer Modus 2 erledigt** (5 Ketten, `tests/testdata/linienzug_modus2_*.json`, abgespielt von `c:TEST_LINIENZUG_MODUS2`). Fuer Modus 3 auf Nutzer-Entscheidung 2026-10-29 **gestrichen** |
|
||||
| 2 | Python-Lesepfad: `lib/vf_journal_export.py` (+ `vf_linienzug_grammatik.py`) lernen `linienzug2`/`linienzug3` mit `SEGS` (heute: "unbekannter Code") | **erledigt** (4a19ac0, Marker-Trennung + Rohtokens) |
|
||||
| 3 | Spec-Form fuer Modus 2/3 festlegen (flaches JSON, lesbar von `ssg-load-json`, Segmente als Einzeiler) | **gestrichen** - siehe Entscheidung |
|
||||
| 4 | Python-Rundlauf `spec_aus_journal`/`journal_aus_spec` fuer Modus 2/3 in `lib/vf_spec_export.py`, Test in `tests/test_vf_spec.py`: Journal -> Spec -> Journal tokengleich | **gestrichen** |
|
||||
| 5 | LISP: `vsp-journal` je Modus (Dispatch ueber Spec-Feld `modus`), `vsp-pruefen` um Modus-2/3-Regeln erweitern | **gestrichen** |
|
||||
| 6 | `vsp-bau-journal`: Bau-Funktion nach Modus waehlen (`vf-linienzug-modus2`/`-modus3`), Ergebnis-Record wie Modus 1 (`prompts` = 0, `journal_diff` leer) | **erledigt** (4a19ac0, Dispatch aus dem Journal statt per Spec-Feld) |
|
||||
| 7 | CAD-Test analog `TEST_HUNDM05` + Eintrag in `tests/alltests.json`; file-freie Teile als `tu-*` in `tests/test_unit.lsp` | **als Journal-Replay erledigt** fuer Modus 2 (`c:TEST_LINIENZUG_MODUS2`), fuer Modus 3 gestrichen |
|
||||
|
||||
## Hinweise
|
||||
|
||||
- Korrektheitskriterium Modus 3 ist "gleiches rein, gleiches raus", NICHT
|
||||
"trifft den Zielpunkt" - der Ist/Soll-Ende-Report weicht schon im
|
||||
interaktiven Bau ab.
|
||||
- Alte `"linienzug2"`-Bloecke mit `OBJS`-Journal (vor 2026-09-18) sind
|
||||
nicht mehr editierbar und taugen NICHT als Referenz.
|
||||
- Neue `vfl-in-*`-Wrapper mit `ssget`/`get*` im statischen Waechter
|
||||
`tests/test_vf_headless_statisch.py` eintragen.
|
||||
- Werte selbstbeschreibend in der Spec (Winkel 30/60/90, nicht Index) -
|
||||
siehe CLAUDE.md, Konventionen.
|
||||
|
||||
---
|
||||
|
||||
## Entscheidung 2026-10-27 (nach Commit 4a19ac0)
|
||||
|
||||
**Die Spec fuer Modus 2/3 wird NICHT gebaut.** Der Grund ist erst durch den
|
||||
Modus-2-Regressionstest (cf626d7) sichtbar geworden:
|
||||
|
||||
Modus-2/3-Journale tragen mit `SEGS` die komplette Segment-Essenz und sind
|
||||
damit **ohne Zeichnung abspielbar** - `vfl-journal-replay-start` +
|
||||
`vf-linienzug-modus2` genuegt, wie `c:TEST_LINIENZUG_MODUS2` zeigt. Der
|
||||
Hauptnutzen einer Spec (Domaenenwerte statt Menue-Codes) faellt damit
|
||||
weitgehend weg: `SEGS` ist bereits Geometrie im Klartext, kein Menue-Code.
|
||||
|
||||
Fuer Modus 1 bleibt die Spec sinnvoll - dessen Journal besteht aus
|
||||
Menue-Ziffern ("5" = "Neue Linie BIS Kettenende"), die ohne Uebersetzung
|
||||
unlesbar sind.
|
||||
|
||||
### Umgesetzt (die lohnenden Teile)
|
||||
|
||||
| Schritt | Stand |
|
||||
|---|---|
|
||||
| 1 Referenz-Journale | **erledigt** - `tests/testdata/linienzug_modus2_{variokurve,gfbogen}.json`, aus einem echten Lauf |
|
||||
| 2 Python liest `linienzug2`/`3` | **erledigt** - `vf_journal_export.py` trennt nach Marker, Modus 2/3 als Rohtokens. Vorher lief die Modus-1-Grammatik auch darueber und brach ab |
|
||||
| 6 Bau-Funktion nach Modus | **erledigt** - `vsp-bau-fn-fuer-journal` leitet sie aus dem Journal ab (kein SEGS = 1, SEGS + Marke `m2v2` = 2, SEGS ohne = 3) |
|
||||
| 7 CAD-Test | **erledigt als Journal-Replay** statt als Spec-Test: `c:TEST_LINIENZUG_MODUS2`, zwei Varianten derselben Strecke |
|
||||
|
||||
### Gestrichen
|
||||
|
||||
Schritte 3, 4 und 5 (Spec-Form, Python-Rundlauf, `vsp-journal` je Modus).
|
||||
Sie lohnen erst, wenn jemand Modus-2/3-Ketten aus EXTERNEN Daten *erzeugen*
|
||||
will - heute tut das niemand. Selbst `dxf_anlage_export.py` schreibt fuer
|
||||
Modus-1-Linienzuege das Journal unveraendert durch (`"typ":
|
||||
"linienzug_journal"`) statt eine Spec zu bauen.
|
||||
|
||||
### Stattdessen: das eigentliche Risiko direkt entschaerft
|
||||
|
||||
Die Spec haette *eine* echte Schwachstelle abgedeckt - positionsabhaengige
|
||||
Menue-Ziffern im Journal. Das ist stattdessen an der Quelle geloest: die
|
||||
Segment-Antworten sind jetzt selbstbeschreibende Werte (`gf`/`vf`,
|
||||
`gf-bogen`/`vario-kurve`, `aussen`/`innen`, gemeinsamer Normalisierer
|
||||
`vfl-wert-norm`). Ein Umsortieren der Optionen deutet damit keine
|
||||
gespeicherte Kette mehr um - genau das war beim Lauf-Anfang (833a4b6) real
|
||||
passiert. Bruchteil des Aufwands, gleicher Schutz.
|
||||
|
||||
### Modus 3: abgeschlossen mit bewusst bleibendem Risiko (2026-10-29)
|
||||
|
||||
**Dasselbe fuer Modus 3** - dessen Segment-Klassifizierung benutzt weiterhin
|
||||
Menue-Ziffern ("1".."4", roh verglichen und genauso ins Journal geschrieben).
|
||||
Nicht mit umgestellt wurde sie, weil fuer Modus 3 kein aufgezeichnetes Journal
|
||||
und damit kein Sicherheitsnetz existiert - bei Modus 2 haben die
|
||||
Referenzketten bewiesen, dass Bestandsketten die Umstellung unveraendert
|
||||
ueberstehen (sie tragen bis heute die alten Ziffern).
|
||||
|
||||
**Nutzer-Entscheidung 2026-10-29:** fuer Modus 3 wird VORERST kein Testfall
|
||||
angelegt - *"bei Problemen im Einsatz testen wir und korrigieren dann"*. Die
|
||||
Umstellung auf selbstbeschreibende Werte unterbleibt damit bis auf Weiteres,
|
||||
und der Punkt ist aus `doc/todo.md` entfernt: er wartet nicht auf Arbeit,
|
||||
sondern auf einen Anlass.
|
||||
|
||||
Praktisch heisst das: Taucht in Modus 3 ein Fehler auf, der nach einer Kette
|
||||
aus der Zeichnung heraus untersucht werden muss, ist der erste Schritt
|
||||
`lib/vf_journal_export.py` auf diese Zeichnung - damit liegt genau das
|
||||
Journal vor, das hier als Sicherheitsnetz fehlt, und die Umstellung waere
|
||||
dann derselbe Handgriff wie bei Modus 2.
|
||||
|
||||
Das Risiko bleibt aber bestehen und wandert dorthin, wo es gefaehrlich wird:
|
||||
als Warnblock direkt ueber der Segment-Auswahl in `vf_linienzug.lsp`
|
||||
(Suche nach "ACHTUNG beim Aendern der folgenden Auswahllisten"). Wer die
|
||||
Modus-3-Optionen umsortiert, ergaenzt oder entfernt, deutet damit jedes
|
||||
gespeicherte `linienzug3`-Journal still um. Eine TODO-Zeile haette diesen
|
||||
Leser nicht erreicht, ein Kommentar an der Aenderungsstelle schon.
|
||||
+30
-10
@@ -387,7 +387,7 @@ arbeiten auf bereits in der Zeichnung vorhandener Geometrie statt auf freier
|
||||
Klick-Eingabe — fuer eine GUI eher Import/Solver-Werkzeuge als klassische
|
||||
Formulare.
|
||||
|
||||
### Modus 2 — Pfad + Zielhoehe (Solver)
|
||||
### Modus 2 — aus 3D Linie MIT Zielhoehe (Solver)
|
||||
|
||||
| Feld | Steuerelement | Werte |
|
||||
|---|---|---|
|
||||
@@ -400,15 +400,28 @@ Formulare.
|
||||
| -> Vario-Kurve-Variante | Dropdown | Aussen / Innen |
|
||||
| GF-Verteilung | Dropdown | alles am Einlauf (GF1) / 1/2 GF1 + 1/2 GF2 |
|
||||
|
||||
### Modus 3 — Vorwaerts-Nachbau (Legacy, wird umgebaut)
|
||||
### Modus 3 — aus 3D Linie OHNE Zielhoehe (Vorwaerts-Bau)
|
||||
|
||||
Baut dieselbe gezeichnete Geometrie wie Modus 2, aber VORWAERTS mit
|
||||
vorgegebenen Winkeln: die Endhoehe ist hier ein Ergebnis, kein Ziel. Genau
|
||||
das ist sein Anwendungsfall — wenn es keine feste Zielhoehe gibt.
|
||||
|
||||
| Feld | Steuerelement | Werte |
|
||||
|---|---|---|
|
||||
| Startpunkt (3D) | Punktwahl | KS_EIN AUS-Element / Kettenanfang |
|
||||
| Gefaellewinkel | Zahl (Grad) | wird auch aus 2 gewaehlten 3D-Punkten vorgeschlagen |
|
||||
| AUS-Element Seite | Dropdown | links / rechts |
|
||||
| Separator vor EIN? | Dropdown | Ja/Nein |
|
||||
| Einfuegen bestaetigen | Dropdown | Ja/Nein |
|
||||
| Startpunkt (3D) + Starthoehe | Punktwahl + Zahl | Kettenanfang |
|
||||
| AS-Element bauen? | Ja/Nein | bei Nein beginnt die Kette direkt am Startpunkt |
|
||||
| -> AS Winkel + Seite | Dropdown | 30/90 Grad · links/rechts (ein Dialog zusammen mit "bauen?") |
|
||||
| ES-Element bauen? | Ja/Nein | **vor** dem Bau gefragt, damit der ES-Fussabdruck von der letzten Geraden abgezogen werden kann |
|
||||
| -> ES Winkel + Seite | Dropdown | 30/90 Grad · links/rechts |
|
||||
| Pfad-Objekte | Objektauswahl | Linien + Boegen der Trasse |
|
||||
| Je gerades Segment: Typ | Dropdown | GF / VF-Ab / VF-Auf / VF-Horizontal |
|
||||
| -> GF-Neigung bzw. Vario-Winkel | Zahl (Grad) | kontextabhaengig |
|
||||
| Je Bogen-Segment: Typ | Dropdown | GF-Bogen / Vario-Kurve (+ Variante) |
|
||||
|
||||
Ketten, die vor dem 2026-10-22 gebaut wurden, kennen die beiden
|
||||
"bauen?"-Fragen noch nicht; sie werden beim Doppelklick automatisch erkannt
|
||||
und in der alten Reihenfolge nachgebaut (siehe `alt-journal` in
|
||||
`vf-linienzug-modus3`).
|
||||
|
||||
---
|
||||
|
||||
@@ -623,9 +636,16 @@ Beispiel: `tests/test_hm_recformat.lsp` (5 echte Ketten aus `data/polylines.dxf`
|
||||
setzt alle drei Schalter mit Save/Restore, ersetzt `getpoint`/`getstring`/
|
||||
`getint`/`getreal`/`alert` zusaetzlich durch **zaehlende** Stubs (Netz fuer
|
||||
Prompts ausserhalb der Wrapper) und schreibt `prompts`, `headless_fehler` und
|
||||
`meldungen` in `tests/output/hm_recformat_results.json`. Noch nicht umgestellt:
|
||||
`vfl-konvertiere-ent` (Batch-2D/3D-Konvertierung) laeuft weiter ohne
|
||||
`*vfl-headless*` - dort ist eine Live-Rueckfrage bisher gewolltes Verhalten.
|
||||
`meldungen` in `tests/output/hm_recformat_results.json`.
|
||||
|
||||
Auch `vfl-konvertiere-ent` (Batch-2D/3D-Konvertierung `SSG_DIM_ALL_2D`/`_3D`,
|
||||
Modus 1/2/3) laeuft seit 2026-10-26 unter `*vfl-headless*` (Wizard und GUI
|
||||
aus, Save/Restore). Reicht ein Journal nicht, bricht der Neubau mit
|
||||
Fundstelle ab statt mitten im Batch live zu fragen. Der ALTE Block bleibt
|
||||
dabei stehen und wird erst geloescht, wenn ein neuer `VF_n`-INSERT entstanden
|
||||
ist; bei einem Fehlschlag raeumt `vfl-konvert-aufraeumen` alles seit der
|
||||
Startmarke Erzeugte wieder weg (keine losen Teile). Die Gruende sammelt
|
||||
`*vfl-konvert-fehler*`, der Batch gibt sie am Ende als Liste aus.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -105,6 +105,63 @@ Zwischen-Etappe, es geht in derselben VF-Einheit weiter (Vario-Kurve,
|
||||
weiteres gerades Stueck, Auf/Ab). "Ja" beendet die VF-Einheit mit einer
|
||||
Motorstation - optional zusaetzlich mit ES-Element (echtes Kettenende).
|
||||
|
||||
### 3a. Neu seit 2026-10-21: Zufuehrungsachse und "Parallel zum Kreisel"
|
||||
|
||||
Die Tabelle oben zitiert eine aeltere Aufzeichnung. Zwei Dinge sind seitdem
|
||||
dazugekommen (aeltere Ketten bleiben unveraendert editierbar - das Journal
|
||||
erkennt am Eintragstyp, welche Fragen damals gestellt wurden):
|
||||
|
||||
**Zufuehrungsachse (2. Punkt) - jetzt bei BEIDEN AS-Winkeln.** Nach Winkel
|
||||
und Seite (Eintrag 4/5) fragt der AS-Dialog zusaetzlich einen zweiten Punkt
|
||||
ab; im Assistenten stehen alle drei Angaben in EINEM Fenster
|
||||
(`vflw_as_achse`). Die beiden Angaben beschreiben verschiedene Dinge und
|
||||
legen das AS erst zusammen vollstaendig fest:
|
||||
|
||||
| Angabe | legt fest |
|
||||
|---|---|
|
||||
| 2. Punkt | Richtung der KS_EIN-Achse = die Zufuehrung, z.B. die Kreisel-Laufrichtung. Der Startpunkt bleibt der Sitz des AS-Elements, der zweite Punkt gibt nur die Richtung. |
|
||||
| links/rechts | AS-Variante und damit die KS_AUS-Richtung, also wohin die Kette nach dem Ausschleusen laeuft. |
|
||||
|
||||
Der Dialog zeigt den Startpunkt mit an (er ist der Sitz des AS-Elements UND
|
||||
der Ausgangspunkt der Achse); waehrend der Punktwahl haengt das Gummiband an
|
||||
ihm. Mit dem gesetzten Punkt ist der Dialog fertig und schliesst direkt - die
|
||||
ermittelte Achsrichtung meldet die Konsole. Nur ein mit ESC abgebrochener
|
||||
Pick zeigt den Dialog noch einmal (mit den vorher gewaehlten Werten), damit
|
||||
nach einem Fehlklick nichts verloren geht.
|
||||
|
||||
Die Achse ist **optional**: ohne Punkt laeuft alles wie frueher ueber die
|
||||
Richtung des naechsten Klicks. Frueher ersetzte die Achse beim 30-Grad-
|
||||
Element die Seitenfrage (die Seite wurde aus der Lage des naechsten Punkts
|
||||
erraten); das gilt nur noch beim Nachbau alter Ketten.
|
||||
|
||||
**"Parallel zum Kreisel weiterbauen"** - 5. Option der Frage "Wie soll die
|
||||
Laenge dieser Gefaellestrecke bestimmt werden?" (Eintrag 30). Sie erscheint
|
||||
nur am Kettenanfang mit AS-Element UND festgelegter Zufuehrungsachse, weil
|
||||
sie beides als Bezug braucht. Gebaut wird AS -> kurzes GF-Stueck -> GF-Bogen,
|
||||
sodass die Kette danach parallel zur Zufuehrungsachse weiterlaeuft. Einzige
|
||||
Eingabe ist der **Abstand**, gemessen senkrecht zur Zufuehrungsachse von
|
||||
KS_EIN des AS bis KS_AUS des Bogens; die Laenge des GF-Stuecks dazwischen
|
||||
wird daraus berechnet. Ein Separator zwischen GF-Stueck und Bogen wird
|
||||
bewusst NICHT gesetzt, damit der Abstand exakt getroffen wird. Der Bogen wird
|
||||
nicht geraten, sondern so gewaehlt, dass er den gemessenen Grundriss-Schwenk
|
||||
des AS-Blocks genau aufhebt - immer zur Gegenseite der AS-Seite:
|
||||
|
||||
| AS | Bogen |
|
||||
|---|---|
|
||||
| 30 Grad links | 30 Grad rechts |
|
||||
| 30 Grad rechts | 30 Grad links |
|
||||
| 90 Grad links | 90 Grad rechts |
|
||||
| 90 Grad rechts | 90 Grad links |
|
||||
|
||||
Diese Tabelle ist das ERGEBNIS der Messung, keine gepflegte Zuordnung im
|
||||
Code - sie bleibt auch dann richtig, wenn ein Element anders vermessen ist
|
||||
als hier erwartet.
|
||||
|
||||
Direkt nach dem Bogen kommt die gewohnte Frage "Ist das das Kettenende?"
|
||||
(Ja mit ES / Ja ohne ES / Nein, weiterbauen) - hier ausnahmsweise NACH dem
|
||||
Bau, weil es keine gepickte Laenge gibt, von der ein ES-Fussabdruck
|
||||
abzuziehen waere.
|
||||
|
||||
## 4. Stufe 1 / Stufe 2 - wie die letzte Strecke berechnet wird
|
||||
|
||||
Am Kettenende (Eintrag 61/62) ist die Aufgabe: von der aktuellen Position/
|
||||
|
||||
+128
-9
@@ -9,6 +9,7 @@
|
||||
"vfl-as-auto-erkannt": "\n>>> Startpunkt liegt auf KS_AUS einer bestehenden %1-Kette - kein AS-Element noetig.",
|
||||
"vfl-familie-neutral": "GF/VF",
|
||||
"vfl-sep-nach-durch-es-ueberschrieben": "\n>>> Separator NACH ignoriert - das ES-Element bringt beim Kettenende bereits seinen eigenen Separator mit (sonst zwei Separatoren hintereinander).",
|
||||
"vfl-sep-gf-es-automatisch": "(Ein Separator zwischen GF und ES wird automatisch gesetzt.)",
|
||||
"vfl-echo-position": "\n>>> Position: X=%1 Y=%2 Z=%3",
|
||||
"vfl-echo-wahl": "\n>>> Gewaehlt: %1",
|
||||
"vfl-aus-seite-header": "\n\nAUS-Element (AS_Element_*) - Seite waehlen:",
|
||||
@@ -55,6 +56,27 @@
|
||||
"vfl-gf-laenge-modus-opt-hoehe": "\n 2 - Zielhoehe festlegen (Laenge wird berechnet)",
|
||||
"vfl-gf-laenge-modus-opt-steigend": "\n 3 - Steigende GF (Sonderfall, bis 3 Grad)",
|
||||
"vfl-gf-laenge-modus-opt-qc": "\n 4 - QC Linie mit GF (automatische Auf-Ab-Berechnung)",
|
||||
"vfl-gf-laenge-modus-opt-parallel": "\n 5 - Parallel zum Kreisel weiterbauen (nur Abstand eingeben)",
|
||||
"vfl-richtung-header": "\n\nIn welche Richtung soll gebaut werden?",
|
||||
"vfl-richtung-opt-vor": "\n 1 - Vorwaerts bauen (der gewaehlte Punkt ist der Kettenanfang)",
|
||||
"vfl-richtung-opt-rueck": "\n 2 - Rueckwaerts bauen (der gewaehlte Punkt ist das Kettenende, ES-Austritt)",
|
||||
"vfl-prompt-es-achse-p2": "\n\nFahrtrichtung - 2. Punkt (gibt nur die Richtung, der Endpunkt bleibt): ",
|
||||
"vfl-es-basislinie-info": "\n Abfuehrungsachse (Fahrtrichtung): %1 Grad.",
|
||||
"vfl-rueck-menu-linie-gf": "\n 1 - Neue Linie: GF (Gefaellestrecke)",
|
||||
"vfl-rueck-laenge-opt-anfangspunkt": "\n 1 - Kettenanfang waehlen (Laenge ergibt sich, Anfangshoehe wird gerechnet)",
|
||||
"vfl-rueck-laenge-opt-anfangshoehe": "\n 2 - Anfangshoehe festlegen (Laenge wird berechnet)",
|
||||
"vfl-rueck-prompt-anfangspunkt": "\n\nKettenanfang waehlen (Richtung steht ueber die Abfuehrungsachse fest): ",
|
||||
"vfl-rueck-prompt-anfangshoehe": "\nGewuenschte Hoehe am Kettenanfang (mm) <%1>: ",
|
||||
"vfl-rueck-alert-hoehe-zu-klein": "Der Kettenanfang muss HOEHER liegen als das Kettenende - eine Gefaellestrecke faellt in Fahrtrichtung.",
|
||||
"vfl-rueck-erfolg-punkt": "\n>>> Rueckwaerts gebaut: GF-Stueck %1 mm (horizontal), Anfangshoehe %2 mm.",
|
||||
"vfl-rueck-erfolg-hoehe": "\n>>> Rueckwaerts gebaut: GF-Stueck %1 mm (horizontal), Anfangshoehe %2 mm.",
|
||||
"vfl-rueck-erfolg-parallel": "\n>>> Rueckwaerts, parallel zum Kreisel: GF-Stueck %1 mm (horizontal), Bogen %2 Grad %3.",
|
||||
"vfl-par-prompt-abstand": "\n\nAbstand zum Kreisel (mm, senkrecht zur Zufuehrungsachse, von AS-KS_EIN bis Bogen-KS_AUS): ",
|
||||
"vfl-par-nur-kettenanfang": "'Parallel zum Kreisel' geht nur am Kettenanfang mit AS-Element UND festgelegter Zufuehrungsachse (2. Punkt im AS-Dialog).",
|
||||
"vfl-par-kein-bogen": "Kein GF-Bogen hebt den AS-Schwenk von %1 Grad auf (Seite %2) - parallel zum Kreisel nicht schliessbar.",
|
||||
"vfl-par-kein-versatz": "Das AS-Element schwenkt nicht aus der Zufuehrungsachse heraus - so laesst sich kein Abstand erreichen.",
|
||||
"vfl-par-zu-klein": "Abstand %1 mm zu klein: AS und Bogen allein brauchen schon %2 mm. Bitte groesseren Abstand waehlen.",
|
||||
"vfl-par-erfolg": "\n>>> Parallel zum Kreisel: GF-Stueck %1 mm (horizontal), Bogen %2 Grad %3, erreichter Abstand %4 mm.",
|
||||
"vfl-qc-nur-kettenanfang": "\nFEHLER: 'QC Linie mit GF' ist nur am Kettenanfang moeglich (braucht eine eigene AS-Seite) - bitte anderen Modus waehlen.",
|
||||
"vfl-qc-prompt-richtung": "\n\nRichtung waehlen (Gerade, auf der AS-Eintritt und ES-Austritt liegen sollen) - Punkt in Fahrtrichtung anklicken: ",
|
||||
"vfl-qc-ks-ein-gemessen": "\n>>> AS KS_EIN (Referenzgerade) gemessen: X=%1 Y=%2 Z=%3",
|
||||
@@ -99,6 +121,11 @@
|
||||
"vfl-es-setzen-frage": "\n\nES-Element setzen?",
|
||||
"vfl-es-nein-zielpunkt": "\n 2 - Nein (Kette endet direkt am Zielpunkt)",
|
||||
"vfl-prompt-endpunkt-fahrtrichtung": "\n\nEndpunkt entlang Fahrtrichtung waehlen (bestimmt die Laenge): ",
|
||||
"vfl-prompt-as-achse-p2": "\n\nZufuehrungsachse - 2. Punkt (gibt nur die Richtung, der Startpunkt bleibt): ",
|
||||
"vfl-basislinie-punkte-gleich": "\n Die beiden Punkte sind identisch - keine Richtung bestimmbar. Abbruch.",
|
||||
"vfl-basislinie-info": "\n Zufuehrungsachse (Fahrtrichtung): %1 Grad.",
|
||||
"vfl-basislinie-ohne": "\n Keine Zufuehrungsachse festgelegt - die Richtung ergibt sich aus dem naechsten Klick.",
|
||||
"vfl-as-seite-ermittelt": "\n AS-Seite aus der Lage des naechsten Punkts: %1",
|
||||
"vfl-endpunkt-modus-header": "\n\nWie soll der Endpunkt bestimmt werden?",
|
||||
"vfl-endpunkt-modus-opt-linie": "\n 1 - Ziellinie zeichnen (2 Punkte) - der Schnittpunkt bestimmt die Laenge",
|
||||
"vfl-prompt-ziellinie-p1": "\n\nZiellinie - 1. Punkt (beliebige Richtung, Z wird ignoriert): ",
|
||||
@@ -122,7 +149,9 @@
|
||||
"vfl-edit-kette-header": "\n\nLinienzug mit %1 Glied(ern):",
|
||||
"vfl-edit-abgespielt": "\n>>> %1 Glied(er) werden abgespielt, %2 zurueckgenommen - danach interaktiv weiter.",
|
||||
"vfl-edit2-reset-info": "\n>>> Linienzug (Modus 2) wird mit den gespeicherten Angaben identisch neu aufgebaut...",
|
||||
"vfl-konvert-fehler": "\n>>> FEHLER bei der Umwandlung von %1: %2 - der alte Block ist entfernt, die Teil-Geometrie liegt frei in der Zeichnung.",
|
||||
"vfl-konvert-fehler": "\n>>> FEHLER bei der Umwandlung von %1: %2 - der alte Block bleibt unveraendert stehen.",
|
||||
"vfl-konvert-grund-journal": "Journal reicht nicht aus (%1)",
|
||||
"vfl-konvert-grund-kein-block": "kein Block erzeugt",
|
||||
"vfl-restore-prompt-auswahl": "\nLose Linienzug-Geometrie waehlen (die Sektions-XDATA der Objekte wird ausgelesen):",
|
||||
"vfl-restore-keine-sektionen": "\n>>> In der Auswahl steckt keine Sektions-XDATA (SSG_VF_EDIT_SEG) - daraus laesst sich keine Kette wiederherstellen.",
|
||||
"vfl-restore-luecke": "\n>>> WARNUNG: Sektion %1 fehlt in der Auswahl - nur die Glieder 1..%2 werden wiederhergestellt.",
|
||||
@@ -169,7 +198,7 @@
|
||||
"vfl-soll-xyz": "\n Soll: X=%1 Y=%2 Z=%3",
|
||||
"vfl-ist-xyz": "\n Ist : X=%1 Y=%2 Z=%3",
|
||||
"vfl-abweichung-xyz": "\n Abweichung: dX=%1 dY=%2 dZ=%3 mm",
|
||||
"vfl-m3-titel": "\n VF-LINIENZUG - Modus 2: Pfad + Ziel-Hoehe (fertig; Anker + Solver + Bau)",
|
||||
"vfl-m3-titel": "\n VF-LINIENZUG - Modus 2: aus 3D Linie MIT Zielhoehe (Anker + Solver + Bau)",
|
||||
"vfl-m3-alert-gf-modul": "Gefaellestrecke-Modul nicht geladen!",
|
||||
"vfl-m3-pfad-waehlen": "\n\nPfad-Objekte waehlen (Linien/Boegen):",
|
||||
"vfl-m3-keine-objekte": "\nKeine Objekte gewaehlt - Abbruch.",
|
||||
@@ -224,13 +253,24 @@
|
||||
"vfl-m3-kletter-zu-kurz-flach": "\n Kein Kletter-Winkel passt (Segment zu kurz) -> Lauf wird komplett flach gebaut, Hoehe wandert in GF1.",
|
||||
"vfl-m3-kletter-flach-gf": "\n Flache Zone: GF-Kompensation (GF1) = %1 mm",
|
||||
"vfl-m3-alert-vf-zu-lang": "VF-Lauf ist %1 m lang (Grenze %2 m) - bitte neu planen (z.B. Zwischen-Motorstation einfuegen).",
|
||||
"vfl-m2-einheit-grenze": "Diese VF-Einheit ist so nicht baubar.\n\nGemessen: %1 m Laenge, %2 Vario-Kurven.\nErlaubt je Einheit (zwischen Umlenk- und Motorstation): hoechstens %3 m und %4 Vario-Kurven.\n\nBitte den Bogen in Segment %5 als GF-Bogen klassifizieren - dann endet die erste Einheit davor mit einer Motorstation und die zweite beginnt danach mit einer Umlenkstation.",
|
||||
"vfl-m2-einheit-grenze-unteilbar": "Diese VF-Einheit ist so nicht baubar.\n\nGemessen: %1 m Laenge, %2 Vario-Kurven.\nErlaubt je Einheit (zwischen Umlenk- und Motorstation): hoechstens %3 m und %4 Vario-Kurven.\n\nEs gibt keinen Bogen, an dem sich der Lauf teilen liesse - bitte den Pfad kuerzer fassen oder eine Ecke einplanen, an der die Einheit enden kann.",
|
||||
"vfl-m3-warnung-fueller-eingang-zu-kurz": "\n WARNUNG: Fueller direkt nach der Umlenkstation zu kurz (%1 mm < Minimum %2 mm) - nur Minimalabstand gebaut, Zielposition nicht exakt erreicht.",
|
||||
"vfl-m3-warnung-fueller-ausgang-zu-kurz": "\n WARNUNG: Fueller direkt vor der Motorstation zu kurz (%1 mm < Minimum %2 mm) - nur Minimalabstand gebaut, Zielposition nicht exakt erreicht.",
|
||||
"vfl-m3-lauf-anfang-header": "\n\nDer VF-Lauf ist der Anfang des gewaehlten Pfads. Lauf beginnen mit:",
|
||||
"vfl-m3-lauf-anfang-opt-offen": "\n 1 - Ohne Umlenkstation (offener Anfang, spaeter fortsetzen/verschmelzen)",
|
||||
"vfl-m3-lauf-anfang-opt-offen": "\n 3 - Ohne Umlenkstation (offener Anfang, spaeter fortsetzen/verschmelzen)",
|
||||
"vfl-m3-lauf-anfang-opt-umlenk": "\n 2 - Umlenkstation direkt (kein GF1/Separator)",
|
||||
"vfl-m3-lauf-anfang-opt-umlenk-gf1": "\n 3 - Umlenkstation mit GF1 + Separator",
|
||||
"vfl-m3-lauf-anfang-opt-umlenk-gf1": "\n 1 - Umlenkstation mit GF1 + Separator",
|
||||
"vfl-m2-uebergang-bogen-fehlt": "Uebergangsbogen %1 fehlt in der Bogen-Tabelle - der Block ist nicht ladbar oder hat kein messbares KS. Der Lauf wird ohne seinen Laengenanteil gebaut und faellt dadurch um dessen Laenge zu lang aus.",
|
||||
"vfl-m2-segwert-unbekannt": "Segment %1 nicht lesbar: Kette %2 enthaelt einen unbekannten Klassifizierungswert. Aufbau abgebrochen - ein geratener Segmenttyp wuerde die Kette falsch neu bauen.",
|
||||
"vfl-m2-eck-korrektur": "\n Eck-Korrektur %1 mm auf Segment %2 (gezeichneter Bogen gegen Fussabdruck des Eck-Bauteils).",
|
||||
"vfl-m2-abschluss-fussabdruck": "\n Abschluss-Fussabdruck %1 mm von Segment %2 abgezogen (Abschlussbogen + Motorstation stehen darauf).",
|
||||
"vfl-m2-kletter-ende-fussabdruck": "\n Kletter-Ende: %1 mm von Segment %2 abgezogen (Motorstation + Separator + ES stehen auf dem Kletterer, nicht auf einem Fueller).",
|
||||
"vfl-m2-as-fussabdruck": "\n AS-Fussabdruck %1 mm von Segment %2 abgezogen (das AS-Element steht selbst darauf).",
|
||||
"vfl-m2-anfang-wert-unbekannt": "Lauf-Anfang nicht lesbar: Kette %1 enthaelt den unbekannten Wert %2. Aufbau abgebrochen - eine geratene Anfangsvariante wuerde die Kette falsch neu bauen.",
|
||||
"vfl-m3-lauf-anfang-offen-hinweis": "\n Anfang bleibt bewusst offen - keine Umlenkstation/GF1/Separator gebaut, spaeter fortsetzen oder per Vario_Kette_Merge verbinden.",
|
||||
"vfl-m2-anfang-offen-gesperrt-zeile": "\n (nicht waehlbar - mit AS-Element braucht der Lauf eine Umlenkstation)",
|
||||
"vfl-m2-anfang-offen-gesperrt": "Mit AS-Element ist ein offener Anfang nicht moeglich - der Lauf braucht dann eine Umlenkstation.",
|
||||
"vfl-m3-lauf-abschluss-header": "\n\nDer VF-Lauf ist das Ende des gewaehlten Pfads. Lauf beenden mit:",
|
||||
"vfl-m3-lauf-abschluss-opt-offen": "\n 1 - Ohne Motorstation (offenes Ende, spaeter fortsetzen/verschmelzen)",
|
||||
"vfl-m3-lauf-abschluss-opt-motor": "\n 2 - Motorstation setzen (kein ES-Element)",
|
||||
@@ -246,6 +286,7 @@
|
||||
"vfl-m3-gf2-ausgleich": "\n GF2 (gemessener Ausgleich): L=%1 mm",
|
||||
"vfl-m3-kurve-back-uebersprungen": "\n >>> [M3a] Vario-Kurve im Back-Lauf - uebersprungen.",
|
||||
"vfl-m3-nichts-gebaut": "\nNichts gebaut - Abbruch.",
|
||||
"vfl-m3-alt-journal": "\n Hinweis: Diese Kette stammt aus der Zeit vor den Fragen AS bauen / ES bauen - sie wird in der alten Reihenfolge nachgebaut.",
|
||||
"vfl-m3-fertig-header": "\n>>> VF-Linienzug (Modus 2) gebaut! <<<",
|
||||
"vfl-m3-ziel-soll": "\n Ziel (Soll): X=%1 Y=%2 Z=%3",
|
||||
"vfl-m3-es-ist": "\n ES (Ist): X=%1 Y=%2 Z=%3",
|
||||
@@ -280,6 +321,7 @@
|
||||
"kreisel-edit-bestehend": "\n-> Bestehend: Abstand=%1 Drehung=%2 Art=%3",
|
||||
"kreisel-edit-dialog-fehlt": "Dialog nicht verfuegbar: %1",
|
||||
"kreisel-eingefuegt": "\n-> Kreisel #%1 eingefügt: %2 (Höhe=%3)",
|
||||
"kreisel-emsg-abstand-zu-klein": "Abstand zu klein! (%1 < %2) - die Endkreise wuerden sich beruehren/ueberschneiden.",
|
||||
"kreisel-emsg-distanz-klein": "Distanz zu klein! (%1 < %2)",
|
||||
"kreisel-hoehe-aus-3dpunkt": "\n-> Hoehe aus 3D-Punkt uebernommen: %1",
|
||||
"kreisel-hoehe-aus-basispunkt": "\n-> Höhe aus Basispunkt übernommen: %1",
|
||||
@@ -633,6 +675,8 @@
|
||||
"dim-switch-blocks": "\n DXFM_BLOCKS = %1",
|
||||
"dim-switch-omniflo": "\n DXFM_OMNIFLO = %1",
|
||||
"dim-batch-fertig": "\nUmwandlung auf %1 abgeschlossen: %2 GF, %3 VF neu aufgebaut (%4 bereits in Zieldimension).",
|
||||
"dim-batch-fehlerliste": "\n%1 Linienzug-Block/Bloecke NICHT umgewandelt (unveraendert stehen gelassen):",
|
||||
"dim-batch-fehler-zeile": "\n - %1: %2",
|
||||
"sprache-gewechselt": "\nSprache umgeschaltet auf: %1",
|
||||
"cmd-block-auswaehlen": "\nBlock auswaehlen: ",
|
||||
"cmd-kein-block-ausgewaehlt": "\nKein Block ausgewaehlt.",
|
||||
@@ -685,6 +729,9 @@
|
||||
"plq-geloescht": "\n[DELETE_PLANQUADRATE] Planquadrat-Raster entfernt (%1 Einfuegung(en)).",
|
||||
"plq-nichts-zu-loeschen": "\n[DELETE_PLANQUADRATE] Kein Planquadrat-Raster in der Zeichnung vorhanden.",
|
||||
"exp-check-ids": "\n[%1] Pruefe und vergebe IDs...",
|
||||
"exp-hoehencheck-frage": "\nVor dem Export den Hoehen-Check (Montagehoehe/Buehnen) ausfuehren?",
|
||||
"exp-bereinigen": "\nBereinige Zeichnung (PURGE: unbenutzte Bloecke, Layer, Linientypen) ...",
|
||||
"exp-hoehencheck-fehlt": "\nHinweis: HOEHEN_CHECK nicht verfuegbar - Export laeuft ohne Hoehen-Check.",
|
||||
"exp-hoehen-aktualisiert": "\nHoehen-Attribute von %1 verschobenen Bloecken aus der Z-Koordinate neu gesetzt.",
|
||||
"exp-sep-proxy-fehler": "\n[EXPORT] WARNUNG: Kopie von '%1' aus Block '%2' fehlgeschlagen (%3) - dieses Element fehlt im Export.",
|
||||
"exp-sep-zuordnung": "\n[%1] verpackte Separator-Kopie(n): ZUORDNUNG aus der ID des Wrapper-Blocks gesetzt.",
|
||||
@@ -913,6 +960,16 @@
|
||||
"tro-insert-kein-block": "Kein Symbol fuer diesen Typ in der Zeichnung (%1) - bitte tro_annotate.py mit diesem Typ laufen lassen.",
|
||||
"tro-insert-prompt-punkt": "\nEinfuegepunkt: ",
|
||||
"tro-insert-eingefuegt": "\nTRO eingefuegt: ID = %1, TYP = %2",
|
||||
"cmd-jam-bearbeiten": "\nStaubereich bearbeiten: %1",
|
||||
"jam-edit-kein-jam": "Block %1 ist kein Staubereich (erwartet JAM_*).",
|
||||
"jam-edit-dialog-fehlt": "Dialogdatei nicht gefunden:\n%1\nDXFM_DCL pruefen (setenv.bat).",
|
||||
"jam-edit-bereich": "Staubereich %1 vor %2 (Eingang %3)",
|
||||
"jam-edit-auto": "Abgeleitet: %1",
|
||||
"jam-edit-hinweis": "In die SCL: tro_annotate --read-jams, danach scl_skeleton.",
|
||||
"jam-edit-foerderer-ungueltig": "Der Foerderer muss vierstellig sein (z. B. 0054) - nichts geaendert.",
|
||||
"jam-edit-nummer-ungueltig": "Die laufende Nummer muss eine ganze Zahl ab 1 sein - nichts geaendert.",
|
||||
"jam-edit-gespeichert": "\nStaubereich gespeichert: %1 (%2)",
|
||||
"jam-edit-doppelt": "\nACHTUNG: %1 gibt es schon in dieser Zeichnung (%2).",
|
||||
"vfl-abbruch-gesichert": "\n>>> Linienzug abgebrochen: %1 Objekt(e) als Block gesichert (per Doppelklick editierbar/fortsetzbar).",
|
||||
"vfl-zurueck-glied-verworfen": "\n>>> Zurueck: letztes Kettenglied wird verworfen - bitte neu beantworten.",
|
||||
"vfl-abbruch-nichts-gebaut": "\n>>> Abgebrochen - es wurde noch keine Geometrie erzeugt.",
|
||||
@@ -929,13 +986,13 @@
|
||||
"vfc-warnung-untermodule-nicht-geladen": "\n[vf_core] WARNUNG: DXFM_LISP nicht gesetzt - Untermodule konnten nicht geladen werden!",
|
||||
"vfc-linienzug-modus-header": "\n\nLinienzug-Modus waehlen:",
|
||||
"vfc-linienzug-modus-1": "\n 1 - Manuelle Eingabe (Punkte klicken)",
|
||||
"vfc-linienzug-modus-2": "\n 2 - 3D-Objekte + Ziel-Hoehe (Randwert-Solver, fertig)",
|
||||
"vfc-linienzug-modus-3": "\n 3 - 3D-Objekte stueckweise (Vorwaerts-Nachbau, in Arbeit)",
|
||||
"vfc-linienzug-modus-2": "\n 2 - aus 3D Linie MIT Zielhoehe (Hoehen werden gerechnet)",
|
||||
"vfc-linienzug-modus-3": "\n 3 - aus 3D Linie OHNE Zielhoehe (Vorwaerts-Bau mit vorgegebenen Winkeln)",
|
||||
"prompt-wahl-1-3": "\nIhre Wahl (1/2/3) [1]: ",
|
||||
"vfl-qc-uform-nicht-implementiert": "\nFEHLER: 'QC Linie mit GF und U-Form' ist noch nicht implementiert - bitte Option 4 oder einen anderen Modus waehlen.",
|
||||
"vfc-typ-standard-beschreibung": "Standard VarioFoerderer (AS/ES 90 Grad, horizontal versetzt)",
|
||||
"vfc-typ-etage-beschreibung": "Etage VarioFoerderer (AS/ES 30 Grad, direkt uebereinander)",
|
||||
"vfc-typ-linienzug-beschreibung": "Streckengruppe (gemischte GF/VF-Kette; Modus 1 manuell / Modus 2 Ziel-Hoehe fertig / Modus 3 stueckweise in Arbeit)",
|
||||
"vfc-typ-linienzug-beschreibung": "Streckengruppe (gemischte GF/VF-Kette; Modus 1 manuell / Modus 2 aus 3D Linie mit Zielhoehe / Modus 3 aus 3D Linie ohne Zielhoehe)",
|
||||
"vfs-schritt6-horizontal": "\n\n6/11: Horizontale Zwischenstrecke (0 Grad, L=%1 mm)",
|
||||
"vfs-schritt6-steigung": "\n\n6/11: Steigungsstrecke (%1 Grad, L=%2 mm)",
|
||||
"vfs-schritt6-gefaelle": "\n\n6/11: Gefaellestrecke (%1 Grad, L=%2 mm)",
|
||||
@@ -964,7 +1021,7 @@
|
||||
"vfe-step14": "\n\n14/15: Separator (300mm, cur-hz=%1)",
|
||||
"vfe-step15": "\n\n15/15: %1 (Ende, verkettet cur-hz=%2)",
|
||||
"vfe-eingefuegt": "\n>>> Etage-VarioFoerderer eingefuegt! <<<",
|
||||
"vfl-vwnb-titel": "\n VF-LINIENZUG - Modus 3: 3D-Objekte stueckweise (Vorwaerts-Nachbau, in Arbeit)",
|
||||
"vfl-vwnb-titel": "\n VF-LINIENZUG - Modus 3: aus 3D Linie OHNE Zielhoehe (Vorwaerts-Bau)",
|
||||
"vfl-vwnb-aus-seite-menu": "\n\nAUS-Element - Seite waehlen:\n 1 - Links\n 2 - Rechts",
|
||||
"vfl-vwnb-alert-eckwinkel": "Kein passender Bogen: Eck-Winkel %1 Grad ist nicht ~30/60/90.\nBitte die Winkel der Linien anpassen.",
|
||||
"vfl-vwnb-alert-keine-gerade": "Pfad enthaelt keine Gerade - eine Kette muss mit einer Geraden beginnen.",
|
||||
@@ -1120,6 +1177,16 @@
|
||||
"kreisel-bp-zeile": "\n Weiche %1: %2 <-> %3 [%4] bei X=%5 Y=%6 Z=%7",
|
||||
"kreisel-bp-kollision": "\n KOLLISION %1: %2 <-> %3 [%4] bei X=%5 Y=%6 Z=%7",
|
||||
"kreisel-bp-marker": "\n%1 Marker gezeichnet (Layer %2).",
|
||||
"chh-start": "\n--- Phase 3: Buehnen-Familien ---",
|
||||
"chh-kein-kreisel": "\n Hinweis: Kreisel-Modul nicht verfuegbar - nur blockweise Abfrage.",
|
||||
"chh-fam-frage": "\n Familie %1 (%2, %3 Kreisel, Montagehoehe %4 m): liegt auf einer Buehne?",
|
||||
"chh-schleife": "\n %1: flache Schleife am selben Kreisel (VON = BIS) - wird einzeln gefragt.",
|
||||
"chh-buehne-hoehe": "Buehnenhoehe in m",
|
||||
"chh-buehne-ungueltig": "\n ! Buehnenhoehe muss > 0 und < %1 m sein.",
|
||||
"chh-kreuz-konflikt": "\n ! %1: Enden in Familien mit verschiedener Buehnenhoehe (%2 / %3 m) - nicht geaendert.",
|
||||
"chh-kreuz-hoehe": "\n ! %1: Familienhoehen unterscheiden sich um %2 mm (> %3 mm) - nicht geaendert.",
|
||||
"chh-strecke-neg": "\n ! %1: Buehne %2 m >= Montagehoehe %3 m - nicht geaendert.",
|
||||
"chh-summe": "\n Phase 3: %1 Familie(n), %2 mit Buehne; angepasst: Kreisel %3, Strecken innerhalb %4, zwischen Familien %5; Konflikte %6; einzeln gefragt %7",
|
||||
"exp-kreisel-weichen": "\n[%1] Kreisel-Weichenpunkte: %2 Beruehrung(en), %3 Kollision(en) -> %4",
|
||||
"exp-kreisel-kollision": "\n[%1] WARNUNG: %2 Kreisel-Kollision(en) - Befehl KREISEL_WEICHEN zeigt sie an.",
|
||||
"lg-daten-fehlt": "\n[Lager] Datendatei nicht gefunden: %1 - es gelten die eingebauten Vorgaben.",
|
||||
@@ -1219,6 +1286,58 @@
|
||||
"lg-regel-profil-fehlt": "\n[Lager] Regelprofil %1 nicht gefunden (%2).",
|
||||
"lg-regel-profil-ungepflegt": "\n[Lager] WARNUNG: Regelprofil %1 ist nicht gepflegt - es gelten die geerbten Werte.",
|
||||
"lg-regel-unbekannt": "\n[Lager] Regel %1 nicht im Profil.",
|
||||
"lg-regel-liste-kopf": "\nRegelprofil %1: %2 Regeln (Kontext: erhoehte Brandgefaehrdung ohne Loeschanlage)"
|
||||
"lg-regel-liste-kopf": "\nRegelprofil %1: %2 Regeln (Kontext: erhoehte Brandgefaehrdung ohne Loeschanlage)",
|
||||
"kf-fehler-daten-fehlt": "\nFEHLER: Kettenfoerderer-Daten nicht gefunden: %1",
|
||||
"kf-fehler-daten-leer": "\nFEHLER: Kettenfoerderer-Daten konnten nicht gelesen werden.",
|
||||
"kf-fehler-block-datei": "\nFEHLER: Blockdatei fuer %1 nicht gefunden (erwartet in data/omniflo/<Dimension>/).",
|
||||
"kf-fehler-ks-fehlt": "In mindestens einem Baustein fehlt KS_EIN oder KS_AUS - die Kette kann nicht verkettet werden. Befehl KF_KS_PRUEFEN zeigt, welcher Block betroffen ist.",
|
||||
"kf-fehler-hoehe-zu-klein": "Die Einbauhoehe ist zu klein: Umlenk- und Antriebsstation bringen bereits mehr Hoehe mit, als gefordert ist. Bitte groessere Hoehe waehlen.",
|
||||
"kf-fehler-laenge-unter-min": "Das Zwischenstueck waere kuerzer als zulaessig. Bitte groessere Einbauhoehe waehlen.",
|
||||
"kf-fehler-laenge-ueber-max": "Das Zwischenstueck waere laenger als zulaessig. Bitte kleinere Einbauhoehe waehlen.",
|
||||
"kf-fehler-winkel-null": "Der gemessene Einbauwinkel des Zwischenstuecks ist waagerecht - damit laesst sich keine Hoehe erreichen. Bitte die KS-Lage der Bloecke pruefen (KF_KS_PRUEFEN).",
|
||||
"kf-fehler-dcl": "Dialogdatei kettenfoerderer.dcl nicht gefunden.",
|
||||
"kf-prompt-messpunkt-1": "\nErsten Messpunkt waehlen (Hoehenbezug unten): ",
|
||||
"kf-prompt-messpunkt-2": "\nZweiten Messpunkt waehlen (Hoehenbezug oben): ",
|
||||
"kf-messung-ergebnis": "\n>>> Gemessen: Hoehendifferenz dZ = %1 mm (zur Kontrolle dY = %2 mm).",
|
||||
"kf-konsole-hoehe-hinweis": "\n(0 eingeben, um die Hoehe aus zwei Punkten zu messen)",
|
||||
"kf-2d-gebaut": "\n>>> Draufsicht %1 eingefuegt: Schraeglaenge %2 mm, Neigung %3 Grad.",
|
||||
"kf-2d-laenge-null": "\nDraufsicht uebersprungen: die Kette hat keine messbare Grundrisslaenge.",
|
||||
"kf-2d-ks-fehlt": "\nDraufsicht uebersprungen: %1 hat kein messbares KS_EIN/KS_AUS.",
|
||||
"kf-prompt-startpunkt": "\nEinfuegepunkt waehlen (KS_EIN der Draufsicht; die Seitenansicht entsteht darueber): ",
|
||||
"kf-prompt-drehung": "\nDrehwinkel der Kette: ",
|
||||
"kf-abgebrochen": "\nAbgebrochen.",
|
||||
"kf-fertig": "\n>>> %1 erstellt: Einbauhoehe %2 mm, Zwischenstueck %3 mm.",
|
||||
"kf-konsole-variante-header": "\n\nSchraegfoerderer Stahl Typ waehlen:",
|
||||
"kf-konsole-option": "\n %1 - %2",
|
||||
"kf-konsole-variante-prompt": "\nSchraegfoerderer Stahl Typ",
|
||||
"kf-konsole-hoehe-prompt": "\nH - Einbauhoehe Schraegfoerderer [mm]",
|
||||
"kf-konsole-verbindung-header": "\n\nVerbindungselemente waehlen:",
|
||||
"kf-konsole-verbindung-prompt": "\nVerbindungselemente",
|
||||
"kf-konsole-farbe-header": "\n\nFarbe Foerderer waehlen:",
|
||||
"kf-konsole-farbe-prompt": "\nFarbe",
|
||||
"kf-konsole-antriebsmotor-header": "\n\nAntriebsmotor Foerderer waehlen:",
|
||||
"kf-konsole-antriebsmotor-prompt": "\nAntriebsmotor Foerderer",
|
||||
"kf-variante-label": "%1 %2",
|
||||
"kf-variante-label-standard": "%1 %2 (Standard)",
|
||||
"kf-konsole-movimot-header": "\n\nAntrieb mit Movimot?",
|
||||
"kf-konsole-movimot-prompt": "\nAntrieb mit Movimot",
|
||||
"kf-konsole-steuerung-header": "\n\nMit Standard Steuerung?",
|
||||
"kf-konsole-steuerung-prompt": "\nMit Standard Steuerung",
|
||||
"kf-pruef-kopf": "\n\n=== KF_KS_PRUEFEN: KS-Lage der Kettenfoerderer-Bloecke ===",
|
||||
"kf-pruef-variante": "\n\n--- Variante: %1 ---",
|
||||
"kf-pruef-block": "\n %1: KS_EIN (%2, %3) Richtung %4 | KS_AUS (%5, %6) Richtung %7",
|
||||
"kf-pruef-block-fehlt": "\n %1: Blockdatei nicht gefunden.",
|
||||
"kf-pruef-ks-fehlt": "\n %1: KS unvollstaendig - KS_EIN: %2, KS_AUS: %3",
|
||||
"kf-pruef-ks-fehlt-kurz": "\n[KF] KS_EIN/KS_AUS nicht lesbar am Baustein: %1 (Befehl KF_KS_PRUEFEN zeigt Einzelheiten)",
|
||||
"kf-pruef-fehler": "\n Geometrie nicht ermittelbar: %1",
|
||||
"kf-pruef-geo": "\n Einbauwinkel (Grad): Umlenkung %1, Zwischenstueck %2, Antrieb %3\n Hoehenbeitrag (mm): Umlenkung %4, Antrieb %5\n Zwischenstueck nativ (mm): dx %6, dy %7",
|
||||
"kf-pruef-ja": "vorhanden",
|
||||
"kf-pruef-nein": "FEHLT",
|
||||
"kf-edit-waehlen": "\nKettenfoerderer (KF_n) zum Bearbeiten waehlen: ",
|
||||
"kf-edit-kein-kf": "Der gewaehlte Block ist kein Kettenfoerderer (KF_n).",
|
||||
"kf-edit-fertig": "\n>>> %1 neu aufgebaut als %2.",
|
||||
"cmd-kettenfoerderer-bearbeiten": "\n>>> Kettenfoerderer %1 wird bearbeitet ...",
|
||||
"vfl-m2-nachrechnen": "\n Gefalteter Lauf: Laengen bei gleichem Winkel neu aufgeteilt - GF %1 -> %2 mm, Kletterstrecke %3 mm (GF1 liegt im Eingangs-Schenkel und verbraucht die Kletterer-Spanne nicht).",
|
||||
"vfl-m2-nachrechnen-fehl": "Der gewaehlte Winkel %1 Grad geht mit der korrigierten Laengenbilanz nicht mehr auf. Die Kette wird mit der urspruenglichen Aufteilung gebaut und kann daher am Ende zu frueh enden - bitte den Ist/Soll-Vergleich pruefen oder einen anderen Winkel waehlen."
|
||||
}
|
||||
}
|
||||
|
||||
+128
-9
@@ -9,6 +9,7 @@
|
||||
"vfl-as-auto-erkannt": "\n>>> Start point lies on the KS_AUS of an existing %1 chain - no AS element needed.",
|
||||
"vfl-familie-neutral": "GF/VF",
|
||||
"vfl-sep-nach-durch-es-ueberschrieben": "\n>>> Separator AFTER ignored - the ES element already brings its own separator at the chain end (otherwise two separators in a row).",
|
||||
"vfl-sep-gf-es-automatisch": "(A separator between GF and ES is inserted automatically.)",
|
||||
"vfl-echo-position": "\n>>> Position: X=%1 Y=%2 Z=%3",
|
||||
"vfl-echo-wahl": "\n>>> Selected: %1",
|
||||
"vfl-aus-seite-header": "\n\nOUT element (AS_Element_*) - select side:",
|
||||
@@ -55,6 +56,27 @@
|
||||
"vfl-gf-laenge-modus-opt-hoehe": "\n 2 - Set target height (length will be calculated)",
|
||||
"vfl-gf-laenge-modus-opt-steigend": "\n 3 - Rising GF (special case, up to 3 degrees)",
|
||||
"vfl-gf-laenge-modus-opt-qc": "\n 4 - QC line with GF (automatic up/down calculation)",
|
||||
"vfl-gf-laenge-modus-opt-parallel": "\n 5 - Continue parallel to the carousel (distance only)",
|
||||
"vfl-richtung-header": "\n\nIn which direction should the chain be built?",
|
||||
"vfl-richtung-opt-vor": "\n 1 - Build forwards (the picked point is the start of the chain)",
|
||||
"vfl-richtung-opt-rueck": "\n 2 - Build backwards (the picked point is the end of the chain, ES outlet)",
|
||||
"vfl-prompt-es-achse-p2": "\n\nTravel direction - 2nd point (defines the direction only, the end point stays): ",
|
||||
"vfl-es-basislinie-info": "\n Outfeed axis (travel direction): %1 degrees.",
|
||||
"vfl-rueck-menu-linie-gf": "\n 1 - New line: GF (gravity section)",
|
||||
"vfl-rueck-laenge-opt-anfangspunkt": "\n 1 - Pick start of chain (length results, start height is calculated)",
|
||||
"vfl-rueck-laenge-opt-anfangshoehe": "\n 2 - Set start height (length will be calculated)",
|
||||
"vfl-rueck-prompt-anfangspunkt": "\n\nPick the start of the chain (direction is fixed by the outfeed axis): ",
|
||||
"vfl-rueck-prompt-anfangshoehe": "\nDesired height at the start of the chain (mm) <%1>: ",
|
||||
"vfl-rueck-alert-hoehe-zu-klein": "The start of the chain must be HIGHER than its end - a gravity section falls in the travel direction.",
|
||||
"vfl-rueck-erfolg-punkt": "\n>>> Built backwards: GF section %1 mm (horizontal), start height %2 mm.",
|
||||
"vfl-rueck-erfolg-hoehe": "\n>>> Built backwards: GF section %1 mm (horizontal), start height %2 mm.",
|
||||
"vfl-rueck-erfolg-parallel": "\n>>> Backwards, parallel to the carousel: GF section %1 mm (horizontal), bend %2 degrees %3.",
|
||||
"vfl-par-prompt-abstand": "\n\nDistance to the carousel (mm, perpendicular to the feed axis, from AS KS_EIN to bend KS_AUS): ",
|
||||
"vfl-par-nur-kettenanfang": "'Parallel to the carousel' only works at the start of a chain with an AS element AND a defined feed axis (2nd point in the AS dialog).",
|
||||
"vfl-par-kein-bogen": "No GF bend cancels the AS plan turn of %1 degrees (side %2) - cannot close parallel to the carousel.",
|
||||
"vfl-par-kein-versatz": "The AS element does not turn away from the feed axis - no distance can be reached this way.",
|
||||
"vfl-par-zu-klein": "Distance %1 mm too small: AS and bend alone already need %2 mm. Please choose a larger distance.",
|
||||
"vfl-par-erfolg": "\n>>> Parallel to the carousel: GF section %1 mm (horizontal), bend %2 degrees %3, resulting distance %4 mm.",
|
||||
"vfl-qc-nur-kettenanfang": "\nERROR: 'QC line with GF' is only possible at the chain start (needs its own AS side) - please choose a different mode.",
|
||||
"vfl-qc-prompt-richtung": "\n\nChoose direction (line on which AS entry and ES exit shall lie) - click a point in the travel direction: ",
|
||||
"vfl-qc-ks-ein-gemessen": "\n>>> AS KS_EIN (reference line) measured: X=%1 Y=%2 Z=%3",
|
||||
@@ -99,6 +121,11 @@
|
||||
"vfl-es-setzen-frage": "\n\nPlace ES element?",
|
||||
"vfl-es-nein-zielpunkt": "\n 2 - No (chain ends directly at the target point)",
|
||||
"vfl-prompt-endpunkt-fahrtrichtung": "\n\nSelect end point along travel direction (defines the length): ",
|
||||
"vfl-prompt-as-achse-p2": "\n\nFeed axis - 2nd point (defines the direction only, the start point stays): ",
|
||||
"vfl-basislinie-punkte-gleich": "\n The two points are identical - no direction can be derived. Aborting.",
|
||||
"vfl-basislinie-info": "\n Feed axis (travel direction): %1 degrees.",
|
||||
"vfl-basislinie-ohne": "\n No feed axis defined - the direction follows from the next click.",
|
||||
"vfl-as-seite-ermittelt": "\n AS side from the position of the next point: %1",
|
||||
"vfl-endpunkt-modus-header": "\n\nHow should the end point be determined?",
|
||||
"vfl-endpunkt-modus-opt-linie": "\n 1 - Draw target line (2 points) - the intersection defines the length",
|
||||
"vfl-prompt-ziellinie-p1": "\n\nTarget line - 1st point (any direction, Z is ignored): ",
|
||||
@@ -122,7 +149,9 @@
|
||||
"vfl-edit-kette-header": "\n\nChain with %1 segment(s):",
|
||||
"vfl-edit-abgespielt": "\n>>> %1 segment(s) replayed, %2 undone - then continue interactively.",
|
||||
"vfl-edit2-reset-info": "\n>>> Rebuilding this Modus-2 chain identically from the saved inputs...",
|
||||
"vfl-konvert-fehler": "\n>>> ERROR converting %1: %2 - the old block is gone, the partial geometry is loose in the drawing.",
|
||||
"vfl-konvert-fehler": "\n>>> ERROR converting %1: %2 - the old block is left unchanged.",
|
||||
"vfl-konvert-grund-journal": "journal is insufficient (%1)",
|
||||
"vfl-konvert-grund-kein-block": "no block created",
|
||||
"vfl-restore-prompt-auswahl": "\nSelect the loose chain geometry (the section XDATA of the objects is read):",
|
||||
"vfl-restore-keine-sektionen": "\n>>> The selection carries no section XDATA (SSG_VF_EDIT_SEG) - no chain can be restored from it.",
|
||||
"vfl-restore-luecke": "\n>>> WARNING: section %1 is missing from the selection - only segments 1..%2 will be restored.",
|
||||
@@ -169,7 +198,7 @@
|
||||
"vfl-soll-xyz": "\n Target: X=%1 Y=%2 Z=%3",
|
||||
"vfl-ist-xyz": "\n Actual: X=%1 Y=%2 Z=%3",
|
||||
"vfl-abweichung-xyz": "\n Deviation: dX=%1 dY=%2 dZ=%3 mm",
|
||||
"vfl-m3-titel": "\n VF LINE PATH - Mode 2: path + target height (finished; anchors + solver + build)",
|
||||
"vfl-m3-titel": "\n VF LINE PATH - Mode 2: from 3D line WITH target height (anchors + solver + build)",
|
||||
"vfl-m3-alert-gf-modul": "Gefaellestrecke module not loaded!",
|
||||
"vfl-m3-pfad-waehlen": "\n\nSelect path objects (lines/arcs):",
|
||||
"vfl-m3-keine-objekte": "\nNo objects selected - aborting.",
|
||||
@@ -224,13 +253,24 @@
|
||||
"vfl-m3-kletter-zu-kurz-flach": "\n No climb angle fits (segment too short) -> run is built entirely flat, height is absorbed by GF1.",
|
||||
"vfl-m3-kletter-flach-gf": "\n Flat zone: GF compensation (GF1) = %1 mm",
|
||||
"vfl-m3-alert-vf-zu-lang": "VF run is %1 m long (limit %2 m) - please re-plan (e.g. insert an intermediate motor station).",
|
||||
"vfl-m2-einheit-grenze": "This VF unit cannot be built like this.\n\nMeasured: %1 m length, %2 vario curves.\nAllowed per unit (between deflection and motor station): at most %3 m and %4 vario curves.\n\nPlease classify the bend in segment %5 as a GF bend - the first unit then ends before it with a motor station and the second one starts after it with a deflection station.",
|
||||
"vfl-m2-einheit-grenze-unteilbar": "This VF unit cannot be built like this.\n\nMeasured: %1 m length, %2 vario curves.\nAllowed per unit (between deflection and motor station): at most %3 m and %4 vario curves.\n\nThere is no bend at which the run could be split - please shorten the path or plan a corner where the unit can end.",
|
||||
"vfl-m3-warnung-fueller-eingang-zu-kurz": "\n WARNING: filler right after the reversing station is too short (%1 mm < minimum %2 mm) - only the minimum clearance was built, target position not reached exactly.",
|
||||
"vfl-m3-warnung-fueller-ausgang-zu-kurz": "\n WARNING: filler right before the motor station is too short (%1 mm < minimum %2 mm) - only the minimum clearance was built, target position not reached exactly.",
|
||||
"vfl-m3-lauf-anfang-header": "\n\nThe VF run is the start of the selected path. Start the run with:",
|
||||
"vfl-m3-lauf-anfang-opt-offen": "\n 1 - No reversing station (open start, continue/merge later)",
|
||||
"vfl-m3-lauf-anfang-opt-offen": "\n 3 - No reversing station (open start, continue/merge later)",
|
||||
"vfl-m3-lauf-anfang-opt-umlenk": "\n 2 - Reversing station directly (no GF1/separator)",
|
||||
"vfl-m3-lauf-anfang-opt-umlenk-gf1": "\n 3 - Reversing station with GF1 + separator",
|
||||
"vfl-m3-lauf-anfang-opt-umlenk-gf1": "\n 1 - Reversing station with GF1 + separator",
|
||||
"vfl-m2-uebergang-bogen-fehlt": "Transition bend %1 is missing from the bend table - the block cannot be loaded or has no measurable KS. The run is built without its length share and therefore comes out too long by that amount.",
|
||||
"vfl-m2-segwert-unbekannt": "Segment %1 cannot be read: chain %2 contains an unknown classification value. Build aborted - guessing a segment type would rebuild the chain incorrectly.",
|
||||
"vfl-m2-eck-korrektur": "\n Corner correction %1 mm on segment %2 (drawn arc versus footprint of the corner component).",
|
||||
"vfl-m2-abschluss-fussabdruck": "\n Closing footprint %1 mm deducted from segment %2 (closing bend + motor station sit on it).",
|
||||
"vfl-m2-kletter-ende-fussabdruck": "\n Climbing end: %1 mm deducted from segment %2 (motor station + separator + ES sit on the climber, not on a filler).",
|
||||
"vfl-m2-as-fussabdruck": "\n AS footprint %1 mm deducted from segment %2 (the AS element sits on it).",
|
||||
"vfl-m2-anfang-wert-unbekannt": "Cannot read run start: chain %1 contains the unknown value %2. Build aborted - guessing a start variant would rebuild the chain incorrectly.",
|
||||
"vfl-m3-lauf-anfang-offen-hinweis": "\n Start deliberately left open - no reversing station/GF1/separator built; continue later or join with Vario_Kette_Merge.",
|
||||
"vfl-m2-anfang-offen-gesperrt-zeile": "\n (not selectable - with an AS element the run needs a reversing station)",
|
||||
"vfl-m2-anfang-offen-gesperrt": "With an AS element an open start is not possible - the run then needs a reversing station.",
|
||||
"vfl-m3-lauf-abschluss-header": "\n\nThe VF run is the end of the selected path. End the run with:",
|
||||
"vfl-m3-lauf-abschluss-opt-offen": "\n 1 - No motor station (open end, continue/merge later)",
|
||||
"vfl-m3-lauf-abschluss-opt-motor": "\n 2 - Set motor station (no ES element)",
|
||||
@@ -246,6 +286,7 @@
|
||||
"vfl-m3-gf2-ausgleich": "\n GF2 (measured compensation): L=%1 mm",
|
||||
"vfl-m3-kurve-back-uebersprungen": "\n >>> [M3a] Vario curve in back run - skipped.",
|
||||
"vfl-m3-nichts-gebaut": "\nNothing built - aborting.",
|
||||
"vfl-m3-alt-journal": "\n Note: this chain predates the build AS / build ES questions - it is rebuilt in the old order.",
|
||||
"vfl-m3-fertig-header": "\n>>> VF line path (mode 2) built! <<<",
|
||||
"vfl-m3-ziel-soll": "\n Target (nominal): X=%1 Y=%2 Z=%3",
|
||||
"vfl-m3-es-ist": "\n ES (actual): X=%1 Y=%2 Z=%3",
|
||||
@@ -280,6 +321,7 @@
|
||||
"kreisel-edit-bestehend": "\n-> Existing: Distance=%1 Rotation=%2 Type=%3",
|
||||
"kreisel-edit-dialog-fehlt": "Dialog not available: %1",
|
||||
"kreisel-eingefuegt": "\n-> Kreisel #%1 inserted: %2 (height=%3)",
|
||||
"kreisel-emsg-abstand-zu-klein": "Distance too small! (%1 < %2) - the end circles would touch/overlap.",
|
||||
"kreisel-emsg-distanz-klein": "Distance too small! (%1 < %2)",
|
||||
"kreisel-hoehe-aus-3dpunkt": "\n-> Height taken from 3D point: %1",
|
||||
"kreisel-hoehe-aus-basispunkt": "\n-> Height taken from base point: %1",
|
||||
@@ -633,6 +675,8 @@
|
||||
"dim-switch-blocks": "\n DXFM_BLOCKS = %1",
|
||||
"dim-switch-omniflo": "\n DXFM_OMNIFLO = %1",
|
||||
"dim-batch-fertig": "\nConversion to %1 complete: %2 GF, %3 VF rebuilt (%4 already in target dimension).",
|
||||
"dim-batch-fehlerliste": "\n%1 polyline block(s) NOT converted (left unchanged):",
|
||||
"dim-batch-fehler-zeile": "\n - %1: %2",
|
||||
"sprache-gewechselt": "\nLanguage switched to: %1",
|
||||
"cmd-block-auswaehlen": "\nSelect block: ",
|
||||
"cmd-kein-block-ausgewaehlt": "\nNo block selected.",
|
||||
@@ -685,6 +729,9 @@
|
||||
"plq-geloescht": "\n[DELETE_PLANQUADRATE] Planquadrat grid removed (%1 insertion(s)).",
|
||||
"plq-nichts-zu-loeschen": "\n[DELETE_PLANQUADRATE] No Planquadrat grid found in the drawing.",
|
||||
"exp-check-ids": "\n[%1] Checking and assigning IDs...",
|
||||
"exp-hoehencheck-frage": "\nRun the height check (mounting height/platforms) before the export?",
|
||||
"exp-bereinigen": "\nPurging drawing (unused blocks, layers, linetypes) ...",
|
||||
"exp-hoehencheck-fehlt": "\nNote: HOEHEN_CHECK not available - export runs without height check.",
|
||||
"exp-hoehen-aktualisiert": "\nHeight attributes of %1 moved blocks reset from their Z coordinate.",
|
||||
"exp-sep-proxy-fehler": "\n[EXPORT] WARNING: copying '%1' out of block '%2' failed (%3) - this element is missing from the export.",
|
||||
"exp-sep-zuordnung": "\n[%1] packed separator copy/copies: ZUORDNUNG set from the wrapper block ID.",
|
||||
@@ -913,6 +960,16 @@
|
||||
"tro-insert-kein-block": "No symbol for this type in the drawing (%1) - run tro_annotate.py with this type first.",
|
||||
"tro-insert-prompt-punkt": "\nInsertion point: ",
|
||||
"tro-insert-eingefuegt": "\nTRO inserted: ID = %1, TYPE = %2",
|
||||
"cmd-jam-bearbeiten": "\nEdit jam area: %1",
|
||||
"jam-edit-kein-jam": "Block %1 is not a jam area (expected JAM_*).",
|
||||
"jam-edit-dialog-fehlt": "Dialog file not found:\n%1\nCheck DXFM_DCL (setenv.bat).",
|
||||
"jam-edit-bereich": "Jam area %1 in front of %2 (entry %3)",
|
||||
"jam-edit-auto": "Derived: %1",
|
||||
"jam-edit-hinweis": "Into the SCL: tro_annotate --read-jams, then scl_skeleton.",
|
||||
"jam-edit-foerderer-ungueltig": "The conveyor must have four digits (e.g. 0054) - nothing changed.",
|
||||
"jam-edit-nummer-ungueltig": "The running number must be a whole number from 1 - nothing changed.",
|
||||
"jam-edit-gespeichert": "\nJam area saved: %1 (%2)",
|
||||
"jam-edit-doppelt": "\nWARNING: %1 already exists in this drawing (%2).",
|
||||
"vfl-abbruch-gesichert": "\n>>> Chain cancelled: %1 object(s) saved as a block (editable/resumable via double-click).",
|
||||
"vfl-zurueck-glied-verworfen": "\n>>> Back: discarding the last chain element - please answer it again.",
|
||||
"vfl-abbruch-nichts-gebaut": "\n>>> Cancelled - no geometry was created yet.",
|
||||
@@ -929,13 +986,13 @@
|
||||
"vfc-warnung-untermodule-nicht-geladen": "\n[vf_core] WARNING: DXFM_LISP not set - submodules could not be loaded!",
|
||||
"vfc-linienzug-modus-header": "\n\nSelect line-path mode:",
|
||||
"vfc-linienzug-modus-1": "\n 1 - Manual entry (click points)",
|
||||
"vfc-linienzug-modus-2": "\n 2 - 3D objects + target height (boundary-value solver, finished)",
|
||||
"vfc-linienzug-modus-3": "\n 3 - 3D objects step by step (forward reconstruction, work in progress)",
|
||||
"vfc-linienzug-modus-2": "\n 2 - from 3D line WITH target height (heights are calculated)",
|
||||
"vfc-linienzug-modus-3": "\n 3 - from 3D line WITHOUT target height (forward build with given angles)",
|
||||
"prompt-wahl-1-3": "\nYour choice (1/2/3) [1]: ",
|
||||
"vfl-qc-uform-nicht-implementiert": "\nERROR: 'QC line with GF and U-shape' is not yet implemented - please choose option 4 or a different mode.",
|
||||
"vfc-typ-standard-beschreibung": "Standard VarioFoerderer (AS/ES 90 degrees, offset horizontally)",
|
||||
"vfc-typ-etage-beschreibung": "Etage VarioFoerderer (AS/ES 30 degrees, directly stacked)",
|
||||
"vfc-typ-linienzug-beschreibung": "Route group (mixed GF/VF chain; mode 1 manual / mode 2 target height finished / mode 3 step by step work in progress)",
|
||||
"vfc-typ-linienzug-beschreibung": "Route group (mixed GF/VF chain; mode 1 manual / mode 2 from 3D line with target height / mode 3 from 3D line without target height)",
|
||||
"vfs-schritt6-horizontal": "\n\n6/11: Horizontal intermediate section (0 deg, L=%1 mm)",
|
||||
"vfs-schritt6-steigung": "\n\n6/11: Incline section (%1 deg, L=%2 mm)",
|
||||
"vfs-schritt6-gefaelle": "\n\n6/11: Slope section (%1 deg, L=%2 mm)",
|
||||
@@ -964,7 +1021,7 @@
|
||||
"vfe-step14": "\n\n14/15: Separator (300mm, cur-hz=%1)",
|
||||
"vfe-step15": "\n\n15/15: %1 (end, chained cur-hz=%2)",
|
||||
"vfe-eingefuegt": "\n>>> Etage VarioFoerderer inserted! <<<",
|
||||
"vfl-vwnb-titel": "\n VF LINE PATH - Mode 3: 3D objects step by step (forward reconstruction, work in progress)",
|
||||
"vfl-vwnb-titel": "\n VF LINE PATH - Mode 3: from 3D line WITHOUT target height (forward build)",
|
||||
"vfl-vwnb-aus-seite-menu": "\n\nOUT element - select side:\n 1 - Left\n 2 - Right",
|
||||
"vfl-vwnb-alert-eckwinkel": "No matching arc: corner angle %1 deg is not ~30/60/90.\nPlease adjust the angles of the lines.",
|
||||
"vfl-vwnb-alert-keine-gerade": "Path contains no straight - a chain must begin with a straight.",
|
||||
@@ -1120,6 +1177,16 @@
|
||||
"kreisel-bp-zeile": "\n Switch %1: %2 <-> %3 [%4] at X=%5 Y=%6 Z=%7",
|
||||
"kreisel-bp-kollision": "\n COLLISION %1: %2 <-> %3 [%4] at X=%5 Y=%6 Z=%7",
|
||||
"kreisel-bp-marker": "\n%1 markers drawn (layer %2).",
|
||||
"chh-start": "\n--- Phase 3: platform families ---",
|
||||
"chh-kein-kreisel": "\n Note: Kreisel module not available - per-block questions only.",
|
||||
"chh-fam-frage": "\n Family %1 (%2, %3 Kreisel, mounting height %4 m): is it on a platform?",
|
||||
"chh-schleife": "\n %1: flat loop on the same Kreisel (VON = BIS) - asked individually.",
|
||||
"chh-buehne-hoehe": "Platform height in m",
|
||||
"chh-buehne-ungueltig": "\n ! Platform height must be > 0 and < %1 m.",
|
||||
"chh-kreuz-konflikt": "\n ! %1: ends in families with different platform heights (%2 / %3 m) - unchanged.",
|
||||
"chh-kreuz-hoehe": "\n ! %1: family heights differ by %2 mm (> %3 mm) - unchanged.",
|
||||
"chh-strecke-neg": "\n ! %1: platform %2 m >= mounting height %3 m - unchanged.",
|
||||
"chh-summe": "\n Phase 3: %1 family(ies), %2 on a platform; adjusted: Kreisel %3, sections within family %4, between families %5; conflicts %6; asked individually %7",
|
||||
"exp-kreisel-weichen": "\n[%1] Kreisel switch points: %2 contact(s), %3 collision(s) -> %4",
|
||||
"exp-kreisel-kollision": "\n[%1] WARNING: %2 Kreisel collision(s) - command KREISEL_WEICHEN shows them.",
|
||||
"lg-daten-fehlt": "\n[Storage] Data file not found: %1 - built-in defaults apply.",
|
||||
@@ -1219,6 +1286,58 @@
|
||||
"lg-regel-profil-fehlt": "\n[Storage] Rule profile %1 not found (%2).",
|
||||
"lg-regel-profil-ungepflegt": "\n[Storage] WARNING: rule profile %1 is not maintained - inherited values apply.",
|
||||
"lg-regel-unbekannt": "\n[Storage] Rule %1 not in profile.",
|
||||
"lg-regel-liste-kopf": "\nRule profile %1: %2 rules (context: increased fire risk without extinguishing system)"
|
||||
"lg-regel-liste-kopf": "\nRule profile %1: %2 rules (context: increased fire risk without extinguishing system)",
|
||||
"kf-fehler-daten-fehlt": "\nERROR: chain conveyor data not found: %1",
|
||||
"kf-fehler-daten-leer": "\nERROR: chain conveyor data could not be read.",
|
||||
"kf-fehler-block-datei": "\nERROR: block file for %1 not found (expected in data/omniflo/<dimension>/).",
|
||||
"kf-fehler-ks-fehlt": "At least one component is missing KS_EIN or KS_AUS - the chain cannot be linked. Command KF_KS_PRUEFEN shows which block is affected.",
|
||||
"kf-fehler-hoehe-zu-klein": "The installation height is too small: the deflection and drive stations already contribute more height than requested. Please choose a greater height.",
|
||||
"kf-fehler-laenge-unter-min": "The intermediate section would be shorter than permitted. Please choose a greater installation height.",
|
||||
"kf-fehler-laenge-ueber-max": "The intermediate section would be longer than permitted. Please choose a smaller installation height.",
|
||||
"kf-fehler-winkel-null": "The measured installation angle of the intermediate section is horizontal - no height can be gained. Please check the KS positions of the blocks (KF_KS_PRUEFEN).",
|
||||
"kf-fehler-dcl": "Dialog file kettenfoerderer.dcl not found.",
|
||||
"kf-prompt-messpunkt-1": "\nSelect first measuring point (lower reference): ",
|
||||
"kf-prompt-messpunkt-2": "\nSelect second measuring point (upper reference): ",
|
||||
"kf-messung-ergebnis": "\n>>> Measured: height difference dZ = %1 mm (for reference dY = %2 mm).",
|
||||
"kf-konsole-hoehe-hinweis": "\n(enter 0 to measure the height from two points)",
|
||||
"kf-2d-gebaut": "\n>>> Plan view %1 inserted: slope length %2 mm, inclination %3 deg.",
|
||||
"kf-2d-laenge-null": "\nPlan view skipped: the chain has no measurable plan length.",
|
||||
"kf-2d-ks-fehlt": "\nPlan view skipped: %1 has no measurable KS_EIN/KS_AUS.",
|
||||
"kf-prompt-startpunkt": "\nSelect insertion point (KS_EIN of the plan view; the side view is built above it): ",
|
||||
"kf-prompt-drehung": "\nRotation angle of the chain: ",
|
||||
"kf-abgebrochen": "\nCancelled.",
|
||||
"kf-fertig": "\n>>> %1 created: installation height %2 mm, intermediate section %3 mm.",
|
||||
"kf-konsole-variante-header": "\n\nSelect inclined steel conveyor type:",
|
||||
"kf-konsole-option": "\n %1 - %2",
|
||||
"kf-konsole-variante-prompt": "\nInclined steel conveyor type",
|
||||
"kf-konsole-hoehe-prompt": "\nH - installation height of inclined conveyor [mm]",
|
||||
"kf-konsole-verbindung-header": "\n\nSelect connecting elements:",
|
||||
"kf-konsole-verbindung-prompt": "\nConnecting elements",
|
||||
"kf-konsole-farbe-header": "\n\nSelect conveyor colour:",
|
||||
"kf-konsole-farbe-prompt": "\nColour",
|
||||
"kf-konsole-antriebsmotor-header": "\n\nSelect conveyor drive motor:",
|
||||
"kf-konsole-antriebsmotor-prompt": "\nConveyor drive motor",
|
||||
"kf-variante-label": "%1 %2",
|
||||
"kf-variante-label-standard": "%1 %2 (default)",
|
||||
"kf-konsole-movimot-header": "\n\nDrive with Movimot?",
|
||||
"kf-konsole-movimot-prompt": "\nDrive with Movimot",
|
||||
"kf-konsole-steuerung-header": "\n\nWith standard control system?",
|
||||
"kf-konsole-steuerung-prompt": "\nWith standard control system",
|
||||
"kf-pruef-kopf": "\n\n=== KF_KS_PRUEFEN: KS positions of the chain conveyor blocks ===",
|
||||
"kf-pruef-variante": "\n\n--- Variant: %1 ---",
|
||||
"kf-pruef-block": "\n %1: KS_EIN (%2, %3) direction %4 | KS_AUS (%5, %6) direction %7",
|
||||
"kf-pruef-block-fehlt": "\n %1: block file not found.",
|
||||
"kf-pruef-ks-fehlt": "\n %1: KS incomplete - KS_EIN: %2, KS_AUS: %3",
|
||||
"kf-pruef-ks-fehlt-kurz": "\n[KF] KS_EIN/KS_AUS not readable on component: %1 (command KF_KS_PRUEFEN shows details)",
|
||||
"kf-pruef-fehler": "\n Geometry could not be determined: %1",
|
||||
"kf-pruef-geo": "\n Installation angles (deg): deflection %1, intermediate %2, drive %3\n Height contribution (mm): deflection %4, drive %5\n Intermediate section native (mm): dx %6, dy %7",
|
||||
"kf-pruef-ja": "present",
|
||||
"kf-pruef-nein": "MISSING",
|
||||
"kf-edit-waehlen": "\nSelect chain conveyor (KF_n) to edit: ",
|
||||
"kf-edit-kein-kf": "The selected block is not a chain conveyor (KF_n).",
|
||||
"kf-edit-fertig": "\n>>> %1 rebuilt as %2.",
|
||||
"cmd-kettenfoerderer-bearbeiten": "\n>>> Editing chain conveyor %1 ...",
|
||||
"vfl-m2-nachrechnen": "\n Folded run: lengths redistributed at the same angle - GF %1 -> %2 mm, climbing section %3 mm (GF1 sits in the entry leg and does not consume the climber span).",
|
||||
"vfl-m2-nachrechnen-fehl": "The chosen angle of %1 degrees no longer works with the corrected length balance. The chain is built with the original distribution and may therefore end too early - please check the actual/target comparison or pick a different angle."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ Edit-Befehl (Doppelklick) zum Neuaufbau liest. Typischer Ablauf: Scanner-
|
||||
Vorlage nachbauen, in BricsCAD von Hand korrigieren/ergaenzen, Zeichnung als
|
||||
DXF speichern und mit diesem Skript die Testdaten aktualisieren.
|
||||
|
||||
Je Wrapper (Felder wie in tests/testdata/object_data.md bzw. mubea.json):
|
||||
Je Wrapper (Felder wie in doc/json-input-lisp.md bzw. mubea.json):
|
||||
|
||||
KREISEL_n -> Kreisel ("function": "insert", x/y/z = Einfuegepunkt,
|
||||
abstand = Mittenabstand AN8-SP8 aus der Blockdefinition,
|
||||
|
||||
@@ -6,7 +6,7 @@ dxf_scan_components.py - Erkennt ILS-/Omniflo-Komponenten in einem FREMDEN DXF.
|
||||
Gedacht fuer Projekt-Zeichnungen, die NICHT von unseren Makros erzeugt wurden
|
||||
(also ohne die Wrapper-Bloecke KREISEL_*, VF_*, GF_*). Das Skript sucht die
|
||||
Bauteile ueber Blocknamen-Muster, rechnet ihre Position in Weltkoordinaten um
|
||||
und schreibt das Ergebnis im JSON-Schema aus tests/testdata/object_data.md -
|
||||
und schreibt das Ergebnis im JSON-Schema aus doc/json-input-lisp.md -
|
||||
also so, dass die Anlage per JSON-Treiber mit den Produktionsmakros
|
||||
nachgebaut werden kann (Vorbild: tests/testdata/mubea.json, das bisher von
|
||||
Hand aus einem DXF abgeleitet wurde).
|
||||
@@ -1697,7 +1697,7 @@ def gf_eintraege_aus_linien(linien, as_liste, kreisel=None, sep_liste=None,
|
||||
def baue_eintraege(treffer, defaults, boegen, weichen,
|
||||
bekannte_bloecke=None, linien=None, kreisel_hoehen=None,
|
||||
kreisel_achsen=None, flach=False):
|
||||
"""Erkannte Vorkommen auf die Schemata aus object_data.md abbilden.
|
||||
"""Erkannte Vorkommen auf die Schemata aus json-input-lisp.md abbilden.
|
||||
|
||||
kreisel_hoehen: Liste (x, y, z) vom Anwender - z gilt fuer den Kreisel,
|
||||
dessen Einfuegepunkt (Eintrag x/y) hoechstens KREISEL_HOEHE_TOL entfernt
|
||||
@@ -2082,7 +2082,7 @@ def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Erkennt ILS-/Omniflo-Komponenten in einem fremden DXF "
|
||||
"und schreibt sie im JSON-Schema aus "
|
||||
"tests/testdata/object_data.md.")
|
||||
"doc/json-input-lisp.md.")
|
||||
parser.add_argument("dxf", help="Quellzeichnung (binaeres oder ASCII-DXF)")
|
||||
parser.add_argument("data_dir", help="Datenverzeichnis mit json/")
|
||||
parser.add_argument("output", help="Ziel-JSON")
|
||||
|
||||
@@ -42,6 +42,7 @@ from export_neighbors import (
|
||||
compute_kreisel_touch_switches,
|
||||
lisp_touch_switches,
|
||||
load_lisp_kreisel_weichen,
|
||||
einsortieren_freie_separatoren,
|
||||
compute_sep_kette,
|
||||
compute_kreisel_umlauf,
|
||||
SENSOR_TEILEARTEN,
|
||||
@@ -1543,6 +1544,12 @@ def process_blocks(blocks, lookup, dbg=None, lisp_weichen=None):
|
||||
if item.get("teileart", "") == "ILS 2.0 Scanner" and separator_id:
|
||||
item["merkmale"]["Naechster Separator"] = separator_id
|
||||
|
||||
# Freie Separatoren, deren Zuordnung eine VF_n/GF_n nennt, die aber nicht
|
||||
# beim Bau der Strecke entstanden sind (fehlen darum in ihrer sepliste),
|
||||
# nach Lage in die Kette aufnehmen - nur fuer diesen Lauf, die XDATA am
|
||||
# Block bleibt unveraendert (siehe einsortieren_freie_separatoren).
|
||||
einsortieren_freie_separatoren(items, NEIGHBOR_TOLERANCE_MM, dbg=dbg)
|
||||
|
||||
# Ketteninterne Separator-/AS-/ES-Reihenfolge aus der neuen "sepliste"-
|
||||
# XDATA (siehe ssg-sepliste-xdata-schreiben) - leeres dict, wenn keine
|
||||
# Strecke eine sepliste traegt (reiner Altbestand ohne neue XDATA).
|
||||
|
||||
@@ -1255,6 +1255,194 @@ def _asel_collision_boxes(item, half_tol, box_dims):
|
||||
# Ersetzt das bisherige Raten der Ketten-internen Reihenfolge (die Linie
|
||||
# selbst wird nicht exportiert) durch die tatsaechliche Bau-Reihenfolge.
|
||||
|
||||
def sepliste_einsortier_positionen(kette_xy, kandidaten):
|
||||
"""Reiner Rechenkern fuer einsortieren_freie_separatoren: wohin gehoert
|
||||
jeder Kandidat in eine vorhandene Kette?
|
||||
|
||||
kette_xy = [(x, y), ...] Lage der Kettenglieder in Kettenfolge (AS ...
|
||||
ES), mindestens zwei Punkte. Sie bilden einen Polygonzug - so
|
||||
folgt die Zuordnung auch einer Kette, die um eine Kurve laeuft,
|
||||
statt nur einer Geraden AS->ES.
|
||||
kandidaten = [(key, x, y), ...]
|
||||
|
||||
Jeder Kandidat wird dem naechstgelegenen Abschnitt (Glied i -> i+1)
|
||||
zugeordnet. Liegt er dabei VOR dem ersten oder HINTER dem letzten Glied,
|
||||
wird er verworfen - eingefuegt wird nur zwischen AS und ES.
|
||||
|
||||
Rueckgabe (einfuegen, verworfen): einfuegen = {i: [key, ...]} - nach
|
||||
Glied i einzufuegen, untereinander in Kettenrichtung sortiert;
|
||||
verworfen = [key, ...].
|
||||
"""
|
||||
abschnitte = []
|
||||
for i in range(len(kette_xy) - 1):
|
||||
(ax, ay), (bx, by) = kette_xy[i], kette_xy[i + 1]
|
||||
dx, dy = bx - ax, by - ay
|
||||
l2 = dx * dx + dy * dy
|
||||
if l2 > 1e-12:
|
||||
abschnitte.append((i, ax, ay, dx, dy, l2))
|
||||
letzter = len(kette_xy) - 2
|
||||
|
||||
einfuegen = {}
|
||||
verworfen = []
|
||||
for key, x, y in kandidaten:
|
||||
best = None
|
||||
for i, ax, ay, dx, dy, l2 in abschnitte:
|
||||
t = ((x - ax) * dx + (y - ay) * dy) / l2
|
||||
tc = min(max(t, 0.0), 1.0)
|
||||
d = math.hypot(x - (ax + tc * dx), y - (ay + tc * dy))
|
||||
if best is None or d < best[0] - 1e-9:
|
||||
best = (d, i, t)
|
||||
if best is None:
|
||||
verworfen.append(key)
|
||||
continue
|
||||
_d, i, t = best
|
||||
if (i == 0 and t <= 0.0) or (i == letzter and t >= 1.0):
|
||||
verworfen.append(key)
|
||||
continue
|
||||
einfuegen.setdefault(i, []).append((min(max(t, 0.0), 1.0), key))
|
||||
|
||||
return ({i: [key for _t, key in sorted(liste)] for i, liste in einfuegen.items()},
|
||||
verworfen)
|
||||
|
||||
|
||||
def _kettenglied_xy(entry, item, strecke):
|
||||
"""Lage eines sepliste-Glieds fuer den Polygonzug: AS/ES ueber K1/K2 der
|
||||
Strecke (Ein-/Auslauf - der ZZ_ASES_MARKER sitzt auf dem Einfuegepunkt
|
||||
des Elements und kann bis ~600 mm seitlich davon liegen), sonst bzw.
|
||||
ohne K1/K2 der Bounding-Box-Mittelpunkt des vertretenden Items."""
|
||||
typ = entry.get("typ", "")
|
||||
if typ in ("AS", "ES"):
|
||||
k1_xy, k2_xy = _asel_kos_xy(strecke)
|
||||
pt = k1_xy if typ == "AS" else k2_xy
|
||||
if pt is not None:
|
||||
return pt
|
||||
bbox = (item or {}).get("_bbox")
|
||||
if not bbox:
|
||||
return None
|
||||
return (bbox.get("cx", 0.0), bbox.get("cy", 0.0))
|
||||
|
||||
|
||||
def einsortieren_freie_separatoren(items, tolerance_mm, dbg=None):
|
||||
"""Nimmt freie Separatoren in die sepliste ihrer VF_n/GF_n-Strecke auf.
|
||||
|
||||
Die sepliste entsteht beim BAU der Strecke (ssg-sepliste-sammeln) und
|
||||
kennt nur die Separatoren, die dabei erzeugt wurden. Ein eigenstaendiger
|
||||
Separator_SP-Block, der spaeter (oder aus einer frueheren Fassung der
|
||||
Strecke) auf ihr liegt, fehlt darin - obwohl seine ZUORDNUNG
|
||||
(cs-zuordnung-lauf) die Strecke nennt. Ohne diesen Schritt fehlt er in
|
||||
TrackIds und Nachbarn (realer Fall Mubea VF_3: 0037/0038 zwischen 0062
|
||||
und 0063).
|
||||
|
||||
Aufgenommen wird ein Separator nur, wenn
|
||||
- seine Zuordnung die Strecke nennt,
|
||||
- er in keiner sepliste steht,
|
||||
- sein Mittelpunkt in der Bounding-Box der Strecke liegt (+ tolerance_mm/2),
|
||||
- er laengs der Kette zwischen AS und ES liegt
|
||||
(sepliste_einsortier_positionen).
|
||||
|
||||
Bewusst NUR im Speicher dieses Exportlaufs: die sepliste-XDATA am Block
|
||||
bleibt das Bauprotokoll. Lisp ordnet ihre Eintraege den eingebauten
|
||||
Bausteinen ueber die Anzahl je Typ zu (csv:sepliste-kette-paare) und
|
||||
fuehrt reservierte AS/ES-IDs unter der lfdnr - ein in die XDATA
|
||||
eingefuegter fremder Separator verschoebe beides. Ausserdem schreibt jeder
|
||||
Neuaufbau der Strecke die XDATA neu; hier wird bei jedem Export frisch
|
||||
aus dem aktuellen Zeichnungsstand gerechnet.
|
||||
|
||||
Aendert items in-place: item["sepliste"] der Strecke bekommt neue
|
||||
SEP-Eintraege (lfdnr "frei<TeileId>", "id" = TeileId des Separators,
|
||||
"frei": True); der Separator bekommt "_in_strecke_kette" (Strecken-
|
||||
TeileId, damit compute_kreisel_umlauf ihn nicht zusaetzlich einem
|
||||
Kreisel zuschlaegt), das Merkmal "Einsortiert in" (Strecken-TeileId,
|
||||
in der CSV-Spalte Merkmale) und einen Hinweis in "warnung".
|
||||
Muss NACH der Separator-Zuordnung und VOR compute_sep_kette laufen.
|
||||
"""
|
||||
half_tol = tolerance_mm / 2.0
|
||||
by_teileid = {it.get("teileid", ""): it for it in items if it.get("teileid", "")}
|
||||
in_ketten = set()
|
||||
for it in items:
|
||||
if it.get("teileart", "") in GF_VF_TEILEARTEN:
|
||||
for e in it.get("sepliste") or []:
|
||||
eid = str(e.get("id", "")).strip()
|
||||
if eid:
|
||||
in_ketten.add(eid)
|
||||
|
||||
if dbg:
|
||||
dbg("=== einsortieren_freie_separatoren ===")
|
||||
|
||||
for strecke in items:
|
||||
if strecke.get("teileart", "") not in GF_VF_TEILEARTEN:
|
||||
continue
|
||||
sepliste = strecke.get("sepliste")
|
||||
sbbox = strecke.get("_bbox")
|
||||
if not sepliste or not sbbox:
|
||||
continue
|
||||
sid = strecke.get("teileid", "")
|
||||
sbounds = _bounds(sbbox, half_tol)
|
||||
|
||||
kandidaten = []
|
||||
for it in items:
|
||||
if it.get("teileart", "") != "ILS 2.0 Separator":
|
||||
continue
|
||||
tid = it.get("teileid", "")
|
||||
if not tid or tid in in_ketten:
|
||||
continue
|
||||
zuordnung = ((it.get("merkmale") or {}).get("Zuordnung")
|
||||
or it.get("_zuordnung_attr") or "").strip()
|
||||
if zuordnung != sid:
|
||||
continue
|
||||
bbox = it.get("_bbox")
|
||||
if not bbox:
|
||||
continue
|
||||
cx, cy = bbox.get("cx", 0.0), bbox.get("cy", 0.0)
|
||||
if not (sbounds[0] <= cx <= sbounds[1] and sbounds[2] <= cy <= sbounds[3]):
|
||||
if dbg:
|
||||
dbg(f" Strecke {sid}: Separator {tid} ausserhalb der Strecken-BBox "
|
||||
f"- nicht einsortiert")
|
||||
continue
|
||||
kandidaten.append((tid, cx, cy))
|
||||
if not kandidaten:
|
||||
continue
|
||||
|
||||
kette_xy = []
|
||||
for e in sepliste:
|
||||
pt = _kettenglied_xy(e, by_teileid.get(str(e.get("id", "")).strip()), strecke)
|
||||
if pt is None:
|
||||
break
|
||||
kette_xy.append(pt)
|
||||
if len(kette_xy) != len(sepliste) or len(kette_xy) < 2:
|
||||
if dbg:
|
||||
dbg(f" Strecke {sid}: Kettenglieder nicht vollstaendig lokalisierbar "
|
||||
f"- freie Separatoren {[k[0] for k in kandidaten]} nicht einsortiert")
|
||||
continue
|
||||
|
||||
einfuegen, verworfen = sepliste_einsortier_positionen(kette_xy, kandidaten)
|
||||
if dbg and verworfen:
|
||||
dbg(f" Strecke {sid}: {verworfen} liegen nicht zwischen AS und ES "
|
||||
f"- nicht einsortiert")
|
||||
if not einfuegen:
|
||||
continue
|
||||
|
||||
neu = []
|
||||
for i, entry in enumerate(sepliste):
|
||||
neu.append(entry)
|
||||
for tid in einfuegen.get(i, []):
|
||||
neu.append({"typ": "SEP", "lfdnr": f"frei{tid}", "id": tid, "frei": True})
|
||||
sep = by_teileid[tid]
|
||||
sep["_in_strecke_kette"] = sid
|
||||
# Fuer Folgewerkzeuge (sps_skel: sepliste-Gegenprobe): dieser
|
||||
# Separator steht in TrackIds, aber nicht im Bauprotokoll.
|
||||
sep.setdefault("merkmale", {})["Einsortiert in"] = sid
|
||||
hinweis = (f"nicht im Bau von {sid} erzeugt - per Lage in dessen "
|
||||
f"Kette einsortiert")
|
||||
bisherige = sep.get("warnung", "")
|
||||
sep["warnung"] = f"{bisherige}; {hinweis}" if bisherige else hinweis
|
||||
in_ketten.add(tid)
|
||||
strecke["sepliste"] = neu
|
||||
if dbg:
|
||||
dbg(f" Strecke {sid}: Kette jetzt "
|
||||
f"{' -> '.join(str(e.get('id', '')) for e in neu)}")
|
||||
|
||||
|
||||
def compute_sep_kette(items, dbg=None):
|
||||
"""Baut je VF_n/GF_n-Item MIT "sepliste" die ketteninterne Vorgaenger-/
|
||||
Nachfolger-Beziehung AS -> Sep1 -> ... -> SepN -> ES.
|
||||
@@ -1392,6 +1580,11 @@ def compute_kreisel_umlauf(items, tolerance_mm, durchmesser_mm=800.0,
|
||||
for item in items:
|
||||
if item.get("teileart", "") not in KREISEL_UMLAUF_TEILEARTEN:
|
||||
continue
|
||||
# Freier Separator, den einsortieren_freie_separatoren in die Kette
|
||||
# einer Strecke aufgenommen hat - gehoert nicht zusaetzlich auf einen
|
||||
# Kreisel, auch wenn seine Box einen beruehrt.
|
||||
if item.get("_in_strecke_kette"):
|
||||
continue
|
||||
teileid = item.get("teileid", "")
|
||||
bbox = item.get("_bbox")
|
||||
if not bbox:
|
||||
|
||||
+243
-3
@@ -58,6 +58,7 @@ items_zusammenfassen. output.csv selbst bleibt unveraendert.
|
||||
import json
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
from export_blockpatterns import (load_patterns, load_export_cfg, cfg_path_from_env,
|
||||
matches_any, csv_quote, safe_float, safe_int)
|
||||
@@ -101,14 +102,36 @@ def get_id(block):
|
||||
# Sprachdatei, da rein Sivas-seitig.
|
||||
GERUEST_TYP_ANZEIGE = sivas_mapping.load_flat_mapping("geruest_typ_anzeige")
|
||||
|
||||
# Kettenfoerderer: Attribut WINKEL fuehrt den Neigungswinkel als nackte Zahl
|
||||
# ("26"/"30"), Sivas-Merkmal 359 erwartet den Optionstext mit Gradzeichen.
|
||||
# Gleiche Bauart und derselbe Grund wie GERUEST_TYP_ANZEIGE.
|
||||
KF_TYP_ANZEIGE = sivas_mapping.load_flat_mapping("kf_typ_anzeige")
|
||||
|
||||
# TeileArt-Spalte der Kettenfoerderer-Zeilen. Fester Wert statt Block-Attribut:
|
||||
# er ist fuer jeden Kettenfoerderer gleich, stuende also an jedem Block nur
|
||||
# redundant herum. Die Erkennung laeuft ueber den Blocknamen
|
||||
# (pattern_kettenfoerderer), nicht ueber TEILEART. Ein Block, der das Attribut
|
||||
# doch mitbringt (Altbestand), hat weiterhin Vorrang.
|
||||
KF_TEILEART = "Schraegfoerderer Stahl"
|
||||
|
||||
SEPARATOR_BEARBEITUNG_ANZEIGE = "ohne HARTCOAT HRC 50 ± 5"
|
||||
|
||||
# Sivas-Merkmale "Streckengruppe - Variofoerderer 001..005 - Hoehe in Meter".
|
||||
# Reihenfolge = Bau-Reihenfolge der Foerdereinheiten in VF_HOEHE_m.
|
||||
VF_HOEHE_MERKMALE = ("4433", "4434", "4435", "4436", "4437")
|
||||
|
||||
|
||||
def geruest_typ_anzeige(wert):
|
||||
"""Wandelt den ASCII-Attributwert GERUEST_TYP in die Sivas-Anzeige um."""
|
||||
return GERUEST_TYP_ANZEIGE.get(wert, wert)
|
||||
|
||||
|
||||
def kf_typ_anzeige(wert):
|
||||
"""Wandelt den Kettenfoerderer-Winkel ("26"/"30") in die Sivas-Anzeige
|
||||
zu Merkmal 359 um ("Schrägförderer Stahl 26°")."""
|
||||
return KF_TYP_ANZEIGE.get(str(wert).strip(), wert)
|
||||
|
||||
|
||||
def ja_nein(flag_1_0):
|
||||
"""Wandelt ein "0"/"1"-Attribut in die Sivas-Anzeige "Ja"/"Nein" um."""
|
||||
return "Ja" if flag_1_0 == "1" else "Nein"
|
||||
@@ -120,14 +143,95 @@ def mm_zu_m(wert_mm):
|
||||
return str(round(safe_float(wert_mm, 0.0) / 1000.0, 3))
|
||||
|
||||
|
||||
# --- AS-/ES-Element (Merkmale 4427-4432) ---------------------------------
|
||||
# Zuordnung komplett in cfg/sivas.cfg ([gefaellestrecke]/[variofoerderer]),
|
||||
# hier stehen nur die Transforms. Die Sivas-Hierarchie ist: 4431/4432
|
||||
# ("AS-Element"/"ES-Element", Ja/Nein) schalten die Unterknoten Winkel
|
||||
# (4427/4429) und Seite (4428/4430) frei.
|
||||
#
|
||||
# Ob ein Element vorhanden ist, entscheidet AUSSCHLIESSLICH WINKEL_AS/
|
||||
# WINKEL_ES: das gemeinsame Strecken-Schema (*strecke-attr-front* in
|
||||
# ssg_core.lsp) laesst den Winkel leer, wenn kein Element gewaehlt wurde.
|
||||
# SEITE_AS/SEITE_ES taugen dafuer NICHT - sie tragen mit "rechts" immer einen
|
||||
# Schema-Vorgabewert. Ohne Element bleiben Winkel UND Seite leer, damit in
|
||||
# Sivas keine Seite unter einem "Nein"-Knoten haengt.
|
||||
|
||||
# Attributwert -> Sivas-Optionswert der Auswahlliste ("30"/"90" -> "30 °"/
|
||||
# "90 °", siehe Merkmalstamm). Wie [geruest_typ_anzeige] in der Config, damit
|
||||
# die exakte Schreibweise ohne Code-Aenderung nachgezogen werden kann.
|
||||
AS_ES_WINKEL_ANZEIGE = sivas_mapping.load_flat_mapping("as_es_winkel_anzeige")
|
||||
|
||||
|
||||
def winkel_text(wert):
|
||||
"""Elementwinkel ganzzahlig normiert ("90.0" -> "90"), ohne Sivas-
|
||||
Anzeigeform. Basis fuer as_es_winkel UND fuer die Gruppierung (dort darf
|
||||
die Anzeigeform keine Rolle spielen). Leerer Wert bleibt leer."""
|
||||
wert = str(wert or "").strip()
|
||||
if not wert:
|
||||
return ""
|
||||
zahl = safe_float(wert, None)
|
||||
return wert if zahl is None else str(int(zahl))
|
||||
|
||||
|
||||
def as_es_vorhanden(winkel):
|
||||
"""Merkmal 4431/4432: "Ja", sobald ein Elementwinkel gesetzt ist."""
|
||||
return "Ja" if winkel_text(winkel) else "Nein"
|
||||
|
||||
|
||||
def as_es_winkel(winkel):
|
||||
"""Merkmal 4427/4429: Elementwinkel in der Sivas-Schreibweise der
|
||||
Auswahlliste (cfg/sivas.cfg [as_es_winkel_anzeige]). Ein Winkel ohne
|
||||
Eintrag dort wird unveraendert (nur ganzzahlig normiert) uebernommen."""
|
||||
winkel = winkel_text(winkel)
|
||||
return AS_ES_WINKEL_ANZEIGE.get(winkel, winkel)
|
||||
|
||||
|
||||
def _seite_text(seite, winkel):
|
||||
"""Gemeinsamer Kern von as_seite/es_seite: Seite nur, wenn es das Element
|
||||
ueberhaupt gibt."""
|
||||
if not winkel_text(winkel):
|
||||
return ""
|
||||
return str(seite or "").strip().lower()
|
||||
|
||||
|
||||
@sivas_mapping.braucht_attribs
|
||||
def as_seite(wert, attribs):
|
||||
"""Merkmal 4428: AS-Seite, aber nur bei vorhandenem AS-Element."""
|
||||
return _seite_text(wert, attribs.get("WINKEL_AS", ""))
|
||||
|
||||
|
||||
@sivas_mapping.braucht_attribs
|
||||
def es_seite(wert, attribs):
|
||||
"""Merkmal 4430: ES-Seite, aber nur bei vorhandenem ES-Element."""
|
||||
return _seite_text(wert, attribs.get("WINKEL_ES", ""))
|
||||
|
||||
|
||||
# --- Transform-Namen, wie sie in cfg/sivas.cfg hinter "|" stehen koennen ---
|
||||
TRANSFORMS = {
|
||||
"ja_nein": ja_nein,
|
||||
"geruest_typ_anzeige": geruest_typ_anzeige,
|
||||
"kf_typ_anzeige": kf_typ_anzeige,
|
||||
"mm_zu_m": mm_zu_m,
|
||||
"as_es_vorhanden": as_es_vorhanden,
|
||||
"as_es_winkel": as_es_winkel,
|
||||
"as_seite": as_seite,
|
||||
"es_seite": es_seite,
|
||||
}
|
||||
|
||||
|
||||
def as_es_signatur(attribs):
|
||||
"""AS-/ES-Anteil des Gruppierungsschluessels (siehe
|
||||
gefaellestrecke_signature). Nutzt dieselben Transforms wie der Export,
|
||||
damit Schluessel und Zeileninhalt nicht auseinanderlaufen: ohne Element
|
||||
ist die Seite leer und darf dann auch nicht trennen."""
|
||||
return (as_es_vorhanden(attribs.get("WINKEL_AS", "")),
|
||||
winkel_text(attribs.get("WINKEL_AS", "")),
|
||||
as_seite(attribs.get("SEITE_AS", ""), attribs),
|
||||
as_es_vorhanden(attribs.get("WINKEL_ES", "")),
|
||||
winkel_text(attribs.get("WINKEL_ES", "")),
|
||||
es_seite(attribs.get("SEITE_ES", ""), attribs))
|
||||
|
||||
|
||||
def streckengruppe_objekt_text(attribs):
|
||||
"""Merkmal 4300 "Streckengruppe": "mehrere Objekte", wenn der Block ein
|
||||
kombinierter Streckengruppe-Block (Gefaelle+Vario, TYP-Attribut
|
||||
@@ -191,12 +295,54 @@ def eckrad_signature(block):
|
||||
)
|
||||
|
||||
|
||||
def kettenfoerderer_signature(block):
|
||||
"""
|
||||
Schluessel zur Gruppierung gleichartiger Kettenfoerderer (KF_n): baugleiche
|
||||
Bloecke landen in EINER Sivas-Zeile, deren Anzahl das Merkmal 353 ("Anzahl
|
||||
der gleichen Schraegfoerderer") traegt.
|
||||
|
||||
In den Schluessel gehoert JEDES Attribut, aus dem ein Merkmal der Zeile
|
||||
entsteht - sonst verschmelzen zwei unterschiedlich ausgefuehrte Foerderer
|
||||
zu einer Zeile, und die Merkmale des ERSTEN Blocks gelten fuer beide
|
||||
(gleiche Ueberlegung wie bei gefaellestrecke_signature/as_es_signatur).
|
||||
Die Kommentare nennen darum je Attribut die Merkmalnummer; einzige
|
||||
Ausnahme ist 353, das erst aus der Gruppengroesse entsteht.
|
||||
|
||||
Das ist zugleich die Voraussetzung dafuer, dass items_zusammenfassen (fuer
|
||||
die _zusammengefasst.csv) zwei KF-Zeilen NIE verschmelzen kann: gleiche
|
||||
Merkmale wuerden schon hier dieselbe Gruppe ergeben. Sonst wuerde dort
|
||||
"anzahl" addiert, waehrend 353 unveraendert stehen bliebe.
|
||||
|
||||
Die Laenge des Zwischenstuecks (L_KF_mm) ist eine FOLGE der Einbauhoehe und
|
||||
steht darum nicht eigens im Schluessel.
|
||||
"""
|
||||
attribs = block.get("attribs", {})
|
||||
return (
|
||||
attribs.get("WINKEL", "26"), # 359
|
||||
attribs.get("STANDARD_STEUERUNG", "0"), # 361
|
||||
attribs.get("FOERDERERTYP", ""), # 350
|
||||
attribs.get("H_EINBAUHOEHE_mm", "0"), # 360
|
||||
attribs.get("FARBE", ""), # 354
|
||||
attribs.get("ANTRIEBSMOTOR", ""), # 355
|
||||
attribs.get("ANTRIEBSART", ""), # 357
|
||||
attribs.get("MOVIMOT", "0"), # 356
|
||||
attribs.get("VERBINDUNGSELEMENTE", "Nein"), # 391
|
||||
attribs.get("ARTINR", ""),
|
||||
)
|
||||
|
||||
|
||||
def gefaellestrecke_signature(block):
|
||||
"""
|
||||
Schluessel zur Gruppierung gleichartiger Gefaellestrecken: Bloecke mit
|
||||
identischen Massen (Hoehe, Laenge, Winkel, Separatoren, Scanner, Typ,
|
||||
Geruest fuer Einzelmodul/Geruestoption) landen in derselben Sivas-Zeile -
|
||||
nur IDs/Bezeichnung unterscheiden sich.
|
||||
Geruest fuer Einzelmodul/Geruestoption, AS-/ES-Element) landen in
|
||||
derselben Sivas-Zeile - nur IDs/Bezeichnung unterscheiden sich.
|
||||
|
||||
AS-/ES-Element (Merkmale 4427-4432) gehoeren mit in den Schluessel: die
|
||||
Merkmale der Zeile entstehen aus dem ERSTEN Block der Gruppe, zwei sonst
|
||||
baugleiche Gefaellestrecken mit AS links bzw. AS rechts wuerden sonst zu
|
||||
einer Zeile mit nur einer der beiden Seiten verschmelzen (siehe
|
||||
as_es_signatur).
|
||||
"""
|
||||
attribs = block.get("attribs", {})
|
||||
return (
|
||||
@@ -209,6 +355,7 @@ def gefaellestrecke_signature(block):
|
||||
attribs.get("TYP", "Gefaellestrecke"),
|
||||
attribs.get("GERUEST_EINZELMODUL", "0"),
|
||||
attribs.get("GERUEST_TYP", "Schoenenberger Geruest"),
|
||||
as_es_signatur(attribs),
|
||||
)
|
||||
|
||||
|
||||
@@ -292,6 +439,20 @@ def build_variofoerderer_details(block):
|
||||
details["4354"] = vf_richtung[0].lower() if vf_richtung else ""
|
||||
details["4386"] = str(int(vf_winkel[0])) if vf_winkel else ""
|
||||
|
||||
# Hoehe je Foerdereinheit (4433-4437, "Variofoerderer 001-005 - Hoehe in
|
||||
# Meter"). Quelle ist das Attribut VF_HOEHE_m: eine kommagetrennte Liste
|
||||
# in Bau-Reihenfolge, je Eintrag der Mittelwert aus KS_EIN der
|
||||
# Umlenkstation und KS_AUS der Motorstation (siehe vf-vfhoehe-anfang/-ende
|
||||
# in Lisp/vf_core.lsp). Einheit Meter, 3 Nachkommastellen - wie L_VF_m.
|
||||
#
|
||||
# Mehr als fuenf Foerdereinheiten kann Sivas hier nicht abbilden; die
|
||||
# ueberzaehligen werden bewusst weggelassen statt zusammengefasst, damit
|
||||
# kein Merkmal einen erfundenen Wert traegt. Fehlende Eintraege bleiben
|
||||
# ganz weg (kein leeres Merkmal).
|
||||
vf_hoehen = parse_float_list(attribs.get("VF_HOEHE_m", ""))
|
||||
for nummer, hoehe in zip(VF_HOEHE_MERKMALE, vf_hoehen):
|
||||
details[nummer] = "%.3f" % hoehe
|
||||
|
||||
return {k: str(v) for k, v in details.items()}
|
||||
|
||||
|
||||
@@ -299,6 +460,7 @@ SIVAS_MAPPING_KREISEL = sivas_mapping.load_section_mapping("kreisel")
|
||||
SIVAS_MAPPING_ECKRAD = sivas_mapping.load_section_mapping("eckrad")
|
||||
SIVAS_MAPPING_GERUEST = sivas_mapping.load_section_mapping("geruest")
|
||||
SIVAS_MAPPING_WEICHEN = sivas_mapping.load_section_mapping("weichen")
|
||||
SIVAS_MAPPING_KETTENFOERDERER = sivas_mapping.load_section_mapping("kettenfoerderer")
|
||||
|
||||
|
||||
def build_kreisel_details(block):
|
||||
@@ -326,6 +488,21 @@ def build_eckrad_details(block):
|
||||
return sivas_mapping.anwenden(SIVAS_MAPPING_ECKRAD, attribs, TRANSFORMS)
|
||||
|
||||
|
||||
def build_kettenfoerderer_details(block, anzahl=1):
|
||||
"""Merkmale-Dict fuer eine Gruppe baugleicher Kettenfoerderer (KF_n,
|
||||
Lisp/KettenFoerderer.lsp).
|
||||
|
||||
350/359/354/356/360/391 kommen flach aus cfg/sivas.cfg [kettenfoerderer].
|
||||
353 ("Anzahl der gleichen Schraegfoerderer") entsteht erst hier aus der
|
||||
Gruppengroesse und kann darum nicht im Mapping stehen - gleiche Bauart wie
|
||||
3510/3512 beim Kreisel.
|
||||
"""
|
||||
attribs = block.get("attribs", {})
|
||||
details = sivas_mapping.anwenden(SIVAS_MAPPING_KETTENFOERDERER, attribs, TRANSFORMS)
|
||||
details["353"] = str(anzahl)
|
||||
return details
|
||||
|
||||
|
||||
# def build_geruest_details(block):
|
||||
#"""Merkmale-Dict fuer eine GR_-Geruest-Baugruppe (siehe pattern_geruest in
|
||||
#cfg/export.cfg, GeruestInsert.lsp *geruest-attrib-defs*). ARTINR/
|
||||
@@ -444,6 +621,8 @@ def process_blocks(blocks, anzahl_weichen_ils=0):
|
||||
btmt_beladung_ids = [] # IDs aller BTMT-Beladung*-Bloecke (eine gruppierte Zeile)
|
||||
btmt_entladung_ids = [] # IDs aller SC_Entladung*-Bloecke (eine gruppierte Zeile)
|
||||
geruest_list = [] # Liste von GR_-Geruest-Baugruppenbloecken, je einer Zeile
|
||||
# Kettenfoerderer: kettenfoerderer_signature(block) -> {"block", "ids", "anzahl"}
|
||||
kettenfoerderer_groups = {}
|
||||
|
||||
counters = {
|
||||
"anzahl_kreisel": 0,
|
||||
@@ -466,6 +645,7 @@ def process_blocks(blocks, anzahl_weichen_ils=0):
|
||||
"anzahl_btbeladung": 0,
|
||||
"anzahl_abwurfstationen": 0,
|
||||
"anzahl_geruest": 0,
|
||||
"anzahl_kettenfoerderer": 0,
|
||||
}
|
||||
|
||||
for block in blocks:
|
||||
@@ -515,6 +695,22 @@ def process_blocks(blocks, anzahl_weichen_ils=0):
|
||||
counters["anzahl_geruest"] += 1
|
||||
continue
|
||||
|
||||
# --- Kettenfoerderer / Schraegfoerderer Stahl (KF_n) ---
|
||||
# MUSS vor dem allgemeinen Omniflo-Zweig stehen: die KF-Baugruppe
|
||||
# traegt TEILEART "Omniflo Kettenfoerderer ..." und wuerde dort sonst
|
||||
# ueber ARTINR aufgeloest - ihre eigenen Merkmale (350/353/354/356/
|
||||
# 359/360/391) gingen dabei verloren. Anders als das Geruest werden
|
||||
# BAUGLEICHE Foerderer zu einer Zeile zusammengefasst, weil Merkmal
|
||||
# 353 genau diese Stueckzahl verlangt.
|
||||
if matches_any(bname, BLOCKPATTERNS.get("pattern_kettenfoerderer", [])):
|
||||
sig = kettenfoerderer_signature(block)
|
||||
if sig not in kettenfoerderer_groups:
|
||||
kettenfoerderer_groups[sig] = {"block": block, "ids": [], "anzahl": 0}
|
||||
kettenfoerderer_groups[sig]["anzahl"] += 1
|
||||
kettenfoerderer_groups[sig]["ids"].append(get_id(block))
|
||||
counters["anzahl_kettenfoerderer"] += 1
|
||||
continue
|
||||
|
||||
# --- Omniflo Gerade (AP110) ---
|
||||
# VOR dem allgemeinen Omniflo-Zweig: Geraden tragen ggf. ebenfalls
|
||||
# TEILEART "Omniflo ...", brauchen aber die Laengensumme.
|
||||
@@ -773,7 +969,7 @@ def process_blocks(blocks, anzahl_weichen_ils=0):
|
||||
"sivasnr": artinr,
|
||||
"sivasnr_quoted": True,
|
||||
"bezeichnung": attribs.get("BEZEICHNUNG", ""),
|
||||
"dispgruppe": 20,
|
||||
"dispgruppe": 30,
|
||||
"anzahl": anzahl,
|
||||
"laenge_mm": attribs.get("LAENGE", ""),
|
||||
"ids": [get_id(block)],
|
||||
@@ -781,6 +977,31 @@ def process_blocks(blocks, anzahl_weichen_ils=0):
|
||||
})
|
||||
nr += 1
|
||||
|
||||
# Kettenfoerderer / Schraegfoerderer Stahl (KF_n) - eine Zeile je Gruppe
|
||||
# BAUGLEICHER Foerderer, deren Groesse als Merkmal 353 mitgefuehrt wird.
|
||||
# Die Sivasnr kommt - wie beim Geruest - aus dem ARTINR-Attribut (gepflegt
|
||||
# als "sivas_id" je Variante in data/json/kettenfoerderer.json); ist dort
|
||||
# nichts hinterlegt, bleibt die Spalte leer und die Zeile traegt allein
|
||||
# ihre Merkmale. Die drei Bausteine des Foerderers (Umlenkstation,
|
||||
# skaliertes Zwischenstueck, Antriebsstation) bekommen KEINE eigenen
|
||||
# Zeilen - der Schraegfoerderer ist in Sivas EIN Artikel.
|
||||
for gruppe in kettenfoerderer_groups.values():
|
||||
block = gruppe["block"]
|
||||
attribs = block.get("attribs", {})
|
||||
items.append({
|
||||
"nr": nr,
|
||||
"teileart": attribs.get("TEILEART") or attribs.get("FOERDERERTYP") or KF_TEILEART,
|
||||
"sivasnr": attribs.get("ARTINR", ""),
|
||||
"sivasnr_quoted": True,
|
||||
"bezeichnung": attribs.get("Bezeichnung", ""),
|
||||
"dispgruppe": 20,
|
||||
"anzahl": gruppe["anzahl"],
|
||||
"laenge_mm": attribs.get("L_KF_mm", ""),
|
||||
"ids": gruppe["ids"],
|
||||
"details": build_kettenfoerderer_details(block, gruppe["anzahl"]),
|
||||
})
|
||||
nr += 1
|
||||
|
||||
# VarioFoerderer-Compound-Bloecke (VF_N) - je Block eine eigene Zeile mit
|
||||
# vollstaendigen Gefaelle-/Angetrieben-Teilgruppen (immer TYP "Streckengruppe").
|
||||
for block in vario_list:
|
||||
@@ -964,6 +1185,13 @@ def zusammengefasster_dateiname(output_csv):
|
||||
return f"{stamm}_zusammengefasst{endung}"
|
||||
|
||||
|
||||
def dispogruppen_dateiname(output_csv, dispo):
|
||||
"""z.B. "500651_sivas.csv", "10" -> "500651_sivas_zusammengefasst_dispo10.csv"."""
|
||||
stamm, endung = os.path.splitext(output_csv)
|
||||
sauber = re.sub(r"[^0-9A-Za-z_-]", "_", str(dispo)) or "leer"
|
||||
return f"{stamm}_zusammengefasst_dispo{sauber}{endung}"
|
||||
|
||||
|
||||
def items_zusammenfassen(items):
|
||||
"""Fasst Zeilen zusammen, die sich nur in Nr, Anzahl und IDs
|
||||
unterscheiden: Anzahl wird addiert, die IDs werden (ohne Dubletten, in
|
||||
@@ -1041,6 +1269,18 @@ def main():
|
||||
print(f"[export_sivas] Zusammengefasste CSV geschrieben: {output_csv_zus} "
|
||||
f"({len(items_zus)} Zeilen)")
|
||||
|
||||
# Je Dispogruppe eine eigene zusammengefasste Datei, z.B.
|
||||
# "<stamm>_zusammengefasst_dispo10.csv" (Nr je Datei neu gezaehlt).
|
||||
for dispo in sorted({str(i["dispgruppe"]) for i in items_zus}):
|
||||
teil = [i for i in items_zus if str(i["dispgruppe"]) == dispo]
|
||||
teil = [dict(i, nr=n) for n, i in enumerate(teil, 1)]
|
||||
pfad = dispogruppen_dateiname(output_csv, dispo)
|
||||
with open(pfad, "w", encoding="utf-8") as f:
|
||||
f.write(header + "\n")
|
||||
for item in teil:
|
||||
f.write(format_csv_line(item) + "\n")
|
||||
print(f"[export_sivas] Dispogruppe {dispo}: {pfad} ({len(teil)} Zeilen)")
|
||||
|
||||
# Zweite, lesbare Kopie fuer die manuelle Pruefung (Merkmalnummer +
|
||||
# Bezeichnung aus cfg/Merkmalsstamm_in_Sivas.xlsx) - wird von Sivas
|
||||
# selbst NICHT eingelesen, nur output_csv ist der eigentliche Import.
|
||||
|
||||
@@ -9,7 +9,7 @@ Hintergrund: data/polylines.dxf enthaelt 5 LWPOLYLINE-Objekte auf Layer
|
||||
"Z-6" - Streckenzuege, die reale Foerderer-Pfade der HundM05-Zeichnung
|
||||
nachbilden (siehe data/polylines.md, von Hand ausgewertet). Dieses Skript
|
||||
macht dieselbe Auswertung reproduzierbar und maschinenlesbar, als Grundlage
|
||||
fuer einen neuen Testfall (siehe tests/testdata/object_data.md fuer das
|
||||
fuer einen neuen Testfall (siehe doc/json-input-lisp.md fuer das
|
||||
allgemeine JSON-Schema).
|
||||
|
||||
Eine Polylinie kann auf einer gekippten Ebene liegen (Gruppencode
|
||||
|
||||
+25
-5
@@ -97,14 +97,31 @@ def load_flat_mapping(section, cfg_path=None):
|
||||
return {}
|
||||
|
||||
|
||||
def braucht_attribs(fn):
|
||||
"""Markiert einen Transform, der NEBEN seinem Rohwert auch das komplette
|
||||
Attribut-Dict des Blocks braucht - er wird dann als fn(wert, attribs)
|
||||
aufgerufen statt als fn(wert).
|
||||
|
||||
Noetig fuer Merkmale, deren Wert von einem ZWEITEN Attribut abhaengt: die
|
||||
AS-/ES-Seite (4428/4430) darf nur gefuellt werden, wenn der zugehoerige
|
||||
WINKEL_AS/WINKEL_ES ueberhaupt ein Element ausweist. Ohne diese Klammer
|
||||
muessten solche Merkmale wieder aus der Config heraus in Python-Code
|
||||
wandern - genau das soll sivas.cfg vermeiden.
|
||||
"""
|
||||
fn.braucht_attribs = True
|
||||
return fn
|
||||
|
||||
|
||||
def anwenden(section_mapping, attribs, transforms):
|
||||
"""Wendet eine per load_section_mapping() gelesene Zuordnung auf ein
|
||||
Block-Attribut-Dict an.
|
||||
|
||||
transforms: dict transform_name -> Funktion(wert) -> wert. Ein in der
|
||||
Config genannter, aber hier unbekannter Transform-Name wird ignoriert
|
||||
(Rohwert bleibt unveraendert) statt abzubrechen - ein Tippfehler in
|
||||
sivas.cfg darf den Export nicht zum Stillstand bringen.
|
||||
transforms: dict transform_name -> Funktion(wert) -> wert. Ein mit
|
||||
@braucht_attribs markierter Transform wird stattdessen als
|
||||
fn(wert, attribs) aufgerufen und sieht damit die uebrigen Attribute des
|
||||
Blocks. Ein in der Config genannter, aber hier unbekannter Transform-Name
|
||||
wird ignoriert (Rohwert bleibt unveraendert) statt abzubrechen - ein
|
||||
Tippfehler in sivas.cfg darf den Export nicht zum Stillstand bringen.
|
||||
|
||||
Rueckgabe: dict merkmal -> wert. Ohne Transform wird der Rohwert zu str()
|
||||
gewandelt (bisheriges Verhalten der build_*_details-Funktionen: alles
|
||||
@@ -124,7 +141,10 @@ def anwenden(section_mapping, attribs, transforms):
|
||||
if transform:
|
||||
fn = transforms.get(transform)
|
||||
if fn is not None:
|
||||
ergebnis[merkmal] = fn(wert)
|
||||
if getattr(fn, "braucht_attribs", False):
|
||||
ergebnis[merkmal] = fn(wert, attribs)
|
||||
else:
|
||||
ergebnis[merkmal] = fn(wert)
|
||||
continue
|
||||
ergebnis[merkmal] = str(wert)
|
||||
return ergebnis
|
||||
|
||||
@@ -65,6 +65,11 @@ PREFIX = "[vf_journal_export]"
|
||||
|
||||
XDATA_APP = "SSG_VF_EDIT"
|
||||
MARKER = "linienzug"
|
||||
# Marker -> Modus-Nummer. "linienzug" (Modus 1) hat ein Frage-Antwort-
|
||||
# Protokoll (Grammatik in vf_linienzug_grammatik.py); "linienzug2"/"3" werden
|
||||
# als Rohtokens ausgegeben - fuer sie gibt es bewusst keine Grammatik, ihre
|
||||
# SEGS-Eintraege machen sie ohnehin selbst-enthalten.
|
||||
MARKER_MODUS = {"linienzug": 1, "linienzug2": 2, "linienzug3": 3}
|
||||
|
||||
# Steuerzeichen-Notation des Eintrags-Trenners im ASCII-DXF (siehe Kopf).
|
||||
TRENNER = "^J"
|
||||
@@ -322,6 +327,19 @@ class ProtokollSink(Sink):
|
||||
self.add("point_abs", "getpoint Startpunkt der Kette (absoluter "
|
||||
"Weltpunkt, einziger Anker der ganzen Kette)", wert=punkt)
|
||||
|
||||
def as_achse(self, punkt):
|
||||
# Zweiter absoluter Punkt - gibt NUR die Richtung der Zufuehrung,
|
||||
# der Startpunkt bleibt der Sitz des AS-Elements. "nil" heisst: die
|
||||
# Frage wurde gestellt und bewusst uebergangen (die Kettenrichtung
|
||||
# kommt dann aus dem naechsten Klick).
|
||||
if punkt is None:
|
||||
self.add("nil", "getpoint Zufuehrungsachse - 2. Punkt: keiner "
|
||||
"gewaehlt, Richtung kommt aus dem naechsten Klick")
|
||||
else:
|
||||
self.add("point_abs", "getpoint Zufuehrungsachse - 2. Punkt "
|
||||
"(gibt nur die Richtung, der Startpunkt bleibt)",
|
||||
wert=punkt)
|
||||
|
||||
def linie(self, dl, hz, frage):
|
||||
was = _vorlage(_LINIE_TEXT, frage)
|
||||
if hz is None:
|
||||
@@ -541,6 +559,58 @@ def baue_testfaelle(inserts, strecken, startpunkt_fix, quelle_datei,
|
||||
return faelle
|
||||
|
||||
|
||||
def baue_tokenfaelle(inserts, quelle_datei):
|
||||
"""Modus-2/3-Ketten als TOKEN-Records (flache Liste, Kopf + Eintraege).
|
||||
|
||||
Warum nicht wie Modus 1 als Frage-Antwort-Protokoll: dafuer braeuchte es
|
||||
eine Grammatik des Modus-2/3-Fragenflusses, die es (bewusst, siehe
|
||||
doc/todo/spec-modus2-3.md) nicht gibt. Die Tokens selbst sind aber bereits
|
||||
aussagekraeftig - vor allem traegt SEGS die komplette Segment-Essenz, womit
|
||||
die Kette OHNE Zeichnung abspielbar ist.
|
||||
|
||||
Ausgabeformat ist genau das, was tests/test_linienzug.lsp
|
||||
(c:TEST_LINIENZUG_MODUS2) einliest:
|
||||
{"art": "PT", "x": .., "y": .., "z": ..}
|
||||
{"art": "REAL", "wert": ..} {"art": "INT", "wert": ..}
|
||||
{"art": "STR", "wert": ".."} {"art": "SEGS", "wert": ".."}
|
||||
Die Metadaten-Zeile (beschreibung/erwartung_*) ist bewusst NICHT dabei -
|
||||
die wird je Testfall von Hand gepflegt und soll beim Neuerzeugen nicht
|
||||
stillschweigend ueberschrieben werden.
|
||||
"""
|
||||
faelle = []
|
||||
for nr, e in enumerate(sorted(inserts, key=lambda i: i["x"]), start=1):
|
||||
toks = tokens_aus_journal(e["journal_roh"])
|
||||
modus = MARKER_MODUS.get(e["marker"], 0)
|
||||
kopf = {
|
||||
"test_id": "VF_%s_M%d_%02d" % (TEST_ID_ANLAGE, modus, nr),
|
||||
"anlagetyp": e["marker"],
|
||||
"modus": modus,
|
||||
"anzahl_eingaben": len(toks),
|
||||
"block": e["block"],
|
||||
"dxf_handle": e["handle"],
|
||||
"beschreibung": ("Linienzug Modus %d, %d Journal-Eintraege - "
|
||||
"Rohtokens, siehe doc/todo/spec-modus2-3.md"
|
||||
% (modus, len(toks))),
|
||||
"quelle": ("INSERT %s (Block %s) in %s, XDATA-App %s, Marker %s"
|
||||
% (e["handle"], e["block"],
|
||||
os.path.basename(quelle_datei), XDATA_APP,
|
||||
e["marker"])),
|
||||
}
|
||||
faelle.append(kopf)
|
||||
for art, wert in toks:
|
||||
if art == "PT":
|
||||
x, y, z = [float(v) for v in wert.split(",")]
|
||||
faelle.append({"art": "PT", "x": round(x, RUND),
|
||||
"y": round(y, RUND), "z": round(z, RUND)})
|
||||
elif art == "REAL":
|
||||
faelle.append({"art": "REAL", "wert": float(wert)})
|
||||
elif art == "INT":
|
||||
faelle.append({"art": "INT", "wert": int(wert)})
|
||||
else:
|
||||
faelle.append({"art": art, "wert": wert})
|
||||
return faelle
|
||||
|
||||
|
||||
def arrays_einzeilig(text):
|
||||
"""Rein numerische JSON-Arrays auf eine Zeile ziehen (wie
|
||||
dxf_scan_components.py) - ssg-parse-json-array (Lisp/ssg_core.lsp) liest
|
||||
@@ -585,9 +655,20 @@ def main():
|
||||
print("%s %d verbundene Strecken im Sivas-Export"
|
||||
% (PREFIX, len(strecken)))
|
||||
|
||||
faelle = baue_testfaelle(inserts, strecken,
|
||||
not args.kein_startpunkt_fix, args.dxf,
|
||||
args.output)
|
||||
# Nach Modus trennen: nur Modus 1 hat eine Grammatik. Frueher lief die
|
||||
# Modus-1-Grammatik auch ueber "linienzug2"/"3" (der startswith-Filter
|
||||
# laesst sie durch) und brach mit "Token 6: STEP erwartet" ab.
|
||||
m1 = [e for e in inserts if MARKER_MODUS.get(e["marker"]) == 1]
|
||||
m23 = [e for e in inserts if MARKER_MODUS.get(e["marker"]) in (2, 3)]
|
||||
faelle = []
|
||||
if m1:
|
||||
faelle.extend(baue_testfaelle(m1, strecken,
|
||||
not args.kein_startpunkt_fix, args.dxf,
|
||||
args.output))
|
||||
if m23:
|
||||
print("%s %d Modus-2/3-Kette(n) als Rohtokens (keine Grammatik, "
|
||||
"siehe doc/todo/spec-modus2-3.md)" % (PREFIX, len(m23)))
|
||||
faelle.extend(baue_tokenfaelle(m23, args.dxf))
|
||||
koepfe = [f for f in faelle if "test_id" in f]
|
||||
for f in koepfe:
|
||||
print("%s %s %s (%s) %d Eingaben"
|
||||
|
||||
@@ -287,6 +287,12 @@ class Sink(object):
|
||||
def praeambel_start(self):
|
||||
"""Kettenkopf beginnt (Startpunkt/Starthoehe/AS-Element)."""
|
||||
|
||||
def as_achse(self, punkt):
|
||||
"""Zufuehrungsachse des AS-Elements verbraucht (2. Punkt, gibt nur
|
||||
die Richtung). punkt = [x, y, z] oder None, wenn die Kette bewusst
|
||||
OHNE Achse gebaut wurde. Wird gar nicht gerufen, wenn das Journal
|
||||
diese Frage noch nicht kennt (vor 2026-10-21)."""
|
||||
|
||||
def praeambel_ende(self):
|
||||
"""Kettenkopf fertig."""
|
||||
|
||||
@@ -518,9 +524,31 @@ class Kern(object):
|
||||
self.sink.real_feld("hoehe", self.real(), "start_hoehe")
|
||||
if self._ja("as", "AS-Element setzen", "as"):
|
||||
self.sink.roh_feld("as_winkel", self.nimm("STR"), "as_winkel")
|
||||
self._code("as_seite", SEITE, "AS-Seite", "as_seite")
|
||||
# Drei Journal-Formate, unterscheidbar an der Eintragsart (siehe
|
||||
# vfl-frage-as-winkel-seite-oder-achse):
|
||||
# PT direkt nach dem Winkel -> Alt-Achse ohne Seitenfrage
|
||||
# (30-Grad-Element, 2026-10-14
|
||||
# bis 10-20); die Seite wurde
|
||||
# damals aus der Lage des
|
||||
# naechsten Punkts ermittelt.
|
||||
# STR, dann PT bzw. NIL -> Format ab 2026-10-21: Seite UND
|
||||
# (optionale) Zufuehrungsachse.
|
||||
# STR, dann etwas anderes -> Altbestand ohne Achsenfrage.
|
||||
if self.art() == "PT":
|
||||
self._as_achse()
|
||||
else:
|
||||
self._code("as_seite", SEITE, "AS-Seite", "as_seite")
|
||||
if self.art() == "PT":
|
||||
self._as_achse()
|
||||
elif self.art() == "NIL":
|
||||
self.nimm("NIL")
|
||||
self.sink.as_achse(None)
|
||||
self.sink.praeambel_ende()
|
||||
|
||||
def _as_achse(self):
|
||||
"""Zufuehrungsachse: zweiter Punkt, der NUR die Richtung gibt."""
|
||||
self.sink.as_achse([float(v) for v in self.nimm("PT").split(",")])
|
||||
|
||||
def sektionen(self):
|
||||
while self.pos < len(self.tok):
|
||||
label = self.nimm("STEP")
|
||||
|
||||
@@ -87,6 +87,11 @@ def tokens_aus_protokoll(eintraege):
|
||||
tok.append(("STR", str(e["wert"])))
|
||||
elif typ == "step":
|
||||
tok.append(("STEP", str(e["wert"])))
|
||||
elif typ == "nil":
|
||||
# Eine Frage, die gestellt und bewusst uebergangen wurde (bisher
|
||||
# nur die Zufuehrungsachse des AS-Elements) - im Journal ein
|
||||
# "NIL"-Eintrag ohne Wert.
|
||||
tok.append(("NIL", None))
|
||||
else:
|
||||
raise ValueError("unbekannter Eintragstyp: %r" % typ)
|
||||
return tok
|
||||
@@ -255,6 +260,14 @@ class SpecSink(Sink):
|
||||
def punkt_abs(self, punkt):
|
||||
self.ziel["punkt"] = punkt
|
||||
|
||||
def as_achse(self, punkt):
|
||||
# Zufuehrungsachse des AS-Elements. "ohne" ist NICHT dasselbe wie ein
|
||||
# fehlendes Feld: "ohne" heisst "die Frage wurde gestellt und bewusst
|
||||
# uebergangen" (NIL im Journal), ein fehlendes Feld heisst "das
|
||||
# Journal kennt die Frage gar nicht" (vor 2026-10-21). Nur so bleibt
|
||||
# der Rundlauf Journal -> Spec -> Journal tokengleich.
|
||||
self.ziel["as_achse"] = punkt if punkt is not None else "ohne"
|
||||
|
||||
def linie(self, dl, hz, frage):
|
||||
self.ziel["dl"] = dl
|
||||
if hz is not None:
|
||||
@@ -398,6 +411,14 @@ class SpecSchreiber(object):
|
||||
self.raus("STR", str(self.feld(start, "as_winkel")))
|
||||
self.raus("STR", code_aus_wert(SEITE, self.feld(start, "as_seite"),
|
||||
"as_seite"))
|
||||
# Optional, Gegenstueck zu SpecSink.as_achse und zu
|
||||
# vsp-praeambel in Lisp/vf_spec.lsp: Liste -> PT, "ohne" -> NIL,
|
||||
# fehlt -> gar kein Token (Journalformat vor 2026-10-21).
|
||||
achse = start.get("as_achse")
|
||||
if isinstance(achse, (list, tuple)):
|
||||
self.raus("PT", ",".join(_zahl(v) for v in achse))
|
||||
elif achse == "ohne":
|
||||
self.raus("NIL", None)
|
||||
|
||||
def sektion(self, sek, erster, naechste=None):
|
||||
label = self.feld(sek, "glied")
|
||||
@@ -641,6 +662,11 @@ def flache_objekte(spec_id, spec, kopf_extra=None):
|
||||
if start["as"]:
|
||||
kopf["as_winkel"] = start["as_winkel"]
|
||||
kopf["as_seite"] = start["as_seite"]
|
||||
# Nur schreiben, wenn vorhanden - ein fehlendes Feld ist die
|
||||
# bewusste Aussage "Journalformat ohne Achsenfrage" (siehe
|
||||
# SpecSink.as_achse), kein Datenverlust.
|
||||
if "as_achse" in start:
|
||||
kopf["as_achse"] = start["as_achse"]
|
||||
for k, v in (kopf_extra or collections.OrderedDict()).items():
|
||||
kopf[k] = v
|
||||
objekte.append(kopf)
|
||||
|
||||
+4
-4
@@ -118,7 +118,7 @@
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00030">
|
||||
<Macro>
|
||||
<Name>3D Objekte stueckweise (in Arbeit)</Name>
|
||||
<Name>aus 3D Linie ohne Zielhoehe</Name>
|
||||
<Command>^C^C(ssg-ensure "VarioFoerderer") LinienzugVarioFoerdererStueckweise</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
@@ -401,7 +401,7 @@
|
||||
<MenuMacro UID="MM_00095">
|
||||
<Macro>
|
||||
<Name>KettenFoerderer</Name>
|
||||
<Command>^C^C(ssg-ensure "OmniModulInsert") OMNI_KettenFoerderer</Command>
|
||||
<Command>^C^C(ssg-ensure "KettenFoerderer") KETTENFOERDERER</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00096">
|
||||
@@ -1155,7 +1155,7 @@
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>3D Objekte stueckweise (in Arbeit)</NameRef>
|
||||
<NameRef>aus 3D Linie ohne Zielhoehe</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00030"/>
|
||||
</MenuItem>
|
||||
@@ -1217,7 +1217,7 @@
|
||||
<PopMenuRef pUID="PM_00084"/>
|
||||
<PopMenuRef pUID="PM_00088"/>
|
||||
<PopMenuItem>
|
||||
<NameRef>~KettenFoerderer</NameRef>
|
||||
<NameRef>KettenFoerderer</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00095"/>
|
||||
</MenuItem>
|
||||
|
||||
@@ -156,8 +156,17 @@
|
||||
(ssg-ensure "VarioFoerderer")
|
||||
(ssg-ensure "EtageVarioFoerderer")
|
||||
(ssg-ensure "export")
|
||||
;; Hoehen-Check vorladen: EXPORTSIVAS bietet ihn per Rueckfrage an und ruft
|
||||
;; c:HOEHEN_CHECK im selben Lauf auf (ein Nachladen waere dort erst nach
|
||||
;; Rueckkehr zum Top-Level sichtbar).
|
||||
(ssg-ensure "check_hoehen")
|
||||
(ssg-ensure "external_call")
|
||||
(ssg-ensure "OmniModulInsert")
|
||||
;; Kettenfoerderer vorladen statt lazy: der erste Menueklick musste sonst
|
||||
;; das Laden des Moduls mitbezahlen, der Dialog erschien dadurch spuerbar
|
||||
;; verzoegert. Das Modul ist klein, der Startaufschlag faellt nicht ins
|
||||
;; Gewicht. (Zum Nachmessen: Schalter "kf-zeit", siehe KettenFoerderer.lsp)
|
||||
(ssg-ensure "KettenFoerderer")
|
||||
;; Tro_Edit wird nicht vorgeladen - der Dispatcher SSG_BLOCKEDIT und die
|
||||
;; Menuemakros holen es per (ssg-ensure "Tro_Edit") bei Bedarf nach.
|
||||
(ssg-ensure "SSG_LIB_Commands")
|
||||
|
||||
+4
-3
@@ -27,7 +27,7 @@
|
||||
[->Streckengruppe]
|
||||
[Werte manuell]^C^C(ssg-ensure "VarioFoerderer") LinienzugVarioFoerdererManuell
|
||||
[aus 3D Linie mit Zielhoehe]^C^C(ssg-ensure "VarioFoerderer") LinienzugVarioFoerdererZielhoehe
|
||||
[<-3D Objekte stueckweise (in Arbeit)]^C^C(ssg-ensure "VarioFoerderer") LinienzugVarioFoerdererStueckweise
|
||||
[<-aus 3D Linie ohne Zielhoehe]^C^C(ssg-ensure "VarioFoerderer") LinienzugVarioFoerdererStueckweise
|
||||
[Vario_Kette_Merge]^C^C(ssg-ensure "VarioFoerderer") Vario_Kette_Merge
|
||||
[<-VarioFoerderer nachruesten (Marker)]^C^C(ssg-ensure "VarioFoerderer") VARIOFOERDERER_NACHRUESTEN
|
||||
[->Gefaellestrecke]
|
||||
@@ -92,7 +92,7 @@
|
||||
[Schwenkschiene Schiebetür R]^C^C(ssg-ensure "OmniModulInsert") OMNI_SCHW_400_R
|
||||
[Schwenkschiene Schiebetür L mit Sensorik]^C^C(ssg-ensure "OmniModulInsert") OMNI_SCHW_400_L_SENSORIK
|
||||
[<-<-<-Schwenkschiene Schiebetür R mit Sensorik]^C^C(ssg-ensure "OmniModulInsert") OMNI_SCHW_400_R_SENSORIK
|
||||
[~KettenFoerderer]^C^C(ssg-ensure "OmniModulInsert") OMNI_KettenFoerderer
|
||||
[KettenFoerderer]^C^C(ssg-ensure "KettenFoerderer") KETTENFOERDERER
|
||||
[Ladeschleifen]^C^C(ssg-ensure "OmniModulInsert") OMNI_LADESCHLEIFE_AP110
|
||||
[->Verbinder]
|
||||
[TV W-AP110 kpl]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_AP110
|
||||
@@ -164,6 +164,7 @@
|
||||
[Ausgang]^C^C(ssg-ensure "SSG_LIB_Commands") ILS_AUSGANG_INSERT
|
||||
[<-SPS Schliessen]^C^C
|
||||
[->Export]
|
||||
[Hoehen-Check (Montagehoehe/Buehne)]^C^C(ssg-ensure "check_hoehen") HOEHEN_CHECK
|
||||
[Export Sivas]^C^C(ssg-ensure "export") EXPORTSIVAS
|
||||
[<-Export CSV]^C^C(ssg-ensure "export") EXPORTCSV
|
||||
[->Konfiguration]
|
||||
@@ -192,7 +193,7 @@
|
||||
[--]
|
||||
[Kreisel]^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_kreisel.lsp")) (c:TEST_KREISEL)
|
||||
[Foerderer]^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_foerderer.lsp")) (c:TEST_FOERDERER)
|
||||
[Foerderer-Linienzug]^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_linienzug.lsp")) (c:TEST_LINIENZUG) (c:TEST_LINIENZUG_STUFE2)
|
||||
[Foerderer-Linienzug]^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_linienzug.lsp")) (c:TEST_LINIENZUG) (c:TEST_LINIENZUG_STUFE2) (c:TEST_LINIENZUG_MODUS2)
|
||||
[Omniflo]^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_omniflo.lsp")) (c:TEST_OMNIFLO)
|
||||
[Omniflo Strecke]^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_omniflo_strecke.lsp")) (c:TEST_OMNIFLO_STRECKE)
|
||||
[Gefaellestrecke]^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_gefaellestrecke.lsp")) (c:TEST_GEFAELLESTRECKE)
|
||||
|
||||
+147
@@ -87,6 +87,153 @@ dem gewuenschten Modus:
|
||||
Lauf ohne manuellen Zusatzschritt, aber ohne gleichzeitige visuelle Kontrolle
|
||||
aller Zeichnungen am Ende. Sinnvoll fuer reine CI-artige Validierung.
|
||||
|
||||
## Anordnung der Linienzug-Testketten
|
||||
|
||||
Der Menueeintrag **Tests -> Foerderer-Linienzug** faehrt drei Befehle
|
||||
nacheinander (`TEST_LINIENZUG`, `TEST_LINIENZUG_STUFE2`,
|
||||
`TEST_LINIENZUG_MODUS2`) und baut dabei **sieben** Ketten. Damit sie
|
||||
nebeneinander auf einer Grundlinie entstehen statt verstreut, tragen die
|
||||
Testdaten versetzte Startpunkte - 20 m Abstand, alle auf `Y = 0`:
|
||||
|
||||
| X | Z | Kette | Datei |
|
||||
|---|---|---|---|
|
||||
| 0 | 2154 | Modus 1, Standardfall | `linienzug_tests.json` |
|
||||
| 20000 | 2154 | Modus 1, Stufe-2-Fallback | `linienzug_tests_stufe2.json` |
|
||||
| 40000 | 0 | Variante A (Vario-Kurve) | `linienzug_modus2_variokurve.json` |
|
||||
| 60000 | 0 | Variante B (GF-Bogen) | `linienzug_modus2_gfbogen.json` |
|
||||
| 80000 | 355 | U-Form 1 (GF alles am Einlauf) | `..._uform_gf1.json` |
|
||||
| 100000 | 711 | U-Form 2 (1/2 + 1/2) | `..._uform_halb.json` |
|
||||
| 120000 | 709 | U-Form 3 (steilerer Winkel) | `..._uform_halb_steil.json` |
|
||||
|
||||
Die Koordinaten sind also **nicht** die der aufgezeichneten Laeufe, die
|
||||
uebrige Geometrie schon. Verschoben wurde rein translatorisch: Laengen,
|
||||
Winkel und die geprueften Abweichungen sind davon unabhaengig. `Z` blieb
|
||||
jeweils stehen - die Starthoehe ist ein Eingabewert des Solvers, kein
|
||||
Layout-Parameter.
|
||||
|
||||
Technisch unterscheiden sich die beiden Datenarten: die Modus-1-Skripte
|
||||
brauchen nur ihren EINEN `point_abs` (alles Weitere ist `point_rel` mit
|
||||
`dL`/`hz`), waehrend bei Modus 2 sowohl die `PT`-Eintraege ALS AUCH die
|
||||
Pfadkoordinaten in `SEGS` (Felder 6..9) mitwandern muessen - sonst zeigt der
|
||||
Pfad woanders hin als Start und Ziel.
|
||||
|
||||
## Referenzfaelle Linienzug Modus 2 (`c:TEST_LINIENZUG_MODUS2`)
|
||||
|
||||
Fuenf aufgezeichnete Laeufe, die als zwei Paare gebildet sind: A/B
|
||||
unterscheiden die Eck-BAUTEILART, U-Form 1..3 den gefalteten Lauf nach
|
||||
GF-Verteilung und Winkel. Ausgefuehrt ueber Menue -> Tests ->
|
||||
Foerderer-Linienzug.
|
||||
|
||||
### Erster und zweiter Fall: Eck-Bauteilart
|
||||
|
||||
Zwei Laeufe auf **demselben gezeichneten Pfad**, die sich nur in der
|
||||
Segment-Klassifizierung unterscheiden. Sie decken die beiden Eck-Bauteilarten
|
||||
ab (waagerecht eingebaute Vario-Kurve und geneigt eingebauter Gefaellebogen)
|
||||
und haben am 2026-10-26 sieben Budget-Fehler aufgedeckt, die ein einzelner
|
||||
Lauf nicht gezeigt haette - erst der VERGLEICH zweier Varianten machte
|
||||
sichtbar, dass eine Korrektur am falschen Segment landete.
|
||||
|
||||
**Gezeichneter Pfad** (5 Objekte, Boegen als R500-Verrundung):
|
||||
|
||||
| Segment | Art | Mass |
|
||||
|---|---|---|
|
||||
| 1 | Linie | L = 9700 mm, hz = 0 |
|
||||
| 2 | Bogen | 90 Grad rechts, R500 |
|
||||
| 3 | Linie | L = 4296 mm, hz = -90 |
|
||||
| 4 | Bogen | 30 Grad links, R500 |
|
||||
| 5 | Linie | L = 1466 mm, hz = -60 |
|
||||
|
||||
**Gemeinsame Eingaben:** AS-Element ja, 90 Grad, links. ES-Element ja,
|
||||
30 Grad, rechts. Lauf beginnen mit "Umlenkstation mit GF1 + Separator",
|
||||
GF-Verteilung "alles am Einlauf", keine zusaetzlichen Separatoren.
|
||||
|
||||
| | Variante A | Variante B |
|
||||
|---|---|---|
|
||||
| Segment 2 | **Vario-Kurve** (aussen) | **GF-Bogen** |
|
||||
| Segment 3 | VF (automatisch nach Kurve) | GF |
|
||||
| Segment 4 | GF-Bogen | GF-Bogen |
|
||||
| Segment 5 | GF | GF |
|
||||
| VF-Lauf | Segment 1..3 | Segment 1..1 |
|
||||
|
||||
**Soll-Ergebnis fuer BEIDE Varianten:**
|
||||
|
||||
- `Quer zur Achse` **~0** (gemessen 0.2 mm - das ist die Aufloesung der
|
||||
Blockmessung, kein Restfehler)
|
||||
- `dZ` **0**
|
||||
- `Laengs KS_AUS-Achse` darf abweichen (~104 mm) - das ist die Ausladung des
|
||||
ES-Elements und ausdruecklich zulaessig.
|
||||
|
||||
Die Regel dahinter: **quer zur KS_AUS-Achse MUSS 0 sein, laengs darf
|
||||
abweichen, dZ MUSS 0 sein.** Beides zugleich geht nicht - entweder liegt die
|
||||
letzte Gerade auf der gezeichneten Linie und der ES-`KS_AUS` landet seitlich
|
||||
daneben, oder umgekehrt. Entschieden ist: der Hauptstrang bleibt gerade, der
|
||||
seitliche Versatz des ES-Elements ist dessen Bauform und kein Fehler.
|
||||
|
||||
**`laengs` wird trotzdem geprueft** - nicht als Genauigkeits-, sondern als
|
||||
FORMkriterium (`erwartung_laengs_mm` in den Testdaten, Toleranz 5 mm). Der Wert
|
||||
ist die Ausladung des ES-Elements und damit je Fall eine Konstante: 104.68 mm
|
||||
bei `ES_Element_30`, 637.58 mm bei `ES_Element_90`.
|
||||
Grund: am 2026-10-29 loeste ein Experiment den Schluss-Fueller gegen Richtung
|
||||
UND Laenge und traf den Zielpunkt dadurch in X und Y exakt - um den Preis, dass
|
||||
es die letzte Gerade um 6.15 Grad verdrehte. `quer` und `dZ` waren dabei NULL,
|
||||
der Test meldete brav OK, und der schiefe Schenkel fiel nur beim Blick in die
|
||||
Zeichnung auf. Ein verdrehter Hauptstrang zielt auf den Endpunkt und drueckt
|
||||
`laengs` von ~638 mm auf ~0 - genau daran ist er zu erkennen.
|
||||
Die Pruefung selbst ist gegengeprueft: mit einer kuenstlich auf 0.01 mm
|
||||
gesetzten Toleranz kippen alle fuenf Faelle auf ABWEICHUNG.
|
||||
|
||||
Im Protokoll muessen die Zuschlags-Zeilen erscheinen: `AS-Fussabdruck`,
|
||||
`Eck-Korrektur` je Ecke, und bei Variante A zusaetzlich
|
||||
`Abschluss-Fussabdruck`. **Eine FEHLENDE Zeile ist das Warnsignal** - sie
|
||||
bedeutet, dass ein Eck-Bauteil nicht messbar war und die Ecke unkorrigiert
|
||||
blieb (so wurde der 2.4-mm-Rest bei Variante B gefunden).
|
||||
|
||||
> **Automatisiert seit 2026-10-27** als `c:TEST_LINIENZUG_MODUS2` (Menue:
|
||||
> Tests -> Foerderer-Linienzug). Der Pfad muss dafuer NICHT gezeichnet werden:
|
||||
> ein Modus-2-Journal traegt einen `SEGS`-Eintrag mit der kompletten
|
||||
> Segment-Essenz und ist damit von den Original-Objekten unabhaengig - der
|
||||
> Test spielt schlicht das mit `lib/vf_journal_export.py` ausgelesene Journal
|
||||
> ab. Die reinen Rechenkerne sind zusaetzlich file-frei abgedeckt
|
||||
> (`tu-tests-vfl-parallel` in `test_unit.lsp`: `vfl-eck-zerlegen`,
|
||||
> `vfl-es-achs-reserve`, `vfl-projiziere-neigung` - jeweils mit den echten
|
||||
> Messwerten aus diesen beiden Laeufen).
|
||||
|
||||
### Dritter bis fuenfter Fall: gefalteter Lauf (U-Form)
|
||||
|
||||
Aufgezeichnet 2026-10-29, Datendateien `tests/testdata/linienzug_modus2_uform_*.json`.
|
||||
|
||||
Der Pfad wechselt ueber zwei 90-Grad-Vario-Kurven **dreimal die
|
||||
Fahrtrichtung**; die Kletterstrecke liegt dadurch in einem ANDEREN Schenkel als
|
||||
der Lauf-Eingang. Genau diese Konstellation war bis 2026-10-29 falsch
|
||||
bilanziert (gemessen 1424 mm quer), weil Posten dem falschen Schenkel
|
||||
zugerechnet wurden.
|
||||
|
||||
| Segment | Art | Mass |
|
||||
|---|---|---|
|
||||
| 1 | Linie | L = 5855 mm, hz = 90 |
|
||||
| 2 | Bogen | 90 Grad rechts, R500 -> **Vario-Kurve aussen** |
|
||||
| 3 | Linie | L = 270 mm, hz = 0 (automatisch VF) |
|
||||
| 4 | Bogen | 90 Grad rechts, R500 -> **Vario-Kurve aussen** |
|
||||
| 5 | Linie | L = 7806 mm, hz = -90 (der Kletterer) |
|
||||
|
||||
| Fall | GF-Verteilung | Winkel-Option | Testdatei |
|
||||
|---|---|---|---|
|
||||
| U-Form 1 | alles am Einlauf (GF1) | 2 | `..._uform_gf1.json` |
|
||||
| U-Form 2 | 1/2 GF1 + 1/2 GF2 | 2 (= 9 Grad) | `..._uform_halb.json` |
|
||||
| U-Form 3 | 1/2 GF1 + 1/2 GF2 | 3 (steiler) | `..._uform_halb_steil.json` |
|
||||
|
||||
**Warum drei und nicht einer:** die GF-VERTEILUNG entscheidet, ob ueberhaupt
|
||||
Gefaellestrecke im fremden Schenkel steht (und damit, ob Nachrechner und das
|
||||
unterdrueckte Fueller-A greifen) - mit "alles am Einlauf" liegt das gesamte GF1
|
||||
dort, mit 1/2+1/2 nur die Haelfte. Der WINKEL ist noetig, weil der Restfehler
|
||||
der alten Bilanz mit `L_GF` skalierte: bei 6 Grad waren es 90 mm, bei 9 Grad
|
||||
934 mm. Zwei Laeufe mit demselben Winkel haetten den Fehler also beinahe
|
||||
verdeckt.
|
||||
|
||||
Soll-Ergebnis wie oben: `quer` und `dZ` jeweils ~0 (gemessen 0.56 mm bei
|
||||
9 Grad und 0.7 mm bei der steileren Option), `laengs` ~638 mm - das ist die
|
||||
Ausladung des `ES_Element_90_links` und in allen drei Faellen gleich.
|
||||
|
||||
## alltests.json — Testregistry
|
||||
|
||||
Die Datei `tests/alltests.json` ist die zentrale Registry aller Test-Module.
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];IDs;details
|
||||
1;"ILS 2.0 Strecke";"6220";"VF_13";20;1;;"0013";{"Anlagenhöhe in Meter": "-1.5", "Streckengruppe": "mehrere Objekte", "Strecken- zu fertigende Menge": "1", "Streckengruppe - Gefällestrecke": "Ja", "Streckengruppe - Gefällestrecke 001-Länge in Meter": "0.0", "Streckengruppe - Gefällestrecke 001 -Winkel": "3", "Streckengruppe - Gefällestrecke 002": "Ja", "Streckengruppe - Gefällestrecke 002-Länge in Meter": "0.707", "Streckengruppe - Gefällestrecke 002- Winkel": "3", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 30°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 30°": "0", "Streckengruppe - Anzahl der Separatoren - Gefällestrecke": "0", "Streckengruppe - Bearbeitung Gefällestreckenteilstück für Separator (829516050)": "ohne HARTCOAT HRC 50 ± 5", "Streckengruppe - Anzahl der Scanner": "0", "Streckengruppe - Varioförderer": "Ja", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (links)": "0", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (rechts)": "1", "Streckengruppe - Varioförderer 001-Länge in Meter": "3.055", "Streckengruppe - Varioförderer 001-Richtung": "ab", "Streckengruppe - Varioförderer 001- Winkel": "39", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 30°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 30°": "0", "Streckengruppe - Anzahl der Separatoren - Varioförderer": "2", "Gerüst für Einzelmodul": "Nein", "Gerüstoption für Einzelmodul": "Schönenberger-Gerüst"}
|
||||
2;"ILS 2.0 Strecke";"6220";"VF_12";20;1;;"0012";{"Anlagenhöhe in Meter": "0.5", "Streckengruppe": "mehrere Objekte", "Strecken- zu fertigende Menge": "1", "Streckengruppe - Gefällestrecke": "Ja", "Streckengruppe - Gefällestrecke 001-Länge in Meter": "0.084", "Streckengruppe - Gefällestrecke 001 -Winkel": "3", "Streckengruppe - Gefällestrecke 002": "Ja", "Streckengruppe - Gefällestrecke 002-Länge in Meter": "0.0", "Streckengruppe - Gefällestrecke 002- Winkel": "3", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 30°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 30°": "0", "Streckengruppe - Anzahl der Separatoren - Gefällestrecke": "0", "Streckengruppe - Bearbeitung Gefällestreckenteilstück für Separator (829516050)": "ohne HARTCOAT HRC 50 ± 5", "Streckengruppe - Anzahl der Scanner": "0", "Streckengruppe - Varioförderer": "Ja", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (links)": "0", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (rechts)": "1", "Streckengruppe - Varioförderer 001-Länge in Meter": "3.478", "Streckengruppe - Varioförderer 001-Richtung": "auf", "Streckengruppe - Varioförderer 001- Winkel": "21", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 30°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 30°": "0", "Streckengruppe - Anzahl der Separatoren - Varioförderer": "2", "Gerüst für Einzelmodul": "Nein", "Gerüstoption für Einzelmodul": "Schönenberger-Gerüst"}
|
||||
3;"ILS 2.0 Strecke";"6220";"VF_11";20;1;;"0011";{"Anlagenhöhe in Meter": "1.5", "Streckengruppe": "mehrere Objekte", "Strecken- zu fertigende Menge": "1", "Streckengruppe - Gefällestrecke": "Ja", "Streckengruppe - Gefällestrecke 001-Länge in Meter": "0.166", "Streckengruppe - Gefällestrecke 001 -Winkel": "3", "Streckengruppe - Gefällestrecke 002": "Ja", "Streckengruppe - Gefällestrecke 002-Länge in Meter": "0.166", "Streckengruppe - Gefällestrecke 002- Winkel": "3", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 30°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 30°": "0", "Streckengruppe - Anzahl der Separatoren - Gefällestrecke": "0", "Streckengruppe - Bearbeitung Gefällestreckenteilstück für Separator (829516050)": "ohne HARTCOAT HRC 50 ± 5", "Streckengruppe - Anzahl der Scanner": "0", "Streckengruppe - Varioförderer": "Ja", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (links)": "0", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (rechts)": "1", "Streckengruppe - Varioförderer 001-Länge in Meter": "3.207", "Streckengruppe - Varioförderer 001-Richtung": "auf", "Streckengruppe - Varioförderer 001- Winkel": "51", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 30°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 30°": "0", "Streckengruppe - Anzahl der Separatoren - Varioförderer": "2", "Gerüst für Einzelmodul": "Nein", "Gerüstoption für Einzelmodul": "Schönenberger-Gerüst"}
|
||||
4;"ILS 2.0 Strecke";"6220";"VF_10";20;1;;"0010";{"Anlagenhöhe in Meter": "-1", "Streckengruppe": "mehrere Objekte", "Strecken- zu fertigende Menge": "1", "Streckengruppe - Gefällestrecke": "Ja", "Streckengruppe - Gefällestrecke 001-Länge in Meter": "0.541", "Streckengruppe - Gefällestrecke 001 -Winkel": "3", "Streckengruppe - Gefällestrecke 002": "Ja", "Streckengruppe - Gefällestrecke 002-Länge in Meter": "0.541", "Streckengruppe - Gefällestrecke 002- Winkel": "3", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 30°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 30°": "0", "Streckengruppe - Anzahl der Separatoren - Gefällestrecke": "0", "Streckengruppe - Bearbeitung Gefällestreckenteilstück für Separator (829516050)": "ohne HARTCOAT HRC 50 ± 5", "Streckengruppe - Anzahl der Scanner": "0", "Streckengruppe - Varioförderer": "Ja", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (links)": "0", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (rechts)": "1", "Streckengruppe - Varioförderer 001-Länge in Meter": "2.731", "Streckengruppe - Varioförderer 001-Richtung": "ab", "Streckengruppe - Varioförderer 001- Winkel": "27", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 30°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 30°": "0", "Streckengruppe - Anzahl der Separatoren - Varioförderer": "2", "Gerüst für Einzelmodul": "Nein", "Gerüstoption für Einzelmodul": "Schönenberger-Gerüst"}
|
||||
5;"ILS 2.0 Strecke";"6220";"VF_9";20;1;;"0009";{"Anlagenhöhe in Meter": "1", "Streckengruppe": "mehrere Objekte", "Strecken- zu fertigende Menge": "1", "Streckengruppe - Gefällestrecke": "Ja", "Streckengruppe - Gefällestrecke 001-Länge in Meter": "0.206", "Streckengruppe - Gefällestrecke 001 -Winkel": "3", "Streckengruppe - Gefällestrecke 002": "Ja", "Streckengruppe - Gefällestrecke 002-Länge in Meter": "0.206", "Streckengruppe - Gefällestrecke 002- Winkel": "3", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 30°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 30°": "0", "Streckengruppe - Anzahl der Separatoren - Gefällestrecke": "0", "Streckengruppe - Bearbeitung Gefällestreckenteilstück für Separator (829516050)": "ohne HARTCOAT HRC 50 ± 5", "Streckengruppe - Anzahl der Scanner": "0", "Streckengruppe - Varioförderer": "Ja", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (links)": "0", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (rechts)": "1", "Streckengruppe - Varioförderer 001-Länge in Meter": "3.07", "Streckengruppe - Varioförderer 001-Richtung": "auf", "Streckengruppe - Varioförderer 001- Winkel": "39", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 30°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 30°": "0", "Streckengruppe - Anzahl der Separatoren - Varioförderer": "2", "Gerüst für Einzelmodul": "Nein", "Gerüstoption für Einzelmodul": "Schönenberger-Gerüst"}
|
||||
6;"ILS 2.0 Strecke";"6220";"VF_8";20;1;;"0008";{"Anlagenhöhe in Meter": "-2", "Streckengruppe": "mehrere Objekte", "Strecken- zu fertigende Menge": "1", "Streckengruppe - Gefällestrecke": "Ja", "Streckengruppe - Gefällestrecke 001-Länge in Meter": "0.15", "Streckengruppe - Gefällestrecke 001 -Winkel": "3", "Streckengruppe - Gefällestrecke 002": "Ja", "Streckengruppe - Gefällestrecke 002-Länge in Meter": "0.15", "Streckengruppe - Gefällestrecke 002- Winkel": "3", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 30°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 30°": "0", "Streckengruppe - Anzahl der Separatoren - Gefällestrecke": "0", "Streckengruppe - Bearbeitung Gefällestreckenteilstück für Separator (829516050)": "ohne HARTCOAT HRC 50 ± 5", "Streckengruppe - Anzahl der Scanner": "0", "Streckengruppe - Varioförderer": "Ja", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (links)": "0", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (rechts)": "1", "Streckengruppe - Varioförderer 001-Länge in Meter": "4.067", "Streckengruppe - Varioförderer 001-Richtung": "ab", "Streckengruppe - Varioförderer 001- Winkel": "45", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 30°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 30°": "0", "Streckengruppe - Anzahl der Separatoren - Varioförderer": "2", "Gerüst für Einzelmodul": "Nein", "Gerüstoption für Einzelmodul": "Schönenberger-Gerüst"}
|
||||
7;"ILS 2.0 Strecke";"6220";"VF_7";20;1;;"0007";{"Anlagenhöhe in Meter": "-1.5", "Streckengruppe": "mehrere Objekte", "Strecken- zu fertigende Menge": "1", "Streckengruppe - Gefällestrecke": "Ja", "Streckengruppe - Gefällestrecke 001-Länge in Meter": "0.354", "Streckengruppe - Gefällestrecke 001 -Winkel": "3", "Streckengruppe - Gefällestrecke 002": "Ja", "Streckengruppe - Gefällestrecke 002-Länge in Meter": "0.354", "Streckengruppe - Gefällestrecke 002- Winkel": "3", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 30°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 30°": "0", "Streckengruppe - Anzahl der Separatoren - Gefällestrecke": "0", "Streckengruppe - Bearbeitung Gefällestreckenteilstück für Separator (829516050)": "ohne HARTCOAT HRC 50 ± 5", "Streckengruppe - Anzahl der Scanner": "0", "Streckengruppe - Varioförderer": "Ja", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (links)": "0", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (rechts)": "1", "Streckengruppe - Varioförderer 001-Länge in Meter": "3.055", "Streckengruppe - Varioförderer 001-Richtung": "ab", "Streckengruppe - Varioförderer 001- Winkel": "39", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 30°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 30°": "0", "Streckengruppe - Anzahl der Separatoren - Varioförderer": "2", "Gerüst für Einzelmodul": "Nein", "Gerüstoption für Einzelmodul": "Schönenberger-Gerüst"}
|
||||
8;"ILS 2.0 Strecke";"6220";"VF_6";20;1;;"0006";{"Anlagenhöhe in Meter": "-1", "Streckengruppe": "mehrere Objekte", "Strecken- zu fertigende Menge": "1", "Streckengruppe - Gefällestrecke": "Ja", "Streckengruppe - Gefällestrecke 001-Länge in Meter": "0.013", "Streckengruppe - Gefällestrecke 001 -Winkel": "3", "Streckengruppe - Gefällestrecke 002": "Ja", "Streckengruppe - Gefällestrecke 002-Länge in Meter": "0.013", "Streckengruppe - Gefällestrecke 002- Winkel": "3", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 30°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 30°": "0", "Streckengruppe - Anzahl der Separatoren - Gefällestrecke": "0", "Streckengruppe - Bearbeitung Gefällestreckenteilstück für Separator (829516050)": "ohne HARTCOAT HRC 50 ± 5", "Streckengruppe - Anzahl der Scanner": "0", "Streckengruppe - Varioförderer": "Ja", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (links)": "0", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (rechts)": "1", "Streckengruppe - Varioförderer 001-Länge in Meter": "3.701", "Streckengruppe - Varioförderer 001-Richtung": "ab", "Streckengruppe - Varioförderer 001- Winkel": "21", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 30°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 30°": "0", "Streckengruppe - Anzahl der Separatoren - Varioförderer": "2", "Gerüst für Einzelmodul": "Nein", "Gerüstoption für Einzelmodul": "Schönenberger-Gerüst"}
|
||||
9;"ILS 2.0 Strecke";"6220";"VF_5";20;1;;"0005";{"Anlagenhöhe in Meter": "-0.5", "Streckengruppe": "mehrere Objekte", "Strecken- zu fertigende Menge": "1", "Streckengruppe - Gefällestrecke": "Ja", "Streckengruppe - Gefällestrecke 001-Länge in Meter": "0.486", "Streckengruppe - Gefällestrecke 001 -Winkel": "3", "Streckengruppe - Gefällestrecke 002": "Ja", "Streckengruppe - Gefällestrecke 002-Länge in Meter": "0.486", "Streckengruppe - Gefällestrecke 002- Winkel": "3", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 30°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 30°": "0", "Streckengruppe - Anzahl der Separatoren - Gefällestrecke": "0", "Streckengruppe - Bearbeitung Gefällestreckenteilstück für Separator (829516050)": "ohne HARTCOAT HRC 50 ± 5", "Streckengruppe - Anzahl der Scanner": "0", "Streckengruppe - Varioförderer": "Ja", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (links)": "0", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (rechts)": "1", "Streckengruppe - Varioförderer 001-Länge in Meter": "3.056", "Streckengruppe - Varioförderer 001-Richtung": "ab", "Streckengruppe - Varioförderer 001- Winkel": "9", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 30°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 30°": "0", "Streckengruppe - Anzahl der Separatoren - Varioförderer": "2", "Gerüst für Einzelmodul": "Nein", "Gerüstoption für Einzelmodul": "Schönenberger-Gerüst"}
|
||||
10;"ILS 2.0 Strecke";"6220";"VF_4";20;1;;"0004";{"Anlagenhöhe in Meter": "1.5", "Streckengruppe": "mehrere Objekte", "Strecken- zu fertigende Menge": "1", "Streckengruppe - Gefällestrecke": "Ja", "Streckengruppe - Gefällestrecke 001-Länge in Meter": "0.166", "Streckengruppe - Gefällestrecke 001 -Winkel": "3", "Streckengruppe - Gefällestrecke 002": "Ja", "Streckengruppe - Gefällestrecke 002-Länge in Meter": "0.166", "Streckengruppe - Gefällestrecke 002- Winkel": "3", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 30°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 30°": "0", "Streckengruppe - Anzahl der Separatoren - Gefällestrecke": "0", "Streckengruppe - Bearbeitung Gefällestreckenteilstück für Separator (829516050)": "ohne HARTCOAT HRC 50 ± 5", "Streckengruppe - Anzahl der Scanner": "0", "Streckengruppe - Varioförderer": "Ja", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (links)": "0", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (rechts)": "1", "Streckengruppe - Varioförderer 001-Länge in Meter": "3.207", "Streckengruppe - Varioförderer 001-Richtung": "auf", "Streckengruppe - Varioförderer 001- Winkel": "51", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 30°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 30°": "0", "Streckengruppe - Anzahl der Separatoren - Varioförderer": "2", "Gerüst für Einzelmodul": "Nein", "Gerüstoption für Einzelmodul": "Schönenberger-Gerüst"}
|
||||
11;"ILS 2.0 Strecke";"6220";"VF_3";20;1;;"0003";{"Anlagenhöhe in Meter": "1", "Streckengruppe": "mehrere Objekte", "Strecken- zu fertigende Menge": "1", "Streckengruppe - Gefällestrecke": "Ja", "Streckengruppe - Gefällestrecke 001-Länge in Meter": "0.206", "Streckengruppe - Gefällestrecke 001 -Winkel": "3", "Streckengruppe - Gefällestrecke 002": "Ja", "Streckengruppe - Gefällestrecke 002-Länge in Meter": "0.206", "Streckengruppe - Gefällestrecke 002- Winkel": "3", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 30°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 30°": "0", "Streckengruppe - Anzahl der Separatoren - Gefällestrecke": "0", "Streckengruppe - Bearbeitung Gefällestreckenteilstück für Separator (829516050)": "ohne HARTCOAT HRC 50 ± 5", "Streckengruppe - Anzahl der Scanner": "0", "Streckengruppe - Varioförderer": "Ja", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (links)": "0", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (rechts)": "1", "Streckengruppe - Varioförderer 001-Länge in Meter": "3.07", "Streckengruppe - Varioförderer 001-Richtung": "auf", "Streckengruppe - Varioförderer 001- Winkel": "39", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 30°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 30°": "0", "Streckengruppe - Anzahl der Separatoren - Varioförderer": "2", "Gerüst für Einzelmodul": "Nein", "Gerüstoption für Einzelmodul": "Schönenberger-Gerüst"}
|
||||
12;"ILS 2.0 Strecke";"6220";"VF_2";20;1;;"0002";{"Anlagenhöhe in Meter": "0.5", "Streckengruppe": "mehrere Objekte", "Strecken- zu fertigende Menge": "1", "Streckengruppe - Gefällestrecke": "Ja", "Streckengruppe - Gefällestrecke 001-Länge in Meter": "0.042", "Streckengruppe - Gefällestrecke 001 -Winkel": "3", "Streckengruppe - Gefällestrecke 002": "Ja", "Streckengruppe - Gefällestrecke 002-Länge in Meter": "0.042", "Streckengruppe - Gefällestrecke 002- Winkel": "3", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 30°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 30°": "0", "Streckengruppe - Anzahl der Separatoren - Gefällestrecke": "0", "Streckengruppe - Bearbeitung Gefällestreckenteilstück für Separator (829516050)": "ohne HARTCOAT HRC 50 ± 5", "Streckengruppe - Anzahl der Scanner": "0", "Streckengruppe - Varioförderer": "Ja", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (links)": "0", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (rechts)": "1", "Streckengruppe - Varioförderer 001-Länge in Meter": "3.478", "Streckengruppe - Varioförderer 001-Richtung": "auf", "Streckengruppe - Varioförderer 001- Winkel": "21", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 30°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 30°": "0", "Streckengruppe - Anzahl der Separatoren - Varioförderer": "2", "Gerüst für Einzelmodul": "Nein", "Gerüstoption für Einzelmodul": "Schönenberger-Gerüst"}
|
||||
13;"ILS 2.0 Strecke";"6220";"VF_1";20;1;;"0001";{"Anlagenhöhe in Meter": "0", "Streckengruppe": "mehrere Objekte", "Strecken- zu fertigende Menge": "1", "Streckengruppe - Gefällestrecke": "Ja", "Streckengruppe - Gefällestrecke 001-Länge in Meter": "0.615", "Streckengruppe - Gefällestrecke 001 -Winkel": "3", "Streckengruppe - Gefällestrecke 002": "Ja", "Streckengruppe - Gefällestrecke 002-Länge in Meter": "0.615", "Streckengruppe - Gefällestrecke 002- Winkel": "3", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 30°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 30°": "0", "Streckengruppe - Anzahl der Separatoren - Gefällestrecke": "0", "Streckengruppe - Bearbeitung Gefällestreckenteilstück für Separator (829516050)": "ohne HARTCOAT HRC 50 ± 5", "Streckengruppe - Anzahl der Scanner": "0", "Streckengruppe - Varioförderer": "Ja", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (links)": "0", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (rechts)": "1", "Streckengruppe - Varioförderer 001-Länge in Meter": "2.74", "Streckengruppe - Varioförderer 001-Richtung": "auf", "Streckengruppe - Varioförderer 001- Winkel": "9", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 30°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 30°": "0", "Streckengruppe - Anzahl der Separatoren - Varioförderer": "2", "Gerüst für Einzelmodul": "Nein", "Gerüstoption für Einzelmodul": "Schönenberger-Gerüst"}
|
||||
14;"ILS 2.0 Automation und Pneumatik - Gesamtanlage";"6269";"";20;1;;"";{"Automation": "Ja", "Anzahl der Kreisel": "0", "Anzahl der Separatoren - Kreisel ohne PINBAND": "0", "Anzahl der Kreisel mit PINBAND": "0", "Anzahl der Separatoren - Kreisel mit PINBAND": "0", "Anzahl der Verbindungskreisel": "0", "Längen aller Kreisel": "0.00", "Anzahl der Weichen": "0", "Anzahl der Eckräder": "0", "Anzahl der einzelnen Gefällestrecken": "0", "Anzahl der einzelnen Vario-Förderer": "0", "Anzahl der Streckengruppen": "13", "Längen aller Gefällestrecken": "0.00", "Anzahl der Motoren in Vario - Förderer": "13", "Längen aller Vario - Förderer": "41.915000000000006", "Anzahl der ETFs": "0", "Längen aller ETFS und Zusatzstücke (Gefällestrecken)": "0.0", "Anzahl der Separatoren in der Anlage": "26", "Anzahl der Scanner in der Anlage": "0", "Zusatzmodul - Anzahl der BT-Beladung": "0", "Zusatzmodul - Anzahl der Abwurfstation": "0", "Pneumatik": "Ja"}
|
||||
1;"ILS 2.0 Strecke";"6220";"VF_13";20;1;;"0013";{"2950": "-1.5", "4431": "Ja", "4427": "90 °", "4428": "links", "4432": "Ja", "4429": "90 °", "4430": "links", "4329": "0", "4330": "0", "4331": "0", "4332": "0", "4333": "0", "4334": "0", "4373": "0", "4374": "0", "4375": "0", "4376": "0", "4377": "0", "4378": "0", "4381": "2", "4382": "ohne HARTCOAT HRC 50 ± 5", "4383": "0", "3992": "Nein", "3993": "Schönenberger-Gerüst", "4300": "mehrere Objekte", "4311": "1", "4312": "Ja", "4318": "0.0", "4391": "3", "4314": "Ja", "4319": "0.707", "4392": "3", "4337": "0", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "4340": "Ja", "4341": "0", "4342": "1", "4353": "3.055", "4354": "ab", "4386": "39", "4433": "-0.012", "4434": "0.488", "4435": "0.988", "4436": "1.488", "4437": "-0.512"}
|
||||
2;"ILS 2.0 Strecke";"6220";"VF_12";20;1;;"0012";{"2950": "0.5", "4431": "Ja", "4427": "90 °", "4428": "links", "4432": "Ja", "4429": "90 °", "4430": "links", "4329": "0", "4330": "0", "4331": "0", "4332": "0", "4333": "0", "4334": "0", "4373": "0", "4374": "0", "4375": "0", "4376": "0", "4377": "0", "4378": "0", "4381": "2", "4382": "ohne HARTCOAT HRC 50 ± 5", "4383": "0", "3992": "Nein", "3993": "Schönenberger-Gerüst", "4300": "mehrere Objekte", "4311": "1", "4312": "Ja", "4318": "0.084", "4391": "3", "4314": "Ja", "4319": "0.0", "4392": "3", "4337": "0", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "4340": "Ja", "4341": "0", "4342": "1", "4353": "3.478", "4354": "auf", "4386": "21", "4433": "-0.012", "4434": "0.488", "4435": "0.988", "4436": "1.488", "4437": "-0.512"}
|
||||
3;"ILS 2.0 Strecke";"6220";"VF_11";20;1;;"0011";{"2950": "1.5", "4431": "Ja", "4427": "90 °", "4428": "links", "4432": "Ja", "4429": "90 °", "4430": "links", "4329": "0", "4330": "0", "4331": "0", "4332": "0", "4333": "0", "4334": "0", "4373": "0", "4374": "0", "4375": "0", "4376": "0", "4377": "0", "4378": "0", "4381": "2", "4382": "ohne HARTCOAT HRC 50 ± 5", "4383": "0", "3992": "Nein", "3993": "Schönenberger-Gerüst", "4300": "mehrere Objekte", "4311": "1", "4312": "Ja", "4318": "0.166", "4391": "3", "4314": "Ja", "4319": "0.166", "4392": "3", "4337": "0", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "4340": "Ja", "4341": "0", "4342": "1", "4353": "3.207", "4354": "auf", "4386": "51", "4433": "-0.012", "4434": "0.488", "4435": "0.988", "4436": "1.488", "4437": "-0.512"}
|
||||
4;"ILS 2.0 Strecke";"6220";"VF_10";20;1;;"0010";{"2950": "-1", "4431": "Ja", "4427": "90 °", "4428": "links", "4432": "Ja", "4429": "90 °", "4430": "links", "4329": "0", "4330": "0", "4331": "0", "4332": "0", "4333": "0", "4334": "0", "4373": "0", "4374": "0", "4375": "0", "4376": "0", "4377": "0", "4378": "0", "4381": "2", "4382": "ohne HARTCOAT HRC 50 ± 5", "4383": "0", "3992": "Nein", "3993": "Schönenberger-Gerüst", "4300": "mehrere Objekte", "4311": "1", "4312": "Ja", "4318": "0.541", "4391": "3", "4314": "Ja", "4319": "0.541", "4392": "3", "4337": "0", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "4340": "Ja", "4341": "0", "4342": "1", "4353": "2.731", "4354": "ab", "4386": "27", "4433": "-0.012", "4434": "0.488", "4435": "0.988", "4436": "1.488", "4437": "-0.512"}
|
||||
5;"ILS 2.0 Strecke";"6220";"VF_9";20;1;;"0009";{"2950": "1", "4431": "Ja", "4427": "90 °", "4428": "rechts", "4432": "Ja", "4429": "90 °", "4430": "rechts", "4329": "0", "4330": "0", "4331": "0", "4332": "0", "4333": "0", "4334": "0", "4373": "0", "4374": "0", "4375": "0", "4376": "0", "4377": "0", "4378": "0", "4381": "2", "4382": "ohne HARTCOAT HRC 50 ± 5", "4383": "0", "3992": "Nein", "3993": "Schönenberger-Gerüst", "4300": "mehrere Objekte", "4311": "1", "4312": "Ja", "4318": "0.206", "4391": "3", "4314": "Ja", "4319": "0.206", "4392": "3", "4337": "0", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "4340": "Ja", "4341": "0", "4342": "1", "4353": "3.07", "4354": "auf", "4386": "39", "4433": "-0.012", "4434": "0.488", "4435": "0.988", "4436": "1.488", "4437": "-0.512"}
|
||||
6;"ILS 2.0 Strecke";"6220";"VF_8";20;1;;"0008";{"2950": "-2", "4431": "Ja", "4427": "90 °", "4428": "links", "4432": "Ja", "4429": "90 °", "4430": "links", "4329": "0", "4330": "0", "4331": "0", "4332": "0", "4333": "0", "4334": "0", "4373": "0", "4374": "0", "4375": "0", "4376": "0", "4377": "0", "4378": "0", "4381": "2", "4382": "ohne HARTCOAT HRC 50 ± 5", "4383": "0", "3992": "Nein", "3993": "Schönenberger-Gerüst", "4300": "mehrere Objekte", "4311": "1", "4312": "Ja", "4318": "0.15", "4391": "3", "4314": "Ja", "4319": "0.15", "4392": "3", "4337": "0", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "4340": "Ja", "4341": "0", "4342": "1", "4353": "4.067", "4354": "ab", "4386": "45", "4433": "-0.012", "4434": "0.488", "4435": "0.988", "4436": "1.488", "4437": "-0.512"}
|
||||
7;"ILS 2.0 Strecke";"6220";"VF_7";20;1;;"0007";{"2950": "-1.5", "4431": "Ja", "4427": "90 °", "4428": "links", "4432": "Ja", "4429": "90 °", "4430": "links", "4329": "0", "4330": "0", "4331": "0", "4332": "0", "4333": "0", "4334": "0", "4373": "0", "4374": "0", "4375": "0", "4376": "0", "4377": "0", "4378": "0", "4381": "2", "4382": "ohne HARTCOAT HRC 50 ± 5", "4383": "0", "3992": "Nein", "3993": "Schönenberger-Gerüst", "4300": "mehrere Objekte", "4311": "1", "4312": "Ja", "4318": "0.354", "4391": "3", "4314": "Ja", "4319": "0.354", "4392": "3", "4337": "0", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "4340": "Ja", "4341": "0", "4342": "1", "4353": "3.055", "4354": "ab", "4386": "39", "4433": "-0.012", "4434": "0.488", "4435": "0.988", "4436": "1.488", "4437": "-0.512"}
|
||||
8;"ILS 2.0 Strecke";"6220";"VF_6";20;1;;"0006";{"2950": "-1", "4431": "Ja", "4427": "90 °", "4428": "links", "4432": "Ja", "4429": "90 °", "4430": "links", "4329": "0", "4330": "0", "4331": "0", "4332": "0", "4333": "0", "4334": "0", "4373": "0", "4374": "0", "4375": "0", "4376": "0", "4377": "0", "4378": "0", "4381": "2", "4382": "ohne HARTCOAT HRC 50 ± 5", "4383": "0", "3992": "Nein", "3993": "Schönenberger-Gerüst", "4300": "mehrere Objekte", "4311": "1", "4312": "Ja", "4318": "0.013", "4391": "3", "4314": "Ja", "4319": "0.013", "4392": "3", "4337": "0", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "4340": "Ja", "4341": "0", "4342": "1", "4353": "3.701", "4354": "ab", "4386": "21", "4433": "-0.012", "4434": "0.488", "4435": "0.988", "4436": "1.488", "4437": "-0.512"}
|
||||
9;"ILS 2.0 Strecke";"6220";"VF_5";20;1;;"0005";{"2950": "-0.5", "4431": "Ja", "4427": "90 °", "4428": "links", "4432": "Ja", "4429": "90 °", "4430": "links", "4329": "0", "4330": "0", "4331": "0", "4332": "0", "4333": "0", "4334": "0", "4373": "0", "4374": "0", "4375": "0", "4376": "0", "4377": "0", "4378": "0", "4381": "2", "4382": "ohne HARTCOAT HRC 50 ± 5", "4383": "0", "3992": "Nein", "3993": "Schönenberger-Gerüst", "4300": "mehrere Objekte", "4311": "1", "4312": "Ja", "4318": "0.486", "4391": "3", "4314": "Ja", "4319": "0.486", "4392": "3", "4337": "0", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "4340": "Ja", "4341": "0", "4342": "1", "4353": "3.056", "4354": "ab", "4386": "9", "4433": "-0.012", "4434": "0.488", "4435": "0.988", "4436": "1.488", "4437": "-0.512"}
|
||||
10;"ILS 2.0 Strecke";"6220";"VF_4";20;1;;"0004";{"2950": "1.5", "4431": "Ja", "4427": "90 °", "4428": "links", "4432": "Ja", "4429": "90 °", "4430": "links", "4329": "0", "4330": "0", "4331": "0", "4332": "0", "4333": "0", "4334": "0", "4373": "0", "4374": "0", "4375": "0", "4376": "0", "4377": "0", "4378": "0", "4381": "2", "4382": "ohne HARTCOAT HRC 50 ± 5", "4383": "0", "3992": "Nein", "3993": "Schönenberger-Gerüst", "4300": "mehrere Objekte", "4311": "1", "4312": "Ja", "4318": "0.166", "4391": "3", "4314": "Ja", "4319": "0.166", "4392": "3", "4337": "0", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "4340": "Ja", "4341": "0", "4342": "1", "4353": "3.207", "4354": "auf", "4386": "51", "4433": "-0.012", "4434": "0.488", "4435": "0.988", "4436": "1.488"}
|
||||
11;"ILS 2.0 Strecke";"6220";"VF_3";20;1;;"0003";{"2950": "1", "4431": "Ja", "4427": "90 °", "4428": "links", "4432": "Ja", "4429": "90 °", "4430": "links", "4329": "0", "4330": "0", "4331": "0", "4332": "0", "4333": "0", "4334": "0", "4373": "0", "4374": "0", "4375": "0", "4376": "0", "4377": "0", "4378": "0", "4381": "2", "4382": "ohne HARTCOAT HRC 50 ± 5", "4383": "0", "3992": "Nein", "3993": "Schönenberger-Gerüst", "4300": "mehrere Objekte", "4311": "1", "4312": "Ja", "4318": "0.206", "4391": "3", "4314": "Ja", "4319": "0.206", "4392": "3", "4337": "0", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "4340": "Ja", "4341": "0", "4342": "1", "4353": "3.07", "4354": "auf", "4386": "39", "4433": "-0.012", "4434": "0.488", "4435": "0.988"}
|
||||
12;"ILS 2.0 Strecke";"6220";"VF_2";20;1;;"0002";{"2950": "0.5", "4431": "Ja", "4427": "90 °", "4428": "links", "4432": "Ja", "4429": "90 °", "4430": "links", "4329": "0", "4330": "0", "4331": "0", "4332": "0", "4333": "0", "4334": "0", "4373": "0", "4374": "0", "4375": "0", "4376": "0", "4377": "0", "4378": "0", "4381": "2", "4382": "ohne HARTCOAT HRC 50 ± 5", "4383": "0", "3992": "Nein", "3993": "Schönenberger-Gerüst", "4300": "mehrere Objekte", "4311": "1", "4312": "Ja", "4318": "0.042", "4391": "3", "4314": "Ja", "4319": "0.042", "4392": "3", "4337": "0", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "4340": "Ja", "4341": "0", "4342": "1", "4353": "3.478", "4354": "auf", "4386": "21", "4433": "-0.012", "4434": "0.488"}
|
||||
13;"ILS 2.0 Strecke";"6220";"VF_1";20;1;;"0001";{"2950": "0", "4431": "Ja", "4427": "90 °", "4428": "links", "4432": "Ja", "4429": "90 °", "4430": "links", "4329": "0", "4330": "0", "4331": "0", "4332": "0", "4333": "0", "4334": "0", "4373": "0", "4374": "0", "4375": "0", "4376": "0", "4377": "0", "4378": "0", "4381": "2", "4382": "ohne HARTCOAT HRC 50 ± 5", "4383": "0", "3992": "Nein", "3993": "Schönenberger-Gerüst", "4300": "mehrere Objekte", "4311": "1", "4312": "Ja", "4318": "0.615", "4391": "3", "4314": "Ja", "4319": "0.615", "4392": "3", "4337": "0", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "4340": "Ja", "4341": "0", "4342": "1", "4353": "2.74", "4354": "auf", "4386": "9", "4433": "-0.012"}
|
||||
14;"ILS 2.0 Automation und Pneumatik - Gesamtanlage";"6269";"";20;1;;"";{"4000": "Ja", "4400": "0", "4413": "0", "4401": "0", "4414": "0", "4402": "0", "4419": "0.00", "4403": "0", "4404": "0", "4425": "0", "4426": "0", "4407": "13", "4418": "0.00", "4408": "13", "4420": "41.915000000000006", "4409": "0", "4417": "0.0", "4410": "26", "4411": "0", "4421": "0", "4422": "0", "4100": "Ja"}
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 50.
|
@@ -1,6 +1,6 @@
|
||||
Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];IDs;details
|
||||
1;"ILS 2.0 Gefaellestrecke";"6220";"GF_8";20;1;;"0008";{"Anlagenhöhe in Meter": "5", "Streckengruppe": "ein Objekt", "Gefällestrecke oder Vario-Förderer": "Gefällestrecke", "Strecken- zu fertigende Menge": "1", "Streckengruppe - Gefällestrecke 001-Länge in Meter": "9.261", "Streckengruppe - Gefällestrecke 001 -Winkel": "3", "Streckengruppe - Anzahl der Separatoren - Gefällestrecke": "1", "Streckengruppe - Bearbeitung Gefällestreckenteilstück für Separator (829516050)": "ohne HARTCOAT HRC 50 ± 5", "Streckengruppe - Anzahl der Scanner": "0", "Gerüst für Einzelmodul": "Nein", "Gerüstoption für Einzelmodul": "Schönenberger-Gerüst"}
|
||||
2;"ILS 2.0 Gefaellestrecke";"6220";"GF_7";20;1;;"0007";{"Anlagenhöhe in Meter": "2", "Streckengruppe": "mehrere Objekte", "Gefällestrecke oder Vario-Förderer": "Gefällestrecke", "Strecken- zu fertigende Menge": "1", "Streckengruppe - Gefällestrecke 001-Länge in Meter": "7.274,5.264", "Streckengruppe - Gefällestrecke 001 -Winkel": "0.2,0.2", "Streckengruppe - Anzahl der Separatoren - Gefällestrecke": "2", "Streckengruppe - Bearbeitung Gefällestreckenteilstück für Separator (829516050)": "ohne HARTCOAT HRC 50 ± 5", "Streckengruppe - Anzahl der Scanner": "0", "Gerüst für Einzelmodul": "Nein", "Gerüstoption für Einzelmodul": "Schönenberger-Gerüst"}
|
||||
3;"ILS 2.0 Gefaellestrecke";"6220";"GF_6";20;1;;"0006";{"Anlagenhöhe in Meter": "5", "Streckengruppe": "ein Objekt", "Gefällestrecke oder Vario-Förderer": "Gefällestrecke", "Strecken- zu fertigende Menge": "1", "Streckengruppe - Gefällestrecke 001-Länge in Meter": "8.838", "Streckengruppe - Gefällestrecke 001 -Winkel": "2.8", "Streckengruppe - Anzahl der Separatoren - Gefällestrecke": "1", "Streckengruppe - Bearbeitung Gefällestreckenteilstück für Separator (829516050)": "ohne HARTCOAT HRC 50 ± 5", "Streckengruppe - Anzahl der Scanner": "0", "Gerüst für Einzelmodul": "Nein", "Gerüstoption für Einzelmodul": "Schönenberger-Gerüst"}
|
||||
4;"ILS 2.0 Gefaellestrecke";"6220";"GF_5, GF_4, GF_3, GF_2, GF_1";20;1;;"0005, 0004, 0003, 0002, 0001";{"Anlagenhöhe in Meter": "5", "Streckengruppe": "ein Objekt", "Gefällestrecke oder Vario-Förderer": "Gefällestrecke", "Strecken- zu fertigende Menge": "5", "Streckengruppe - Gefällestrecke 001-Länge in Meter": "8.851", "Streckengruppe - Gefällestrecke 001 -Winkel": "3", "Streckengruppe - Anzahl der Separatoren - Gefällestrecke": "1", "Streckengruppe - Bearbeitung Gefällestreckenteilstück für Separator (829516050)": "ohne HARTCOAT HRC 50 ± 5", "Streckengruppe - Anzahl der Scanner": "0", "Gerüst für Einzelmodul": "Nein", "Gerüstoption für Einzelmodul": "Schönenberger-Gerüst"}
|
||||
5;"ILS 2.0 Automation und Pneumatik - Gesamtanlage";"6269";"";20;1;;"";{"Automation": "Ja", "Anzahl der Kreisel": "0", "Anzahl der Separatoren - Kreisel ohne PINBAND": "0", "Anzahl der Kreisel mit PINBAND": "0", "Anzahl der Separatoren - Kreisel mit PINBAND": "0", "Anzahl der Verbindungskreisel": "0", "Längen aller Kreisel": "0.00", "Anzahl der Weichen": "0", "Anzahl der Eckräder": "0", "Anzahl der einzelnen Gefällestrecken": "8", "Anzahl der einzelnen Vario-Förderer": "0", "Anzahl der Streckengruppen": "0", "Längen aller Gefällestrecken": "62.35", "Anzahl der Motoren in Vario - Förderer": "0", "Längen aller Vario - Förderer": "0.0", "Anzahl der ETFs": "0", "Längen aller ETFS und Zusatzstücke (Gefällestrecken)": "0.0", "Anzahl der Separatoren in der Anlage": "9", "Anzahl der Scanner in der Anlage": "0", "Zusatzmodul - Anzahl der BT-Beladung": "0", "Zusatzmodul - Anzahl der Abwurfstation": "0", "Pneumatik": "Ja"}
|
||||
1;"ILS 2.0 Gefaellestrecke";"6220";"GF_8";20;1;;"0008";{"2950": "5", "4431": "Ja", "4427": "30 °", "4428": "links", "4432": "Ja", "4429": "30 °", "4430": "links", "4384": "Gefällestrecke", "4318": "9.261", "4391": "3", "4337": "1", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "3992": "Nein", "3993": "Schönenberger-Gerüst", "4300": "ein Objekt", "4311": "1"}
|
||||
2;"ILS 2.0 Gefaellestrecke";"6220";"GF_7";20;1;;"0007";{"2950": "2", "4431": "Ja", "4427": "90 °", "4428": "links", "4432": "Ja", "4429": "90 °", "4430": "links", "4384": "Gefällestrecke", "4318": "7.274,5.264", "4391": "0.2,0.2", "4337": "2", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "3992": "Nein", "3993": "Schönenberger-Gerüst", "4300": "mehrere Objekte", "4311": "1"}
|
||||
3;"ILS 2.0 Gefaellestrecke";"6220";"GF_6";20;1;;"0006";{"2950": "5", "4431": "Ja", "4427": "90 °", "4428": "links", "4432": "Ja", "4429": "90 °", "4430": "links", "4384": "Gefällestrecke", "4318": "8.838", "4391": "2.8", "4337": "1", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "3992": "Nein", "3993": "Schönenberger-Gerüst", "4300": "ein Objekt", "4311": "1"}
|
||||
4;"ILS 2.0 Gefaellestrecke";"6220";"GF_5, GF_4, GF_3, GF_2, GF_1";20;1;;"0005, 0004, 0003, 0002, 0001";{"2950": "5", "4431": "Ja", "4427": "90 °", "4428": "links", "4432": "Ja", "4429": "90 °", "4430": "links", "4384": "Gefällestrecke", "4318": "8.851", "4391": "3", "4337": "1", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "3992": "Nein", "3993": "Schönenberger-Gerüst", "4300": "ein Objekt", "4311": "5"}
|
||||
5;"ILS 2.0 Automation und Pneumatik - Gesamtanlage";"6269";"";20;1;;"";{"4000": "Ja", "4400": "0", "4413": "0", "4401": "0", "4414": "0", "4402": "0", "4419": "0.00", "4403": "0", "4404": "0", "4425": "8", "4426": "0", "4407": "0", "4418": "62.35", "4408": "0", "4420": "0.0", "4409": "0", "4417": "0.0", "4410": "9", "4411": "0", "4421": "0", "4422": "0", "4100": "Ja"}
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 57.
|
@@ -5,20 +5,20 @@ Elementnummer;TeileArt;TeileId;Bezeichnung;Planquadrat;Anzahl;Position;Boundingb
|
||||
4;"ILS 2.0 Strecke";"0004";"VF_4";"H/1-J/4";1;"18465.07, 4300.26, 2119.66";"2518.90, 6404.92, 848.78";"f///EdR0IN4QAAAAAAAAAAAA";"AqAYAC2kAFQk";"AwJzAC2kAFQk";"";"";"0006-L";"0038, 0039, 0040, 0041";"nur ein Partner";"";{"Typ": "Streckengruppe", "Seite_AS": "links", "Seite_ES": "links", "Winkel": "3,3", "VF_Winkel": "0,0,18", "DeltaH_mm": "0", "DeltaL_mm": "1907", "L_VF_m": "0.269,0.458,1.663", "L_GF_m": "4.166,1.658", "Montagehoehe_m": "2.154", "Hoehe_Von_mm": "2154", "Hoehe_Bis_mm": "2154", "Antriebfahrtrichtung": "horizontal,horizontal,Auf", "Anzahl_Separator": "2", "Anzahl_Scanner": "0"}
|
||||
5;"ILS 2.0 Strecke";"0005";"VF_5";"J/1-K/4";1;"22239.27, 4299.16, 2119.66";"2518.90, 6404.92, 848.78";"f///EdAoIN4QAAAAAAAAAAAA";"AzOGAC2ZAFQk";"A5XhAC2ZAFQk";"";"";"0006-L";"0042, 0043, 0044, 0045";"nur ein Partner";"";{"Typ": "Streckengruppe", "Seite_AS": "links", "Seite_ES": "links", "Winkel": "3,3", "VF_Winkel": "0,0,18", "DeltaH_mm": "0", "DeltaL_mm": "1907", "L_VF_m": "0.269,0.458,1.663", "L_GF_m": "4.166,1.658", "Montagehoehe_m": "2.154", "Hoehe_Von_mm": "2154", "Hoehe_Bis_mm": "2154", "Antriebfahrtrichtung": "horizontal,horizontal,Auf", "Anzahl_Separator": "4", "Anzahl_Scanner": "1"}
|
||||
6;"ILS 2.0 Kreisel";"0006";"Kreisel1";"A/1-M/1";1;"13594.00, 767.00, 2154.00";"24100.00, 800.00, 1.00";"F49AC7QYIN4QAAAAAAAAAAAA";"";"";"";"";"0005, 0004, 0003, 0002, 0001";"0021, 0022, 0007, 0008, 0024, 0029, 0010, 0030, 0033, 0012, 0034, 0037, 0014, 0038, 0041, 0016, 0042, 0045, 0018, 0020, 0023";"";"";{"Abstand (Kreiselachse A - Kreiselachse) in Meter": "23.3", "Anzahl der Separatoren": "4", "Kreiselart": "STANDARD", "Anzahl der Scanner": "4", "Anzahl der Rampen": "0", "Höhe in m": "2.15", "Drehrichtung": "UZS", "Drehung": 0, "Name": "Kreisel1", "Geruest fuer Einzelmodul": true}
|
||||
7;"ILS 2.0 Separator";"0007";"Separator :20";"A/1";1;"2414.95, 365.00, 2155.50";"209.90, 150.00, 3.00";"I+84BZHIIN4QAAAAAAAAAAAA";"AFv+AA5CAFQk";"";"";"";"0022, 0008";"";"";"";{"Zuordnung": "0006-R", "ARTINR": "200000077", "Höhe": "2154", "Drehung": 0, "Typ": ""}
|
||||
7;"ILS 2.0 Separator";"0007";"Separator :20";"A/1";1;"2414.95, 365.00, 2155.50";"209.90, 150.00, 3.00";"I+84BZHIIN4QAAAAAAAAAAAA";"AFv+AA5CAFQk";"";"";"";"0022, 0008";"";"";"";{"Zuordnung": "0001", "ARTINR": "200000077", "Höhe": "2154", "Drehung": 0, "Typ": ""}
|
||||
8;"ILS 2.0 Separator";"0008";"Separator :19";"B/1";1;"4056.38, 1165.90, 2155.50";"209.90, 150.00, 3.00";"Ps9qEcpMIN4QAAAAAAAAf///";"AKDLAC2LAFQk";"";"";"";"0007, 0024";"";"";"";{"Zuordnung": "0006-L", "ARTINR": "200000077", "Höhe": "2154", "Drehung": 180, "Typ": ""}
|
||||
9;"ILS 2.0 Scanner";"0009";"Scanner :6";"B/1";1;"4095.50, 804.10, 2154.00";"150.00, 280.00, 1.00";"Pn4MEcNEIN4QAAAAAAAApX2I";"";"";"";"";"";"";"";"";{"Zuordnung": "0006-L", "ARTINR": "829534306", "Höhe": "2154", "Drehung": 270, "Typ": "", "Naechster Separator": "0008"}
|
||||
10;"ILS 2.0 Separator";"0010";"Separator :18";"D/1";1;"8555.49, 1169.50, 2155.50";"209.90, 150.00, 3.00";"f///EdhcIN4QAAAAAAAAf///";"AVCKAC2vAFQk";"";"";"";"0029, 0030";"";"";"";{"Zuordnung": "0006-L", "ARTINR": "200000077", "Höhe": "2154", "Drehung": 180, "Typ": ""}
|
||||
11;"ILS 2.0 Scanner";"0011";"Scanner :5";"D/1";1;"8598.69, 807.70, 2154.00";"150.00, 280.00, 1.00";"f///EdFUIN4QAAAAAAAApX2I";"";"";"";"";"";"";"";"";{"Zuordnung": "0006-L", "ARTINR": "829534306", "Höhe": "2154", "Drehung": 270, "Typ": "", "Naechster Separator": "0010"}
|
||||
10;"ILS 2.0 Separator";"0010";"Separator :18";"D/1";1;"8555.49, 1169.50, 2155.50";"209.90, 150.00, 3.00";"f///EdhcIN4QAAAAAAAAf///";"AVCKAC2vAFQk";"";"";"";"0029, 0030";"";"";"";{"Zuordnung": "0002", "ARTINR": "200000077", "Höhe": "2154", "Drehung": 180, "Typ": ""}
|
||||
11;"ILS 2.0 Scanner";"0011";"Scanner :5";"D/1";1;"8598.69, 807.70, 2154.00";"150.00, 280.00, 1.00";"f///EdFUIN4QAAAAAAAApX2I";"";"";"";"";"";"";"";"";{"Zuordnung": "0002", "ARTINR": "829534306", "Höhe": "2154", "Drehung": 270, "Typ": "", "Naechster Separator": "0010"}
|
||||
12;"ILS 2.0 Separator";"0012";"Separator :17";"F/1";1;"12631.71, 1168.20, 2155.50";"209.90, 150.00, 3.00";"f///EdNIIN4QAAAAAAAAf///";"Ae/EAC2iAFQk";"";"";"";"0033, 0034";"";"";"";{"Zuordnung": "0006-L", "ARTINR": "200000077", "Höhe": "2154", "Drehung": 180, "Typ": ""}
|
||||
13;"ILS 2.0 Scanner";"0013";"Scanner :4";"F/1";1;"12669.10, 806.40, 2154.00";"150.00, 280.00, 1.00";"f///EcxAIN4QAAAAAAAApX2I";"";"";"";"";"";"";"";"";{"Zuordnung": "0006-L", "ARTINR": "829534306", "Höhe": "2154", "Drehung": 270, "Typ": "", "Naechster Separator": "0012"}
|
||||
14;"ILS 2.0 Separator";"0014";"Separator :16";"H/1";1;"16799.72, 1171.70, 2155.50";"209.90, 150.00, 3.00";"f///EeD0IN4QAAAAAAAAf///";"ApKUAC3FAFQk";"";"";"";"0037, 0038";"";"";"";{"Zuordnung": "0006-L", "ARTINR": "200000077", "Höhe": "2154", "Drehung": 180, "Typ": ""}
|
||||
15;"ILS 2.0 Scanner";"0015";"Scanner :3";"H/1";1;"16839.52, 809.80, 2154.00";"150.00, 280.00, 1.00";"f///EdmIIN4QAAAAAAAApX2I";"";"";"";"";"";"";"";"Distanz-Zuordnung unsicher: 0006 (3270mm) vs. 0004 (3527mm)";{"Zuordnung": "0006-L", "ARTINR": "829534306", "Höhe": "2154", "Drehung": 270, "Typ": "", "Naechster Separator": "0014"}
|
||||
16;"ILS 2.0 Separator";"0016";"Separator :15";"J/1";1;"20577.16, 1166.20, 2155.50";"209.90, 150.00, 3.00";"f///Ect4IN4QAAAAAAAAf///";"AyYjAC2OAFQk";"";"";"";"0041, 0042";"";"";"";{"Zuordnung": "0006-L", "ARTINR": "200000077", "Höhe": "2154", "Drehung": 180, "Typ": ""}
|
||||
17;"ILS 2.0 Scanner";"0017";"Scanner :2";"J/1";1;"20807.70, 804.30, 2154.00";"150.00, 280.00, 1.00";"f///EcQMIN4QAAAAAAAApX2I";"";"";"";"";"";"";"";"";{"Zuordnung": "0005", "ARTINR": "829534306", "Höhe": "2154", "Drehung": 270, "Typ": "", "Naechster Separator": "0016"}
|
||||
17;"ILS 2.0 Scanner";"0017";"Scanner :2";"J/1";1;"20807.70, 804.30, 2154.00";"150.00, 280.00, 1.00";"f///EcQMIN4QAAAAAAAApX2I";"";"";"";"";"";"";"";"";{"Zuordnung": "0006-L", "ARTINR": "829534306", "Höhe": "2154", "Drehung": 270, "Typ": "", "Naechster Separator": "0016"}
|
||||
18;"ILS 2.0 Separator";"0018";"Separator :14";"L/1";1;"23678.05, 1170.60, 2155.50";"209.90, 150.00, 3.00";"f///EdyoIN4QAAAAAAAAf///";"A59EAC26AFQk";"";"";"";"0045, 0020";"";"";"";{"Zuordnung": "0005", "ARTINR": "200000077", "Höhe": "2154", "Drehung": 180, "Typ": ""}
|
||||
19;"ILS 2.0 Scanner";"0019";"Scanner :1";"L/1";1;"23780.80, 808.80, 2154.00";"150.00, 280.00, 1.00";"f///EdWgIN4QAAAAAAAApX2I";"";"";"";"";"";"";"";"";{"Zuordnung": "0006-L", "ARTINR": "829534306", "Höhe": "2154", "Drehung": 270, "Typ": "", "Naechster Separator": "0018"}
|
||||
20;"ILS 2.0 Separator";"0020";"Separator :13";"L/1";1;"24570.15, 1167.20, 2155.50";"209.90, 150.00, 3.00";"f///Ec9gIN4QAAAAAAAAf///";"A8IdAC2YAFQk";"";"";"";"0018, 0023";"";"";"";{"Zuordnung": "0006-L", "ARTINR": "200000077", "Höhe": "2154", "Drehung": 180, "Typ": ""}
|
||||
19;"ILS 2.0 Scanner";"0019";"Scanner :1";"L/1";1;"23780.80, 808.80, 2154.00";"150.00, 280.00, 1.00";"f///EdWgIN4QAAAAAAAApX2I";"";"";"";"";"";"";"";"";{"Zuordnung": "0005", "ARTINR": "829534306", "Höhe": "2154", "Drehung": 270, "Typ": "", "Naechster Separator": "0018"}
|
||||
20;"ILS 2.0 Separator";"0020";"Separator :13";"L/1";1;"24570.15, 1167.20, 2155.50";"209.90, 150.00, 3.00";"f///Ec9gIN4QAAAAAAAAf///";"A8IdAC2YAFQk";"";"";"";"0018, 0023";"";"";"";{"Zuordnung": "0005", "ARTINR": "200000077", "Höhe": "2154", "Drehung": 180, "Typ": ""}
|
||||
21;"ILS 2.0 BTMT Beladung";"0021";"BTMT Beladung :2";"B/1-C/1";1;"5532.67, 265.14, 2109.31";"652.35, 408.38, 316.02";"ULuUBaYYIN4QAAAAAAAAf/7S";"AON9AANLAFSv";"AMu/AA6CAFQk";"";"";"0023, 0022";"";"";"";{"ARTINR": "829662012", "Höhe": "2154", "Drehung": 179}
|
||||
22;"ILS 2.0 BTMT Beladung";"0022";"BTMT Beladung :1";"B/1";1;"4503.25, 269.77, 2109.31";"651.33, 406.70, 316.02";"QQVQBbW4IN4QAAAAAAAAf/8o";"ALtMAAOBAFSv";"AKOGAA6oAFQk";"";"";"0021, 0007";"";"";"";{"ARTINR": "829662012", "Höhe": "2154", "Drehung": 179}
|
||||
23;"ILS 2.0 BTMT Entladung";"0023";"BTMT Entladung :1";"L/1-M/1";1;"25014.37, 1545.51, 2001.09";"1475.51, 961.98, 467.01";"f///Edt8IN4QAAAAAAAAARVf";"A7q4AC1/AFQk";"A+0BAE7eAEX5";"";"";"0020, 0021";"";"";"";{"ARTINR": "400100156", "Höhe": "2154", "Drehung": 1}
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 233.
|
@@ -1,9 +1,9 @@
|
||||
Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];IDs;details
|
||||
1;"ILS 2.0 Kreisel";"6200";"Kreisel12";20;1;;"0006";{"2952": "2.154", "3510": "Kreisel", "3511": "1", "3512": "23.3", "3515": "4", "3517": "4", "3519": "0", "3992": "Ja", "3993": "Schönenberger-Gerüst"}
|
||||
1;"ILS 2.0 Kreisel";"6200";"Kreisel1";20;1;;"0006";{"2952": "2.154", "3511": "1", "3515": "4", "3517": "4", "3519": "0", "3992": "Ja", "3993": "Schönenberger-Gerüst", "3510": "Kreisel", "3512": "23.3"}
|
||||
2;"ILS 2.0 Zusatzmodul";"6215";"";20;1;;"0022, 0021, 0023";{"3501": "Ja", "3503": "2", "3502": "Ja", "3504": "1"}
|
||||
3;"ILS 2.0 Strecke";"6220";"VF_9";20;1;;"0005";{"2950": "2.154", "4300": "mehrere Objekte", "4311": "1", "4312": "Ja", "4318": "4.166", "4391": "3", "4314": "Ja", "4319": "1.658", "4392": "3", "4329": "0", "4330": "0", "4331": "0", "4332": "0", "4333": "0", "4334": "0", "4337": "0", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "4340": "Ja", "4341": "0", "4342": "1", "4353": "0.269", "4354": "horizontal", "4386": "0", "4373": "0", "4374": "0", "4375": "0", "4376": "2", "4377": "0", "4378": "0", "4381": "4", "4382": "ohne HARTCOAT HRC 50 ± 5", "4383": "1", "3992": "Ja", "3993": "Schönenberger-Gerüst"}
|
||||
4;"ILS 2.0 Strecke";"6220";"VF_8";20;1;;"0004";{"2950": "2.154", "4300": "mehrere Objekte", "4311": "1", "4312": "Ja", "4318": "4.166", "4391": "3", "4314": "Ja", "4319": "1.658", "4392": "3", "4329": "0", "4330": "0", "4331": "0", "4332": "0", "4333": "0", "4334": "0", "4337": "0", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "4340": "Ja", "4341": "0", "4342": "1", "4353": "0.269", "4354": "horizontal", "4386": "0", "4373": "0", "4374": "0", "4375": "0", "4376": "2", "4377": "0", "4378": "0", "4381": "2", "4382": "ohne HARTCOAT HRC 50 ± 5", "4383": "0", "3992": "Ja", "3993": "Schönenberger-Gerüst"}
|
||||
5;"ILS 2.0 Strecke";"6220";"VF_7";20;1;;"0003";{"2950": "2.154", "4300": "mehrere Objekte", "4311": "1", "4312": "Ja", "4318": "4.166", "4391": "3", "4314": "Ja", "4319": "1.658", "4392": "3", "4329": "0", "4330": "0", "4331": "0", "4332": "0", "4333": "0", "4334": "0", "4337": "0", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "4340": "Ja", "4341": "0", "4342": "1", "4353": "0.269", "4354": "horizontal", "4386": "0", "4373": "0", "4374": "0", "4375": "0", "4376": "2", "4377": "0", "4378": "0", "4381": "2", "4382": "ohne HARTCOAT HRC 50 ± 5", "4383": "0", "3992": "Ja", "3993": "Schönenberger-Gerüst"}
|
||||
6;"ILS 2.0 Strecke";"6220";"VF_6";20;1;;"0002";{"2950": "2.154", "4300": "mehrere Objekte", "4311": "1", "4312": "Ja", "4318": "4.166", "4391": "3", "4314": "Ja", "4319": "1.658", "4392": "3", "4329": "0", "4330": "0", "4331": "0", "4332": "0", "4333": "0", "4334": "0", "4337": "0", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "4340": "Ja", "4341": "0", "4342": "1", "4353": "0.269", "4354": "horizontal", "4386": "0", "4373": "0", "4374": "0", "4375": "0", "4376": "2", "4377": "0", "4378": "0", "4381": "3", "4382": "ohne HARTCOAT HRC 50 ± 5", "4383": "1", "3992": "Ja", "3993": "Schönenberger-Gerüst"}
|
||||
7;"ILS 2.0 Strecke";"6220";"VF_5";20;1;;"0001";{"2950": "2.154", "4300": "mehrere Objekte", "4311": "1", "4312": "Ja", "4318": "0.727", "4391": "3", "4314": "Ja", "4319": "0.201", "4392": "3", "4329": "0", "4330": "0", "4331": "0", "4332": "0", "4333": "0", "4334": "0", "4337": "0", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "4340": "Ja", "4341": "0", "4342": "2", "4353": "3.704", "4354": "horizontal", "4386": "0", "4373": "0", "4374": "0", "4375": "1", "4376": "2", "4377": "0", "4378": "1", "4381": "5", "4382": "ohne HARTCOAT HRC 50 ± 5", "4383": "0", "3992": "Ja", "3993": "Schönenberger-Gerüst"}
|
||||
3;"ILS 2.0 Strecke";"6220";"VF_5";20;1;;"0005";{"2950": "2.154", "4431": "Ja", "4427": "90 °", "4428": "links", "4432": "Ja", "4429": "90 °", "4430": "links", "4329": "0", "4330": "0", "4331": "0", "4332": "0", "4333": "0", "4334": "0", "4373": "0", "4374": "0", "4375": "0", "4376": "2", "4377": "0", "4378": "0", "4381": "4", "4382": "ohne HARTCOAT HRC 50 ± 5", "4383": "1", "3992": "Ja", "3993": "Schönenberger-Gerüst", "4300": "mehrere Objekte", "4311": "1", "4312": "Ja", "4318": "4.166", "4391": "3", "4314": "Ja", "4319": "1.658", "4392": "3", "4337": "0", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "4340": "Ja", "4341": "0", "4342": "1", "4353": "0.269", "4354": "horizontal", "4386": "0", "4433": "1.800", "4434": "1.800", "4435": "2.071"}
|
||||
4;"ILS 2.0 Strecke";"6220";"VF_4";20;1;;"0004";{"2950": "2.154", "4431": "Ja", "4427": "90 °", "4428": "links", "4432": "Ja", "4429": "90 °", "4430": "links", "4329": "0", "4330": "0", "4331": "0", "4332": "0", "4333": "0", "4334": "0", "4373": "0", "4374": "0", "4375": "0", "4376": "2", "4377": "0", "4378": "0", "4381": "2", "4382": "ohne HARTCOAT HRC 50 ± 5", "4383": "0", "3992": "Ja", "3993": "Schönenberger-Gerüst", "4300": "mehrere Objekte", "4311": "1", "4312": "Ja", "4318": "4.166", "4391": "3", "4314": "Ja", "4319": "1.658", "4392": "3", "4337": "0", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "4340": "Ja", "4341": "0", "4342": "1", "4353": "0.269", "4354": "horizontal", "4386": "0", "4433": "1.800", "4434": "1.800", "4435": "2.071"}
|
||||
5;"ILS 2.0 Strecke";"6220";"VF_3";20;1;;"0003";{"2950": "2.154", "4431": "Ja", "4427": "90 °", "4428": "links", "4432": "Ja", "4429": "90 °", "4430": "links", "4329": "0", "4330": "0", "4331": "0", "4332": "0", "4333": "0", "4334": "0", "4373": "0", "4374": "0", "4375": "0", "4376": "2", "4377": "0", "4378": "0", "4381": "2", "4382": "ohne HARTCOAT HRC 50 ± 5", "4383": "0", "3992": "Ja", "3993": "Schönenberger-Gerüst", "4300": "mehrere Objekte", "4311": "1", "4312": "Ja", "4318": "4.166", "4391": "3", "4314": "Ja", "4319": "1.658", "4392": "3", "4337": "0", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "4340": "Ja", "4341": "0", "4342": "1", "4353": "0.269", "4354": "horizontal", "4386": "0", "4433": "1.800", "4434": "1.800", "4435": "2.071"}
|
||||
6;"ILS 2.0 Strecke";"6220";"VF_2";20;1;;"0002";{"2950": "2.154", "4431": "Ja", "4427": "90 °", "4428": "links", "4432": "Ja", "4429": "90 °", "4430": "links", "4329": "0", "4330": "0", "4331": "0", "4332": "0", "4333": "0", "4334": "0", "4373": "0", "4374": "0", "4375": "0", "4376": "2", "4377": "0", "4378": "0", "4381": "3", "4382": "ohne HARTCOAT HRC 50 ± 5", "4383": "1", "3992": "Ja", "3993": "Schönenberger-Gerüst", "4300": "mehrere Objekte", "4311": "1", "4312": "Ja", "4318": "4.166", "4391": "3", "4314": "Ja", "4319": "1.658", "4392": "3", "4337": "0", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "4340": "Ja", "4341": "0", "4342": "1", "4353": "0.269", "4354": "horizontal", "4386": "0", "4433": "1.800", "4434": "1.800", "4435": "2.071"}
|
||||
7;"ILS 2.0 Strecke";"6220";"VF_1";20;1;;"0001";{"2950": "2.154", "4431": "Ja", "4427": "90 °", "4428": "links", "4432": "Ja", "4429": "90 °", "4430": "links", "4329": "0", "4330": "0", "4331": "0", "4332": "0", "4333": "0", "4334": "0", "4373": "0", "4374": "0", "4375": "1", "4376": "2", "4377": "0", "4378": "1", "4381": "5", "4382": "ohne HARTCOAT HRC 50 ± 5", "4383": "0", "3992": "Ja", "3993": "Schönenberger-Gerüst", "4300": "mehrere Objekte", "4311": "1", "4312": "Ja", "4318": "0.727", "4391": "3", "4314": "Ja", "4319": "0.201", "4392": "3", "4337": "0", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "4340": "Ja", "4341": "0", "4342": "2", "4353": "3.704", "4354": "horizontal", "4386": "0", "4433": "1.980", "4434": "1.980", "4435": "1.875", "4436": "2.076", "4437": "2.282"}
|
||||
8;"ILS 2.0 Automation und Pneumatik - Gesamtanlage";"6269";"";20;1;;"";{"4000": "Ja", "4400": "1", "4413": "4", "4401": "0", "4414": "0", "4402": "0", "4419": "23.30", "4403": "0", "4404": "0", "4425": "0", "4426": "0", "4407": "5", "4418": "0.00", "4408": "17", "4420": "0.0", "4409": "0", "4417": "0.0", "4410": "20", "4411": "6", "4421": "2", "4422": "1", "4100": "Ja"}
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 54.
|
@@ -3,7 +3,7 @@
|
||||
"test_id": "KR_Kreuz_Q1_0Grad",
|
||||
"status": "executed",
|
||||
"block_name": "KREISEL_1_STANDARD_2000",
|
||||
"block_handle": "13A",
|
||||
"block_handle": "186",
|
||||
"insert_point": [500, 500, 2500],
|
||||
"actual_attributes": {
|
||||
"ID": "0001",
|
||||
@@ -28,7 +28,7 @@
|
||||
"test_id": "KR_Kreuz_Q2_90Grad",
|
||||
"status": "executed",
|
||||
"block_name": "KREISEL_2_STANDARD_3000",
|
||||
"block_handle": "187",
|
||||
"block_handle": "1D7",
|
||||
"insert_point": [-500, 500, 2500],
|
||||
"actual_attributes": {
|
||||
"ID": "0002",
|
||||
@@ -53,7 +53,7 @@
|
||||
"test_id": "KR_Kreuz_Q3_180Grad",
|
||||
"status": "executed",
|
||||
"block_name": "KREISEL_3_STANDARD_4000",
|
||||
"block_handle": "1D3",
|
||||
"block_handle": "227",
|
||||
"insert_point": [-500, -500, 2500],
|
||||
"actual_attributes": {
|
||||
"ID": "0003",
|
||||
@@ -78,7 +78,7 @@
|
||||
"test_id": "KR_Kreuz_Q4_270Grad",
|
||||
"status": "executed",
|
||||
"block_name": "KREISEL_4_STANDARD_5000",
|
||||
"block_handle": "21F",
|
||||
"block_handle": "277",
|
||||
"insert_point": [500, -500, 2500],
|
||||
"actual_attributes": {
|
||||
"ID": "0004",
|
||||
@@ -103,7 +103,7 @@
|
||||
"test_id": "KR_Schraeg_Q1_30Grad",
|
||||
"status": "executed",
|
||||
"block_name": "KREISEL_5_STANDARD_3000",
|
||||
"block_handle": "26B",
|
||||
"block_handle": "2C7",
|
||||
"insert_point": [3000, 3000, 3000],
|
||||
"actual_attributes": {
|
||||
"ID": "0005",
|
||||
@@ -128,7 +128,7 @@
|
||||
"test_id": "KR_Pin_Q1_0Grad",
|
||||
"status": "executed",
|
||||
"block_name": "KREISEL_6_PIN_3000",
|
||||
"block_handle": "2BC",
|
||||
"block_handle": "31C",
|
||||
"insert_point": [500, 6000, 1500],
|
||||
"actual_attributes": {
|
||||
"ID": "0006",
|
||||
@@ -153,7 +153,7 @@
|
||||
"test_id": "KR_Pin_Q1_90Grad",
|
||||
"status": "executed",
|
||||
"block_name": "KREISEL_7_PIN_4000",
|
||||
"block_handle": "30C",
|
||||
"block_handle": "370",
|
||||
"insert_point": [-500, 6500, 1500],
|
||||
"actual_attributes": {
|
||||
"ID": "0007",
|
||||
@@ -178,7 +178,7 @@
|
||||
"test_id": "KR_Pin_Q1_30Grad_Schraeg",
|
||||
"status": "executed",
|
||||
"block_name": "KREISEL_8_PIN_3000",
|
||||
"block_handle": "35C",
|
||||
"block_handle": "3C4",
|
||||
"insert_point": [3000, 8000, 1500],
|
||||
"actual_attributes": {
|
||||
"ID": "0008",
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];IDs;details
|
||||
1;"ILS 2.0 Kreisel";"6200";"Kreisel8, Kreisel6";20;2;;"0008, 0006";{"2952": "1.5", "3510": "Kreisel mit PINBAND", "3511": "1", "3512": "3.0", "3515": "0", "3517": "0", "3519": "0", "3992": "Ja", "3993": "Schönenberger-Gerüst"}
|
||||
2;"ILS 2.0 Kreisel";"6200";"Kreisel7";20;1;;"0007";{"2952": "1.5", "3510": "Kreisel mit PINBAND", "3511": "1", "3512": "4.0", "3515": "0", "3517": "0", "3519": "0", "3992": "Ja", "3993": "Schönenberger-Gerüst"}
|
||||
3;"ILS 2.0 Kreisel";"6200";"Kreisel5, Kreisel2";20;2;;"0005, 0002";{"2952": "3", "3510": "Kreisel", "3511": "1", "3512": "3.0", "3515": "0", "3517": "0", "3519": "0", "3992": "Ja", "3993": "Schönenberger-Gerüst"}
|
||||
4;"ILS 2.0 Kreisel";"6200";"Kreisel4";20;1;;"0004";{"2952": "2.5", "3510": "Kreisel", "3511": "1", "3512": "5.0", "3515": "0", "3517": "0", "3519": "0", "3992": "Ja", "3993": "Schönenberger-Gerüst"}
|
||||
5;"ILS 2.0 Kreisel";"6200";"Kreisel3";20;1;;"0003";{"2952": "2.5", "3510": "Kreisel", "3511": "1", "3512": "4.0", "3515": "0", "3517": "0", "3519": "0", "3992": "Ja", "3993": "Schönenberger-Gerüst"}
|
||||
6;"ILS 2.0 Kreisel";"6200";"Kreisel1";20;1;;"0001";{"2952": "2.5", "3510": "Kreisel", "3511": "1", "3512": "2.0", "3515": "0", "3517": "0", "3519": "0", "3992": "Ja", "3993": "Schönenberger-Gerüst"}
|
||||
7;"ILS 2.0 Automation und Pneumatik - Gesamtanlage";"6269";"";20;1;;"";{"4000": "Ja", "4400": "8", "4413": "0", "4401": "3", "4414": "0", "4402": "0", "4419": "27.00", "4403": "0", "4404": "0", "4425": "0", "4426": "0", "4407": "0", "4418": "0.00", "4408": "0", "4420": "0.0", "4409": "0", "4417": "0.0", "4410": "0", "4411": "0", "4421": "0", "4422": "0", "4100": "Ja"}
|
||||
1;"ILS 2.0 Kreisel";"6200";"Kreisel8, Kreisel6";20;2;;"0008, 0006";{"2952": "1.5", "3511": "1", "3515": "0", "3517": "0", "3519": "0", "3992": "Ja", "3993": "Schönenberger-Gerüst", "3510": "Kreisel mit PINBAND", "3512": "3.0"}
|
||||
2;"ILS 2.0 Kreisel";"6200";"Kreisel7";20;1;;"0007";{"2952": "1.5", "3511": "1", "3515": "0", "3517": "0", "3519": "0", "3992": "Ja", "3993": "Schönenberger-Gerüst", "3510": "Kreisel mit PINBAND", "3512": "4.0"}
|
||||
3;"ILS 2.0 Kreisel";"6200";"Kreisel5";20;1;;"0005";{"2952": "3", "3511": "1", "3515": "0", "3517": "0", "3519": "0", "3992": "Ja", "3993": "Schönenberger-Gerüst", "3510": "Kreisel", "3512": "3.0"}
|
||||
4;"ILS 2.0 Kreisel";"6200";"Kreisel4";20;1;;"0004";{"2952": "2.5", "3511": "1", "3515": "0", "3517": "0", "3519": "0", "3992": "Ja", "3993": "Schönenberger-Gerüst", "3510": "Kreisel", "3512": "5.0"}
|
||||
5;"ILS 2.0 Kreisel";"6200";"Kreisel3";20;1;;"0003";{"2952": "2.5", "3511": "1", "3515": "0", "3517": "0", "3519": "0", "3992": "Ja", "3993": "Schönenberger-Gerüst", "3510": "Kreisel", "3512": "4.0"}
|
||||
6;"ILS 2.0 Kreisel";"6200";"Kreisel2";20;1;;"0002";{"2952": "2.5", "3511": "1", "3515": "0", "3517": "0", "3519": "0", "3992": "Ja", "3993": "Schönenberger-Gerüst", "3510": "Kreisel", "3512": "3.0"}
|
||||
7;"ILS 2.0 Kreisel";"6200";"Kreisel1";20;1;;"0001";{"2952": "2.5", "3511": "1", "3515": "0", "3517": "0", "3519": "0", "3992": "Ja", "3993": "Schönenberger-Gerüst", "3510": "Kreisel", "3512": "2.0"}
|
||||
8;"ILS 2.0 Automation und Pneumatik - Gesamtanlage";"6269";"";20;1;;"";{"4000": "Ja", "4400": "8", "4413": "0", "4401": "3", "4414": "0", "4402": "0", "4419": "27.00", "4403": "0", "4404": "0", "4425": "0", "4426": "0", "4407": "0", "4418": "0.00", "4408": "0", "4420": "0.0", "4409": "0", "4417": "0.0", "4410": "0", "4411": "0", "4421": "0", "4422": "0", "4100": "Ja"}
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 69.
|
@@ -2,7 +2,7 @@
|
||||
{
|
||||
"test_id": "LZ_Standard",
|
||||
"status": "OK",
|
||||
"schritte_gesamt": 37,
|
||||
"schritte_gesamt": 34,
|
||||
"schritte_offen": 0
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];IDs;details
|
||||
1;"ILS 2.0 Strecke";"6220";"VF_1";20;1;;"0001";{"Anlagenhöhe in Meter": "2.154", "Streckengruppe": "mehrere Objekte", "Strecken- zu fertigende Menge": "1", "Streckengruppe - Gefällestrecke": "Ja", "Streckengruppe - Gefällestrecke 001-Länge in Meter": "4.166", "Streckengruppe - Gefällestrecke 001 -Winkel": "3", "Streckengruppe - Gefällestrecke 002": "Ja", "Streckengruppe - Gefällestrecke 002-Länge in Meter": "1.658", "Streckengruppe - Gefällestrecke 002- Winkel": "3", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke links 30°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 90°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 60°": "0", "Streckengruppe - Anzahl der Kurven - Gefällestrecke rechts 30°": "0", "Streckengruppe - Anzahl der Separatoren - Gefällestrecke": "0", "Streckengruppe - Bearbeitung Gefällestreckenteilstück für Separator (829516050)": "ohne HARTCOAT HRC 50 ± 5", "Streckengruppe - Anzahl der Scanner": "0", "Streckengruppe - Varioförderer": "Ja", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (links)": "0", "Streckengruppe - Anzahl der Motoren für Vario-Förderer (rechts)": "1", "Streckengruppe - Varioförderer 001-Länge in Meter": "0.269", "Streckengruppe - Varioförderer 001-Richtung": "horizontal", "Streckengruppe - Varioförderer 001- Winkel": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 90°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Außenbogen 30°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 90°": "2", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 60°": "0", "Streckengruppe - Anzahl der Kurven - Varioförderer Innenbogen 30°": "0", "Streckengruppe - Anzahl der Separatoren - Varioförderer": "2", "Gerüst für Einzelmodul": "Ja", "Gerüstoption für Einzelmodul": "Schönenberger-Gerüst"}
|
||||
2;"ILS 2.0 Automation und Pneumatik - Gesamtanlage";"6269";"";20;1;;"";{"Automation": "Ja", "Anzahl der Kreisel": "0", "Anzahl der Separatoren - Kreisel ohne PINBAND": "0", "Anzahl der Kreisel mit PINBAND": "0", "Anzahl der Separatoren - Kreisel mit PINBAND": "0", "Anzahl der Verbindungskreisel": "0", "Längen aller Kreisel": "0.00", "Anzahl der Weichen": "0", "Anzahl der Eckräder": "0", "Anzahl der einzelnen Gefällestrecken": "0", "Anzahl der einzelnen Vario-Förderer": "0", "Anzahl der Streckengruppen": "1", "Längen aller Gefällestrecken": "0.00", "Anzahl der Motoren in Vario - Förderer": "3", "Längen aller Vario - Förderer": "0.0", "Anzahl der ETFs": "0", "Längen aller ETFS und Zusatzstücke (Gefällestrecken)": "0.0", "Anzahl der Separatoren in der Anlage": "2", "Anzahl der Scanner in der Anlage": "0", "Zusatzmodul - Anzahl der BT-Beladung": "0", "Zusatzmodul - Anzahl der Abwurfstation": "0", "Pneumatik": "Ja"}
|
||||
1;"ILS 2.0 Strecke";"6220";"VF_1";20;1;;"0001";{"2950": "2.154", "4431": "Ja", "4427": "90 °", "4428": "links", "4432": "Ja", "4429": "90 °", "4430": "links", "4329": "0", "4330": "0", "4331": "0", "4332": "0", "4333": "0", "4334": "0", "4373": "0", "4374": "0", "4375": "0", "4376": "2", "4377": "0", "4378": "0", "4381": "2", "4382": "ohne HARTCOAT HRC 50 ± 5", "4383": "0", "3992": "Ja", "3993": "Schönenberger-Gerüst", "4300": "mehrere Objekte", "4311": "1", "4312": "Ja", "4318": "4.166", "4391": "3", "4314": "Ja", "4319": "1.658", "4392": "3", "4337": "0", "4338": "ohne HARTCOAT HRC 50 ± 5", "4339": "0", "4340": "Ja", "4341": "0", "4342": "1", "4353": "0.269", "4354": "horizontal", "4386": "0", "4433": "1.800", "4434": "1.800", "4435": "2.071"}
|
||||
2;"ILS 2.0 Automation und Pneumatik - Gesamtanlage";"6269";"";20;1;;"";{"4000": "Ja", "4400": "0", "4413": "0", "4401": "0", "4414": "0", "4402": "0", "4419": "0.00", "4403": "0", "4404": "0", "4425": "0", "4426": "0", "4407": "1", "4418": "0.00", "4408": "3", "4420": "0.0", "4409": "0", "4417": "0.0", "4410": "2", "4411": "0", "4421": "0", "4422": "0", "4100": "Ja"}
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 49.
|
@@ -183,6 +183,7 @@
|
||||
(if (findfile csv-pfad) (vl-file-delete csv-pfad))
|
||||
(if (findfile sivas-pfad) (vl-file-delete sivas-pfad))
|
||||
|
||||
(setq *csv-hoehencheck-fragen* nil) ;; keine Rueckfrage im Testlauf
|
||||
(princ (strcat "\n[TEST_EXPORT_ALL] CSV-Export -> " csv-name))
|
||||
(c:EXPORTCSV)
|
||||
(setq csv-ok (export_all:wait-for-file csv-pfad 30.0))
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
test_export_freie_separatoren.py - freie Separatoren in der Kette einer Strecke.
|
||||
Laeuft komplett ohne BricsCAD (reine Python-Logik, siehe lib/export_neighbors.py).
|
||||
|
||||
Szenario nach einem realen Mubea-Befund (VF_3 = 0015): die sepliste aus dem
|
||||
Bau kennt nur AS 0061, SEP 0062, SEP 0063, ES 0064. Die eigenstaendigen
|
||||
Separatoren 0037/0038 liegen auf der Strecke, ihre Zuordnung nennt 0015 - sie
|
||||
fehlten aber in TrackIds und Nachbarn. einsortieren_freie_separatoren nimmt
|
||||
sie nach Lage auf.
|
||||
|
||||
Alle Daten sind hier fest eingetragen (Stand des Mubea-Exports 2026-10-28) und
|
||||
werden aus keiner Datei gelesen - aendert sich die Mubea-Zeichnung, bleibt
|
||||
dieser Test unberuehrt. Er prueft den Algorithmus, nicht die Szene.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib"))
|
||||
|
||||
from export_neighbors import ( # noqa: E402
|
||||
compute_sep_kette,
|
||||
einsortieren_freie_separatoren,
|
||||
sepliste_einsortier_positionen,
|
||||
)
|
||||
from export_csv import ( # noqa: E402
|
||||
map_sepliste_kette_items,
|
||||
resolve_umlauf_und_sepliste_nachbarn,
|
||||
write_separatorliste_merkmale,
|
||||
)
|
||||
|
||||
TOL_MM = 100.0
|
||||
|
||||
|
||||
def _sep(teileid, x, y, zuordnung):
|
||||
return {
|
||||
"teileart": "ILS 2.0 Separator",
|
||||
"teileid": teileid,
|
||||
"merkmale": {"Zuordnung": zuordnung},
|
||||
"nachbarn": "",
|
||||
"_bbox": {"cx": x, "cy": y, "cz": 0.0, "dx": 150.0, "dy": 210.0},
|
||||
}
|
||||
|
||||
|
||||
def _ases(teileart, teileid, x, y, zuordnung):
|
||||
return {
|
||||
"teileart": teileart,
|
||||
"teileid": teileid,
|
||||
"_zuordnung": zuordnung,
|
||||
"merkmale": {},
|
||||
"nachbarn": "",
|
||||
"_bbox": {"cx": x, "cy": y, "cz": 0.0, "dx": 200.0, "dy": 200.0},
|
||||
}
|
||||
|
||||
|
||||
def _mubea_vf3():
|
||||
strecke = {
|
||||
"teileart": "ILS 2.0 Strecke",
|
||||
"teileid": "0015",
|
||||
"nachbarn": "0002-L",
|
||||
"merkmale": {},
|
||||
"k1": "", "k2": "",
|
||||
"_bbox": {"cx": -631.28, "cy": 6543.11, "cz": 1624.70,
|
||||
"dx": 1018.09, "dy": 12791.0},
|
||||
"sepliste": [
|
||||
{"typ": "AS", "lfdnr": 1, "id": "0061"},
|
||||
{"typ": "SEP", "lfdnr": 2, "id": "0062"},
|
||||
{"typ": "SEP", "lfdnr": 3, "id": "0063"},
|
||||
{"typ": "ES", "lfdnr": 4, "id": "0064"},
|
||||
],
|
||||
}
|
||||
return [
|
||||
strecke,
|
||||
_ases("ILS Ausschleuselement", "0061", -400.00, 270.54, "0015"),
|
||||
_sep("0062", -898.87, 1134.60, "0015"),
|
||||
_sep("0063", -702.98, 12307.81, "0015"),
|
||||
_ases("ILS Einschleuselement", "0064", -400.00, 12832.58, "0015"),
|
||||
_sep("0037", -1026.00, 10723.05, "0015"),
|
||||
_sep("0038", -1026.00, 5250.05, "0015"),
|
||||
]
|
||||
|
||||
|
||||
def _by_id(items, teileid):
|
||||
return next(it for it in items if it.get("teileid") == teileid)
|
||||
|
||||
|
||||
def _pipeline(items):
|
||||
einsortieren_freie_separatoren(items, TOL_MM)
|
||||
sep_kette = compute_sep_kette(items)
|
||||
sep_kette_by_key = map_sepliste_kette_items(items, sep_kette)
|
||||
write_separatorliste_merkmale(items, sep_kette_by_key)
|
||||
resolve_umlauf_und_sepliste_nachbarn(items, {}, sep_kette, sep_kette_by_key, {})
|
||||
return items
|
||||
|
||||
|
||||
class TestEinsortierPositionen:
|
||||
"""Reiner Rechenkern, ohne Items."""
|
||||
|
||||
KETTE = [(0.0, 0.0), (0.0, 1000.0), (0.0, 5000.0), (0.0, 6000.0)]
|
||||
|
||||
def test_zwei_kandidaten_im_selben_abschnitt_sortiert(self):
|
||||
einfuegen, verworfen = sepliste_einsortier_positionen(
|
||||
self.KETTE, [("B", 50.0, 4000.0), ("A", -50.0, 2000.0)])
|
||||
assert einfuegen == {1: ["A", "B"]}
|
||||
assert verworfen == []
|
||||
|
||||
def test_vor_as_und_hinter_es_verworfen(self):
|
||||
einfuegen, verworfen = sepliste_einsortier_positionen(
|
||||
self.KETTE, [("vor", 0.0, -500.0), ("hinter", 0.0, 6500.0)])
|
||||
assert einfuegen == {}
|
||||
assert sorted(verworfen) == ["hinter", "vor"]
|
||||
|
||||
def test_kette_um_eine_kurve(self):
|
||||
"""Polygonzug statt Gerade AS->ES: ein Separator auf dem zweiten
|
||||
Schenkel einer L-Kette gehoert in DEN Abschnitt, nicht nach
|
||||
seiner Projektion auf die Diagonale."""
|
||||
kette = [(0.0, 0.0), (0.0, 3000.0), (3000.0, 3000.0)]
|
||||
einfuegen, _ = sepliste_einsortier_positionen(kette, [("S", 1500.0, 3050.0)])
|
||||
assert einfuegen == {1: ["S"]}
|
||||
|
||||
def test_entartete_kette(self):
|
||||
einfuegen, verworfen = sepliste_einsortier_positionen(
|
||||
[(0.0, 0.0), (0.0, 0.0)], [("S", 10.0, 10.0)])
|
||||
assert einfuegen == {}
|
||||
assert verworfen == ["S"]
|
||||
|
||||
|
||||
class TestMubeaVf3:
|
||||
|
||||
def test_trackids_mit_freien_separatoren(self):
|
||||
items = _pipeline(_mubea_vf3())
|
||||
assert _by_id(items, "0015").get("trackids") == \
|
||||
"0061, 0062, 0038, 0037, 0063, 0064"
|
||||
|
||||
def test_nachbarn_der_kette(self):
|
||||
items = _pipeline(_mubea_vf3())
|
||||
assert _by_id(items, "0062")["nachbarn"] == "0061, 0038"
|
||||
assert _by_id(items, "0038")["nachbarn"] == "0062, 0037"
|
||||
assert _by_id(items, "0037")["nachbarn"] == "0038, 0063"
|
||||
assert _by_id(items, "0063")["nachbarn"] == "0037, 0064"
|
||||
|
||||
def test_hinweis_am_freien_separator(self):
|
||||
items = _pipeline(_mubea_vf3())
|
||||
assert "0015" in _by_id(items, "0037").get("warnung", "")
|
||||
assert _by_id(items, "0062").get("warnung", "") == ""
|
||||
|
||||
def test_merkmal_einsortiert_in(self):
|
||||
items = _pipeline(_mubea_vf3())
|
||||
assert _by_id(items, "0037")["merkmale"].get("Einsortiert in") == "0015"
|
||||
assert _by_id(items, "0038")["merkmale"].get("Einsortiert in") == "0015"
|
||||
assert "Einsortiert in" not in _by_id(items, "0062")["merkmale"]
|
||||
|
||||
def test_fremde_zuordnung_bleibt_draussen(self):
|
||||
items = _mubea_vf3()
|
||||
_by_id(items, "0037")["merkmale"]["Zuordnung"] = "0002-L"
|
||||
_pipeline(items)
|
||||
assert _by_id(items, "0015").get("trackids") == "0061, 0062, 0038, 0063, 0064"
|
||||
|
||||
def test_ausserhalb_der_strecken_bbox_bleibt_draussen(self):
|
||||
items = _mubea_vf3()
|
||||
_by_id(items, "0038")["_bbox"]["cx"] = -3000.0
|
||||
_pipeline(items)
|
||||
assert _by_id(items, "0015").get("trackids") == "0061, 0062, 0037, 0063, 0064"
|
||||
|
||||
def test_ohne_ids_kein_einsortieren(self):
|
||||
"""Altbestand ohne aufgeloeste IDs: Glieder nicht lokalisierbar ->
|
||||
sepliste bleibt wie gebaut."""
|
||||
items = _mubea_vf3()
|
||||
for e in _by_id(items, "0015")["sepliste"]:
|
||||
e["id"] = ""
|
||||
einsortieren_freie_separatoren(items, TOL_MM)
|
||||
assert len(_by_id(items, "0015")["sepliste"]) == 4
|
||||
@@ -0,0 +1,181 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
test_export_sivas_as_es.py - Sivas-Merkmale 4427-4432 (AS-/ES-Element) fuer
|
||||
Gefaellestrecke (GF_N) und Streckengruppe (VF_N).
|
||||
|
||||
Pruefpunkte: Vorhandensein haengt am Winkel (nicht an der Seite, die immer
|
||||
einen Vorgabewert traegt), der Winkel wird in die Sivas-Schreibweise der
|
||||
Auswahlliste uebersetzt, ohne Element bleiben Winkel UND Seite leer, die
|
||||
Zuordnung steht vollstaendig in cfg/sivas.cfg, und die GF-Gruppierung trennt
|
||||
Bloecke mit unterschiedlichem AS-/ES-Element.
|
||||
|
||||
Laeuft komplett ohne BricsCAD (reine Python-Logik).
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib"))
|
||||
|
||||
import export_sivas # noqa: E402
|
||||
import sivas_mapping # noqa: E402
|
||||
|
||||
# Sivas-Schreibweise der Winkel-Auswahlliste (cfg/sivas.cfg
|
||||
# [as_es_winkel_anzeige]) - die Tests vergleichen gegen die Config, damit ein
|
||||
# Nachziehen der Schreibweise dort nicht die halbe Testdatei bricht.
|
||||
W30 = export_sivas.as_es_winkel("30")
|
||||
W90 = export_sivas.as_es_winkel("90")
|
||||
|
||||
|
||||
def _strecke(nr, typ="Gefaellestrecke", **attr):
|
||||
"""GF_N-/VF_N-Block mit dem gemeinsamen Strecken-Attributschema."""
|
||||
attribs = {"ID": f"000{nr}", "Bezeichnung": f"GF_{nr}", "ARTINR": "6220",
|
||||
"MONTAGEHOEHE_m": "2.000", "HOEHE_VON_mm": "2000",
|
||||
"HOEHE_BIS_mm": "1000", "TYP": typ,
|
||||
"L_GF_m": "3.000", "GF_WINKEL": "3",
|
||||
"SEITE_AS": "links", "WINKEL_AS": "90",
|
||||
"SEITE_ES": "links", "WINKEL_ES": "90"}
|
||||
attribs.update(attr)
|
||||
return {"block_name": f"GF_{nr}", "x": 0.0, "y": 0.0, "z": 2000.0,
|
||||
"rotation": 0.0, "attribs": attribs}
|
||||
|
||||
|
||||
def test_as_es_vorhanden_mit_winkel_und_seite():
|
||||
details = export_sivas.build_gefaellestrecke_details(_strecke(1))
|
||||
assert details["4431"] == "Ja"
|
||||
assert details["4427"] == W90
|
||||
assert details["4428"] == "links"
|
||||
assert details["4432"] == "Ja"
|
||||
assert details["4429"] == W90
|
||||
assert details["4430"] == "links"
|
||||
|
||||
|
||||
def test_zuordnung_steht_in_der_config():
|
||||
"""Die sechs Merkmale muessen in BEIDEN Strecken-Abschnitten von
|
||||
sivas.cfg stehen (GF_N und VF_N lesen dieselben Attribute)."""
|
||||
for abschnitt in ("gefaellestrecke", "variofoerderer"):
|
||||
mapping = sivas_mapping.load_section_mapping(abschnitt)
|
||||
for merkmal, attribut, transform in (
|
||||
("4431", "WINKEL_AS", "as_es_vorhanden"),
|
||||
("4427", "WINKEL_AS", "as_es_winkel"),
|
||||
("4428", "SEITE_AS", "as_seite"),
|
||||
("4432", "WINKEL_ES", "as_es_vorhanden"),
|
||||
("4429", "WINKEL_ES", "as_es_winkel"),
|
||||
("4430", "SEITE_ES", "es_seite")):
|
||||
assert merkmal in mapping, f"{merkmal} fehlt in [{abschnitt}]"
|
||||
ist_attribut, _alt, _default, ist_transform = mapping[merkmal]
|
||||
assert ist_attribut == attribut, f"[{abschnitt}] {merkmal}"
|
||||
assert ist_transform == transform, f"[{abschnitt}] {merkmal}"
|
||||
assert ist_transform in export_sivas.TRANSFORMS
|
||||
|
||||
|
||||
def test_winkel_in_sivas_schreibweise():
|
||||
"""4427/4429 tragen den Optionswert der Auswahlliste, nicht die nackte
|
||||
Attributzahl (Vorgabe aus cfg/sivas.cfg [as_es_winkel_anzeige])."""
|
||||
details = export_sivas.build_gefaellestrecke_details(
|
||||
_strecke(1, WINKEL_AS="30", WINKEL_ES="90.0"))
|
||||
assert details["4427"] == W30
|
||||
assert details["4429"] == W90
|
||||
# Unbekannter Winkel faellt auf die ganzzahlige Rohzahl zurueck
|
||||
assert export_sivas.as_es_winkel("60.0") in (W30, W90, "60")
|
||||
|
||||
|
||||
def test_ohne_winkel_kein_element_und_keine_seite():
|
||||
"""Leerer WINKEL_AS = kein AS-Element; die Seite darf dann NICHT
|
||||
durchgereicht werden (SEITE_AS traegt mit "rechts" immer einen
|
||||
Schema-Vorgabewert)."""
|
||||
details = export_sivas.build_gefaellestrecke_details(
|
||||
_strecke(1, WINKEL_AS="", SEITE_AS="rechts"))
|
||||
assert details["4431"] == "Nein"
|
||||
assert details["4427"] == ""
|
||||
assert details["4428"] == ""
|
||||
# ES bleibt davon unberuehrt
|
||||
assert details["4432"] == "Ja"
|
||||
assert details["4430"] == "links"
|
||||
|
||||
|
||||
def test_seite_rechts():
|
||||
details = export_sivas.build_gefaellestrecke_details(
|
||||
_strecke(1, SEITE_AS="rechts", SEITE_ES="rechts"))
|
||||
assert details["4428"] == "rechts"
|
||||
assert details["4430"] == "rechts"
|
||||
|
||||
|
||||
def test_variofoerderer_hat_dieselben_merkmale():
|
||||
block = _strecke(1, typ="Streckengruppe", L_VF_m="2.000", VF_WINKEL="0",
|
||||
ANTRIEBFAHRTRICHTUNG="Auf", MOTORSEITE="rechts",
|
||||
WINKEL_AS="30", SEITE_AS="rechts")
|
||||
details = export_sivas.build_variofoerderer_details(block)
|
||||
assert details["4431"] == "Ja"
|
||||
assert details["4427"] == W30
|
||||
assert details["4428"] == "rechts"
|
||||
assert details["4429"] == W90
|
||||
|
||||
|
||||
def test_gruppierung_trennt_nach_as_seite():
|
||||
"""Sonst baugleiche Gefaellestrecken mit AS links bzw. rechts duerfen
|
||||
nicht in einer Sivas-Zeile landen (die Zeile wuerde nur eine der beiden
|
||||
Seiten zeigen)."""
|
||||
links = export_sivas.gefaellestrecke_signature(_strecke(1, SEITE_AS="links"))
|
||||
rechts = export_sivas.gefaellestrecke_signature(_strecke(2, SEITE_AS="rechts"))
|
||||
assert links != rechts
|
||||
assert links == export_sivas.gefaellestrecke_signature(_strecke(3, SEITE_AS="links"))
|
||||
|
||||
|
||||
def test_gruppierung_trennt_nach_as_winkel():
|
||||
assert (export_sivas.gefaellestrecke_signature(_strecke(1, WINKEL_AS="30"))
|
||||
!= export_sivas.gefaellestrecke_signature(_strecke(2, WINKEL_AS="90")))
|
||||
|
||||
|
||||
def test_gruppierung_ohne_element_ignoriert_die_seite():
|
||||
"""Ohne AS-Element ist die Seite bedeutungslos und steht auch nicht in der
|
||||
Zeile - sie darf die Gruppierung dann nicht aufspalten."""
|
||||
assert (export_sivas.gefaellestrecke_signature(
|
||||
_strecke(1, WINKEL_AS="", SEITE_AS="links"))
|
||||
== export_sivas.gefaellestrecke_signature(
|
||||
_strecke(2, WINKEL_AS="", SEITE_AS="rechts")))
|
||||
|
||||
|
||||
def test_reihenfolge_im_details_json():
|
||||
"""Die sechs Merkmale stehen im details-JSON direkt HINTER 2950
|
||||
(Anlagenhoehe) - so vorgegeben, und so steht es in beiden Abschnitten von
|
||||
sivas.cfg. Die Reihenfolge der JSON-Keys folgt der Zeilenreihenfolge der
|
||||
Config (configparser und dict erhalten beide die Einfuegereihenfolge)."""
|
||||
erwartet = ["2950", "4431", "4427", "4428", "4432", "4429", "4430"]
|
||||
gf = list(export_sivas.build_gefaellestrecke_details(_strecke(1)))
|
||||
vf = list(export_sivas.build_variofoerderer_details(
|
||||
_strecke(2, typ="Streckengruppe", L_VF_m="2.000")))
|
||||
assert gf[:len(erwartet)] == erwartet
|
||||
assert vf[:len(erwartet)] == erwartet
|
||||
|
||||
|
||||
def test_altbestand_ohne_die_attribute():
|
||||
"""Bloecke aus Zeichnungen, die vor der Einfuehrung von WINKEL_AS gebaut
|
||||
wurden, haben die Attribute gar nicht - dann greift der leere Default und
|
||||
es wird "Nein" gemeldet (statt KeyError). Das ist die einzig moegliche
|
||||
Aussage: Sivas kennt nur Ja/Nein, kein "unbekannt"."""
|
||||
block = _strecke(1)
|
||||
for tag in ("WINKEL_AS", "SEITE_AS", "WINKEL_ES", "SEITE_ES"):
|
||||
del block["attribs"][tag]
|
||||
details = export_sivas.build_gefaellestrecke_details(block)
|
||||
assert details["4431"] == "Nein"
|
||||
assert details["4432"] == "Nein"
|
||||
assert details["4427"] == details["4428"] == ""
|
||||
assert details["4429"] == details["4430"] == ""
|
||||
|
||||
|
||||
def test_transform_mit_attribs_kontext():
|
||||
"""Der @braucht_attribs-Transform muss das komplette Attribut-Dict sehen -
|
||||
sonst koennte die Seite ihre Abhaengigkeit vom Winkel nicht pruefen."""
|
||||
assert getattr(export_sivas.as_seite, "braucht_attribs", False)
|
||||
assert getattr(export_sivas.es_seite, "braucht_attribs", False)
|
||||
assert not getattr(export_sivas.ja_nein, "braucht_attribs", False)
|
||||
|
||||
mapping = {"4428": ("SEITE_AS", None, "", "as_seite")}
|
||||
attribs = {"SEITE_AS": "links", "WINKEL_AS": "90"}
|
||||
assert sivas_mapping.anwenden(mapping, attribs, export_sivas.TRANSFORMS) \
|
||||
== {"4428": "links"}
|
||||
attribs_ohne = {"SEITE_AS": "links", "WINKEL_AS": ""}
|
||||
assert sivas_mapping.anwenden(mapping, attribs_ohne, export_sivas.TRANSFORMS) \
|
||||
== {"4428": ""}
|
||||
@@ -100,7 +100,7 @@ def test_geruest_unveraendert():
|
||||
assert zeilen["825002022"]["anzahl"] == 2
|
||||
assert zeilen["825002022"]["teileart"] == "Geruest Saeule 2 Zoll"
|
||||
assert zeilen["825002022"]["ids"] == ["0060"]
|
||||
assert zeilen["825002022"]["dispgruppe"] == 20
|
||||
assert zeilen["825002022"]["dispgruppe"] == 30
|
||||
# Ohne TEILEFARBE kein Farb-Merkmal
|
||||
assert zeilen["825002022"]["details"] == {}
|
||||
|
||||
|
||||
@@ -26,12 +26,14 @@
|
||||
;; also genau die Werte, mit denen die Ketten in BricsCAD gebaut wurden.
|
||||
;;
|
||||
;; JSON-Aufbau (FLACH, weil ssg-load-json zeilenweise liest - Details in
|
||||
;; tests/testdata/object_data.md Abschnitt 8):
|
||||
;; doc/json-input-lisp.md Abschnitt 6):
|
||||
;; Kopf-Objekt (traegt "test_id"): test_id, anlagetyp, modus,
|
||||
;; anzahl_eingaben, block, dxf_handle, startpunkt_mm,
|
||||
;; rotation_grad, beschreibung, sivas_* , erwartung_hinweis
|
||||
;; Eingabe-Objekt (traegt "typ"): point_abs | point_rel | real | int |
|
||||
;; string | step - in exakter Frage-Reihenfolge
|
||||
;; string | step | nil - in exakter Frage-Reihenfolge
|
||||
;; ("nil" = Frage gestellt und bewusst uebergangen, z.B.
|
||||
;; keine Zufuehrungsachse gewaehlt)
|
||||
;; Ein Kopf-Objekt beginnt eine Kette, die folgenden Eingabe-Objekte gehoeren
|
||||
;; dazu (hmrec:gruppiere).
|
||||
;;
|
||||
@@ -291,6 +293,13 @@
|
||||
(list (cons "STR" (hmrec:als-string (ssg-val e "wert")))))
|
||||
((= typ "step")
|
||||
(list (cons "STEP" (hmrec:als-string (ssg-val e "wert")))))
|
||||
;; Eine Frage, die gestellt und bewusst uebergangen wurde (bisher nur die
|
||||
;; Zufuehrungsachse des AS-Elements, siehe ProtokollSink.as_achse in
|
||||
;; lib/vf_journal_export.py) - im Journal ein wertloser "NIL"-Eintrag.
|
||||
;; Er MUSS mitlaufen: beim Replay poppt ihn vfl-in-point, sonst zoege
|
||||
;; dieser Aufruf den naechsten Wert aus der Queue (Desync).
|
||||
((= typ "nil")
|
||||
(list (cons "NIL" nil)))
|
||||
(T nil)
|
||||
)
|
||||
)
|
||||
@@ -468,6 +477,7 @@
|
||||
;; aufgehen und warten).
|
||||
(setq *hmrec-alt-wizard* (if (boundp '*vfl-wizard-mode*) *vfl-wizard-mode*))
|
||||
(setq *vfl-wizard-mode* nil)
|
||||
(setq *hmrec-alt-gui* (if (boundp '*ssg-gui-aus*) *ssg-gui-aus*))
|
||||
(if (car (atoms-family 1 '("SSG-GUI-AUS"))) (ssg-gui-aus))
|
||||
;; Headless-Riegel der Produktion einschalten: eine erschoepfte Replay-Queue
|
||||
;; ist dann ein harter, lokalisierter Abbruch statt eines stillen Rueckfalls
|
||||
@@ -488,7 +498,7 @@
|
||||
alert *hmrec-alt-alert*)
|
||||
(setq *vfl-wizard-mode* *hmrec-alt-wizard*)
|
||||
(setq *vfl-headless* *hmrec-alt-headless*)
|
||||
(if (car (atoms-family 1 '("SSG-GUI-AN"))) (ssg-gui-an))
|
||||
(setq *ssg-gui-aus* *hmrec-alt-gui*) ; Vorzustand, nicht pauschal an
|
||||
(princ)
|
||||
)
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ Zwei Ebenen:
|
||||
|
||||
Die Testdaten stammen aus lib/vf_journal_export.py (Journale der VF_n-Bloecke
|
||||
aus data/polylines.dxf, XDATA-App SSG_VF_EDIT) und nicht aus Handarbeit -
|
||||
Schema siehe tests/testdata/object_data.md Abschnitt 8.
|
||||
Schema siehe doc/json-input-lisp.md Abschnitt 6.
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
;; hundm05.json auch andere Objekte der Anlage stehen - erkennbar an
|
||||
;; "function". Format wie in tests/testdata/kreisel_tests.json, damit die
|
||||
;; Felder nicht zweimal beschrieben werden muessen (Schema: siehe
|
||||
;; tests/testdata/object_data.md Abschnitt 1).
|
||||
;; doc/json-input-lisp.md Abschnitt 1).
|
||||
;; vsp-gruppieren ignoriert diese Objekte, sie stoeren die Ketten also nicht.
|
||||
;; lib/vf_spec_export.py uebernimmt sie beim Neuerzeugen der Spec-Daten
|
||||
;; unveraendert ans Dateiende (sonst waeren sie beim naechsten Lauf weg).
|
||||
@@ -61,7 +61,7 @@
|
||||
;; Unterstuetzt: Kreisel (function "insert", wie test_kreisel.lsp) und
|
||||
;; beliebige eigenstaendige Bloecke ueber "block" (Separator/Scanner sowie
|
||||
;; BTMT-Beladung/SC_Entladung, wie in mubea.json - Schema tests/testdata/
|
||||
;; object_data.md Abschnitt 5). Unterscheidung ueber das Feld "block": nur
|
||||
;; json-input-lisp.md Abschnitt 2). Unterscheidung ueber das Feld "block": nur
|
||||
;; Bloecke haben es, Kreisel-Eintraege nicht. hundm05:bau-sensor ist dabei
|
||||
;; blockname-agnostisch (reiner _.INSERT), der "kind"-Wert "sensor" bleibt
|
||||
;; als Sammelbegriff fuer "kein Kreisel" bestehen (siehe dort).
|
||||
@@ -125,7 +125,7 @@
|
||||
"kreisel-insert-script lieferte nil"))))))
|
||||
|
||||
;; Separator/Scanner/BTMT-Beladung/SC_Entladung bauen ("block"-Eintraege,
|
||||
;; siehe object_data.md Abschnitt 5). ils-insert-sensor/ils-insert-station
|
||||
;; siehe json-input-lisp.md Abschnitt 2). ils-insert-sensor/ils-insert-station
|
||||
;; (SSG_LIB_Commands.lsp) sind dafuer NICHT scriptbar (fragen Punkt/Rotation
|
||||
;; per getpoint/pause in einer Schleife) - wir bauen den _.INSERT darum
|
||||
;; direkt selbst nach, wie mubea:build-separator-one in tests/test_mubea.lsp
|
||||
|
||||
@@ -59,7 +59,11 @@ def spec_ergebnisse(alle_ergebnisse):
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def kreisel_ergebnisse(alle_ergebnisse):
|
||||
raus = [r for r in alle_ergebnisse if r.get("kind") == "kreisel"]
|
||||
"""Ergebnisse ALLER nachgetragenen Anlagenteile (Gegenstueck zu
|
||||
kreisel_objekte) - nicht nur kind "kreisel": Separatoren, Scanner und
|
||||
BTMT kommen als kind "sensor" zurueck. Der Name ist historisch."""
|
||||
raus = [r for r in alle_ergebnisse
|
||||
if r.get("kind", "linienzug") != "linienzug"]
|
||||
if not raus:
|
||||
pytest.skip("keine Kreisel-Ergebnisse (Lauf vor dem Nachtragen "
|
||||
"weiterer Anlagenteile?)")
|
||||
@@ -180,7 +184,7 @@ class TestSpecBau:
|
||||
# ============================================================
|
||||
# tests/testdata/hundm05.json enthaelt neben den Ketten auch andere Objekte
|
||||
# der Anlage - Format wie tests/testdata/kreisel_tests.json (Schema in
|
||||
# tests/testdata/object_data.md Abschnitt 1). Gebaut werden sie von
|
||||
# doc/json-input-lisp.md Abschnitt 1). Gebaut werden sie von
|
||||
# hundm05:bau-zusatzobjekte in tests/test_hundm05.lsp.
|
||||
|
||||
class TestZusatzobjekte:
|
||||
|
||||
+239
-6
@@ -13,6 +13,7 @@
|
||||
;; "typ" ist ein Eingabe-Schritt in exakter Aufruf-Reihenfolge:
|
||||
;; {"typ":"point_abs","wert":[x,y,z]} absoluter Punkt (getpoint)
|
||||
;; {"typ":"point_rel","dL":..,"hz":..} Basispunkt + dL entlang Richtung hz
|
||||
;; {"typ":"point_none"} getpoint ohne Punkt (Enter -> nil)
|
||||
;; {"typ":"real","wert":..} getreal
|
||||
;; {"typ":"int","wert":..} getint
|
||||
;; {"typ":"string","wert":".."} getstring
|
||||
@@ -53,17 +54,23 @@
|
||||
;; Skript-Eintrag (P dL hz) -> Basispunkt + dL entlang Richtung hz (Grad),
|
||||
;; sodass die Projektion in vfl-neue-linie-messen
|
||||
;; exakt dL ergibt.
|
||||
;; Skript-Eintrag KEIN -> nil (Enter ohne Punkt, z.B. optionale
|
||||
;; AS-Zufuehrungsachse nicht gesetzt)
|
||||
(defun tlz-getpoint (a b / spec base rad)
|
||||
(setq spec (tlz-pop))
|
||||
(setq base (if (and a (listp a)) a '(0.0 0.0 0.0)))
|
||||
(if (and (listp spec) (= (car spec) 'A))
|
||||
(list (float (cadr spec)) (float (caddr spec)) (float (cadddr spec)))
|
||||
(cond
|
||||
((= spec 'KEIN) nil)
|
||||
((and (listp spec) (= (car spec) 'A))
|
||||
(list (float (cadr spec)) (float (caddr spec)) (float (cadddr spec))))
|
||||
(T
|
||||
(progn
|
||||
(setq rad (* (float (caddr spec)) (/ pi 180.0)))
|
||||
(list (+ (car base) (* (float (cadr spec)) (cos rad)))
|
||||
(+ (cadr base) (* (float (cadr spec)) (sin rad)))
|
||||
(caddr base))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(defun tlz-getstring (a) (tlz-pop))
|
||||
@@ -84,6 +91,8 @@
|
||||
(setq q (cons (cons 'A (ssg-val schritt "wert")) q)))
|
||||
((= typ "point_rel")
|
||||
(setq q (cons (list 'P (ssg-val schritt "dL") (ssg-val schritt "hz")) q)))
|
||||
((= typ "point_none")
|
||||
(setq q (cons 'KEIN q)))
|
||||
((= typ "real")
|
||||
(setq q (cons (float (ssg-val schritt "wert")) q)))
|
||||
((= typ "int")
|
||||
@@ -139,7 +148,7 @@
|
||||
;; ebenfalls nur einen einzigen Testfall pro Lauf kennt).
|
||||
(defun tlz-run-datei (json-datei test-id befehl-anzeige /
|
||||
daten meta schritte-anz rest-anz status
|
||||
old-vgp old-gs old-gi old-gr err)
|
||||
old-vgp old-gs old-gi old-gr err old-gui)
|
||||
(if (or (not *lib-initialized*) (null bogen-auf)) (init-bibliothek))
|
||||
(if (null (car (atoms-family 1 '("VF-LINIENZUG-MODUS"))))
|
||||
(progn
|
||||
@@ -176,6 +185,7 @@
|
||||
;; GUI aus: keine Wizard-DCL-Dialoge waehrend des automatischen Replays -
|
||||
;; die Eingaben kommen aus der Mock-Queue (getstring/getint/getreal), siehe
|
||||
;; ssg-gui-aus/ssg-gui-p in ssg_core.lsp und vfl-wizard-mode-p.
|
||||
(setq old-gui (if (boundp '*ssg-gui-aus*) *ssg-gui-aus*))
|
||||
(if (car (atoms-family 1 '("SSG-GUI-AUS"))) (ssg-gui-aus))
|
||||
|
||||
;; --- Eingabe-Funktionen sichern und durch Mocks ersetzen ---
|
||||
@@ -192,9 +202,11 @@
|
||||
|
||||
;; --- Eingabe-Funktionen wiederherstellen (IMMER) ---
|
||||
(setq vfl-getpoint old-vgp getstring old-gs getint old-gi getreal old-gr)
|
||||
;; GUI wieder einschalten (auch nach Fehler), damit eine folgende interaktive
|
||||
;; Sitzung nicht headless bleibt.
|
||||
(if (car (atoms-family 1 '("SSG-GUI-AN"))) (ssg-gui-an))
|
||||
;; GUI-Zustand von VOR dem Test wiederherstellen (auch nach Fehler) - NICHT
|
||||
;; pauschal einschalten: unter SSG_RUN_ALL_TESTS ist sie fuer den ganzen
|
||||
;; Batch aus, und ein pauschales ssg-gui-an liess den anschliessenden
|
||||
;; EXPORTSIVAS nach Hoehen-Check/Bereinigen fragen (Lauf hing).
|
||||
(setq *ssg-gui-aus* old-gui)
|
||||
|
||||
(setq rest-anz (length *tlz-q*))
|
||||
|
||||
@@ -255,3 +267,224 @@
|
||||
(tlz-run-datei json-datei "LZ_Stufe2_Kettenende" "TEST_LINIENZUG_STUFE2")
|
||||
(princ)
|
||||
)
|
||||
|
||||
|
||||
;; ============================================================
|
||||
;; MODUS 2 (aus 3D-Linie mit Zielhoehe) - Replay echter Laeufe
|
||||
;; ============================================================
|
||||
;; Anders als die Modus-1-Faelle oben braucht Modus 2 KEINE Mocks und KEINEN
|
||||
;; gezeichneten Pfad: sein Journal traegt einen SEGS-Eintrag mit der kompletten
|
||||
;; Segment-Essenz (Typ, Richtung, Laenge, Eckwinkel, Seite, Start/Ende), ist
|
||||
;; also von den Original-Objekten unabhaengig - dieselbe Eigenschaft, auf der
|
||||
;; schon vfl-konvertiere-ent beruht (vfl-journal-hat-segs-p). Der Test spielt
|
||||
;; daher das echte, aus der Zeichnung ausgelesene Journal ab.
|
||||
;;
|
||||
;; Die Faelle sind zwei BEWUSST gebildete Paare, kein Sammelsurium:
|
||||
;;
|
||||
;; A/B (Ecke als Vario-Kurve bzw. als GF-Bogen) - derselbe Pfad, nur die
|
||||
;; 90-Grad-Ecke einmal waagerecht und einmal geneigt eingebaut. Sie laufen
|
||||
;; durch verschiedene Zweige (mit und ohne flache Zone), und genau der
|
||||
;; VERGLEICH hat am 2026-10-26/27 Fehler aufgedeckt, die ein einzelner
|
||||
;; Lauf nicht gezeigt haette (ES-Fussabdruck am falschen Segment: 878 mm
|
||||
;; nur in der GF-Bogen-Variante).
|
||||
;;
|
||||
;; U-Form 1..3 (gefalteter Lauf) - der Pfad wechselt ueber zwei 90-Grad-
|
||||
;; Vario-Kurven dreimal die Fahrtrichtung, die Kletterstrecke liegt
|
||||
;; dadurch in einem ANDEREN Schenkel als der Lauf-Eingang. Hier variieren
|
||||
;; GF-VERTEILUNG (alles am Einlauf vs. 1/2+1/2) und WINKEL. Beides ist
|
||||
;; noetig: die Verteilung entscheidet, ob ueberhaupt GF im fremden
|
||||
;; Schenkel steht (Nachrechner, Fueller-A), und der Restfehler der alten
|
||||
;; Bilanz skalierte mit L_GF, also mit dem Winkel (6 Grad 90 mm, 9 Grad
|
||||
;; 934 mm) - zwei Laeufe mit demselben Winkel haetten das verdeckt.
|
||||
;;
|
||||
;; Einen Fall zu loeschen nimmt dem Test den jeweiligen Vergleich und damit
|
||||
;; seinen Wert.
|
||||
;;
|
||||
;; Aufgezeichnet mit lib/vf_journal_export.py aus echten BricsCAD-Laeufen
|
||||
;; (A/B am 2026-10-27, U-Form am 2026-10-29).
|
||||
;; Pruefkriterium (Nutzer-Vorgabe 2026-10-26): quer zur ES-KS_AUS-Achse und dZ
|
||||
;; MUESSEN ~0 sein, laengs DARF abweichen (Ausladung des ES-Elements).
|
||||
|
||||
(setq *tlz-m2-toleranz* 1.0) ; mm; 0.2 ist die Messaufloesung der Blockmasse
|
||||
|
||||
;; Toleranz fuer den LAENGS-Wert gegen "erwartung_laengs_mm" aus den Testdaten.
|
||||
;; Der Wert ist die Ausladung des ES-Elements und damit je Fall eine Konstante
|
||||
;; (gemessen: 104.68 mm bei ES_Element_30, 637.58 mm bei ES_Element_90) - 5 mm
|
||||
;; reichen also fuer Rundung, ohne echte Abweichungen durchzulassen.
|
||||
;;
|
||||
;; Warum ueberhaupt geprueft, wo laengs doch ausdruecklich abweichen DARF:
|
||||
;; Am 2026-10-29 loeste ein Experiment den Schluss-Fueller gegen Richtung UND
|
||||
;; Laenge und traf den Zielpunkt dadurch in X und Y exakt - um den Preis, dass
|
||||
;; es die letzte Gerade um 6.15 Grad verdrehte (sichtbar schiefer Schenkel im
|
||||
;; U-Form-Fall). quer und dZ waren dabei NULL, der Test meldete OK; gefunden
|
||||
;; wurde der Fehler nur mit dem Auge in der Zeichnung.
|
||||
;; laengs ist der Wert, der das verraet: ein verdrehter Hauptstrang zielt auf
|
||||
;; den Endpunkt und drueckt laengs von ~638 mm auf ~0. Die Pruefung ist also
|
||||
;; kein zweites Genauigkeitskriterium, sondern ein Formkriterium - sie stellt
|
||||
;; sicher, dass der ES-Versatz noch da ist, wo er hingehoert.
|
||||
(setq *tlz-m2-laengs-toleranz* 5.0)
|
||||
|
||||
;; Wert als String - eigene Kopie statt hmrec:als-string aus
|
||||
;; test_hm_recformat.lsp: diese Datei soll fuer sich allein ladbar bleiben.
|
||||
(defun tlz-m2-str (v)
|
||||
(cond ((null v) "")
|
||||
((= (type v) 'STR) v)
|
||||
((= (type v) 'INT) (itoa v))
|
||||
((= (type v) 'REAL) (rtos v 2 6))
|
||||
(T (vl-princ-to-string v))))
|
||||
|
||||
;; Ein JSON-Record -> Journal-Eintrag (kind . wert), nil bei Metadaten-Zeile.
|
||||
(defun tlz-m2-eintrag->journal (e / art)
|
||||
(setq art (ssg-val e "art"))
|
||||
(cond
|
||||
((null art) nil)
|
||||
((= art "PT") (cons "PT" (list (float (ssg-val e "x"))
|
||||
(float (ssg-val e "y"))
|
||||
(float (ssg-val e "z")))))
|
||||
((= art "REAL") (cons "REAL" (float (ssg-val e "wert"))))
|
||||
((= art "INT") (cons "INT" (fix (ssg-val e "wert"))))
|
||||
;; SEGS traegt im Journal eine LISTE von Segment-Records, nicht den
|
||||
;; String - genau diese Umwandlung macht auch der XDATA-Decoder
|
||||
;; (vfl-journal-string->entry). Ohne sie bekommt vfl-in-segmente den
|
||||
;; Rohstring und der erste mapcar darauf stirbt (real 2026-10-27).
|
||||
((= art "SEGS") (cons "SEGS" (vfl-string->segs (tlz-m2-str (ssg-val e "wert")))))
|
||||
(T (cons art (tlz-m2-str (ssg-val e "wert"))))))
|
||||
|
||||
;; Einen Modus-2-Fall abspielen. Rueckgabe: (status laengs quer dz offen).
|
||||
(defun tlz-m2-run (json-datei test-id anzeige /
|
||||
daten journal meta offen err status abw j
|
||||
old-headless old-gui quer dz laengs
|
||||
soll-laengs laengs-ok)
|
||||
(if (or (not *lib-initialized*) (null bogen-auf)) (init-bibliothek))
|
||||
(princ (strcat "\n\n--- " anzeige " ---"))
|
||||
;; Vorbelegen, damit der Ergebnis-Record auch im Fehlerzweig Zahlen hat -
|
||||
;; sonst stirbt das abschliessende rtos an nil (real passiert 2026-10-27).
|
||||
(setq laengs 0.0 quer 999.0 dz 999.0 offen 0 status "FEHLER")
|
||||
(setq daten (ssg-load-json json-datei))
|
||||
(if (null daten)
|
||||
(progn (princ (strcat "\n FEHLER: Testdaten fehlen: " json-datei))
|
||||
(setq status "FEHLER"))
|
||||
(progn
|
||||
(setq meta (car daten))
|
||||
(setq journal '())
|
||||
(foreach e daten
|
||||
(setq j (tlz-m2-eintrag->journal e))
|
||||
(if j (setq journal (cons j journal))))
|
||||
(setq journal (reverse journal))
|
||||
(princ (strcat "\n Journal-Eintraege: " (itoa (length journal))))
|
||||
(if meta (princ (strcat "\n Szenario: " (ssg-val meta "kurz"))))
|
||||
|
||||
(ssg-start anzeige '(("OSMODE") ("ATTREQ") ("ATTDIA")))
|
||||
(setvar "OSMODE" 0) (setvar "ATTREQ" 0) (setvar "ATTDIA" 0)
|
||||
;; GUI aus (keine Wizard-Dialoge) UND headless: eine erschoepfte
|
||||
;; Replay-Queue ist damit ein harter Abbruch MIT Fundstelle statt eines
|
||||
;; stillen Rueckfalls auf eine Live-Abfrage, die im Batch haengen wuerde.
|
||||
(setq old-gui *ssg-gui-aus* old-headless *vfl-headless*)
|
||||
(if (car (atoms-family 1 '("SSG-GUI-AUS"))) (ssg-gui-aus))
|
||||
(setq *vfl-headless* T *vfl-m2-abweichung* nil)
|
||||
|
||||
(vfl-journal-replay-start journal)
|
||||
(setq err (vl-catch-all-apply 'vf-linienzug-modus2 '()))
|
||||
|
||||
(setq *vfl-headless* old-headless *ssg-gui-aus* old-gui)
|
||||
(if (car (atoms-family 1 '("SSG-GUI-AN"))) (if (null old-gui) (ssg-gui-an)))
|
||||
|
||||
(setq offen (length *vfl-replay-queue*))
|
||||
(setq abw (if (boundp '*vfl-m2-abweichung*) *vfl-m2-abweichung* nil))
|
||||
(setq laengs (if abw (car abw) 0.0)
|
||||
quer (if abw (cadr abw) 999.0)
|
||||
dz (if abw (caddr abw) 999.0))
|
||||
(cond
|
||||
((vl-catch-all-error-p err)
|
||||
(setq status "FEHLER")
|
||||
(princ (strcat "\n FEHLER: " (vl-catch-all-error-message err))))
|
||||
((null abw)
|
||||
(setq status "FEHLER")
|
||||
(princ "\n FEHLER: keine Abweichung gemessen (Bau nicht beendet)."))
|
||||
(T
|
||||
(princ (strcat "\n laengs=" (rtos laengs 2 1)
|
||||
" quer=" (rtos quer 2 1)
|
||||
" dZ=" (rtos dz 2 1) " mm"))
|
||||
(if (> offen 0)
|
||||
(princ (strcat "\n WARNUNG: " (itoa offen)
|
||||
" Journal-Eintraege NICHT verbraucht (Ablauf weicht ab).")))
|
||||
;; laengs gegen den erwarteten ES-Versatz pruefen, sofern die
|
||||
;; Testdaten einen nennen (siehe *tlz-m2-laengs-toleranz*).
|
||||
(setq soll-laengs (if meta (ssg-val meta "erwartung_laengs_mm") nil))
|
||||
(setq laengs-ok
|
||||
(if (numberp soll-laengs)
|
||||
(<= (abs (- laengs (float soll-laengs))) *tlz-m2-laengs-toleranz*)
|
||||
T))
|
||||
(if (not laengs-ok)
|
||||
(princ (strcat "\n WARNUNG: laengs " (rtos laengs 2 1)
|
||||
" statt erwarteter " (rtos (float soll-laengs) 2 1)
|
||||
" mm - der Hauptstrang zeigt nicht mehr in die"
|
||||
" gezeichnete Richtung (ES-Versatz verschwunden?).")))
|
||||
(setq status
|
||||
(if (and (<= (abs quer) *tlz-m2-toleranz*)
|
||||
(<= (abs dz) *tlz-m2-toleranz*)
|
||||
laengs-ok
|
||||
(= offen 0))
|
||||
"OK" "ABWEICHUNG"))
|
||||
(princ (strcat "\n -> " status
|
||||
" (Soll: |quer| und |dZ| <= " (rtos *tlz-m2-toleranz* 2 1)
|
||||
" mm, laengs = "
|
||||
(if (numberp soll-laengs)
|
||||
(strcat (rtos (float soll-laengs) 2 0) " +/- "
|
||||
(rtos *tlz-m2-laengs-toleranz* 2 0) " mm")
|
||||
"frei")
|
||||
")"))))
|
||||
(ssg-end)))
|
||||
(list status laengs quer dz offen))
|
||||
|
||||
;; Testfall-Tabelle: (Dateiname test-id Anzeigename). Ein weiterer Fall ist
|
||||
;; damit EINE Zeile - der Ablauf darunter ist generisch. Reihenfolge =
|
||||
;; Ausgabereihenfolge; die beiden Paare stehen bewusst beieinander.
|
||||
(setq *tlz-m2-faelle*
|
||||
(list
|
||||
(list "linienzug_modus2_variokurve.json" "LZ_M2_variokurve"
|
||||
"Variante A: Ecke = Vario-Kurve")
|
||||
(list "linienzug_modus2_gfbogen.json" "LZ_M2_gfbogen"
|
||||
"Variante B: Ecke = GF-Bogen")
|
||||
(list "linienzug_modus2_uform_gf1.json" "LZ_M2_uform_gf1"
|
||||
"U-Form 1: GF alles am Einlauf")
|
||||
(list "linienzug_modus2_uform_halb.json" "LZ_M2_uform_halb"
|
||||
"U-Form 2: GF 1/2 + 1/2")
|
||||
(list "linienzug_modus2_uform_halb_steil.json" "LZ_M2_uform_halb_steil"
|
||||
"U-Form 3: GF 1/2 + 1/2, steilere Winkel-Option")))
|
||||
|
||||
(defun c:TEST_LINIENZUG_MODUS2 ( / basis fall r erg zeilen anzahl-ok)
|
||||
;; Doppelte Backslashes: "\t" waere in AutoLISP ein TABULATOR, der Pfad
|
||||
;; wuerde zu "...dxfmakros<TAB>ests<TAB>estdata" (real passiert 2026-10-27).
|
||||
(setq basis (strcat (getenv "DXFMAKRO") "\\tests\\testdata\\"))
|
||||
(princ "\n================================================================")
|
||||
(princ (strcat "\n TEST_LINIENZUG_MODUS2 - " (itoa (length *tlz-m2-faelle*))
|
||||
" Ketten aus echten BricsCAD-Laeufen"))
|
||||
(princ "\n================================================================")
|
||||
(setq erg '() zeilen '() anzahl-ok 0)
|
||||
(foreach fall *tlz-m2-faelle*
|
||||
(setq r (tlz-m2-run (strcat basis (car fall)) (cadr fall) (caddr fall)))
|
||||
(if (= (car r) "OK") (setq anzahl-ok (1+ anzahl-ok)))
|
||||
(setq erg (cons (list (caddr fall) (car r)) erg))
|
||||
(setq zeilen
|
||||
(cons (strcat " { \"test_id\": \"" (cadr fall)
|
||||
"\", \"status\": \"" (car r)
|
||||
"\", \"quer_mm\": " (rtos (caddr r) 2 2)
|
||||
", \"dz_mm\": " (rtos (cadddr r) 2 2)
|
||||
", \"laengs_mm\": " (rtos (cadr r) 2 2) " }")
|
||||
zeilen)))
|
||||
(setq erg (reverse erg) zeilen (reverse zeilen))
|
||||
(princ "\n\n================================================================")
|
||||
(princ "\n ERGEBNIS")
|
||||
(princ "\n----------------------------------------------------------------")
|
||||
(foreach e erg
|
||||
(princ (strcat "\n " (car e) ": " (cadr e))))
|
||||
(princ (strcat "\n----------------------------------------------------------------"
|
||||
"\n " (itoa anzahl-ok) " von " (itoa (length *tlz-m2-faelle*))
|
||||
" OK"))
|
||||
(princ "\n================================================================")
|
||||
;; Ergebnis fuer run-all (Konvention wie linienzug:export-results).
|
||||
;; ssg-join aus ssg_core - die Zeilen sind bereits fertige JSON-Objekte.
|
||||
(setq *linienzug-m2-test-results* (ssg-join zeilen ",\n"))
|
||||
(princ)
|
||||
)
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
;; --- Vario (VF_*): L_GF/L_VF fuer gegebenes deltaL+deltaH+winkel loesen, dann bauen ---
|
||||
;; deltaL ist (wie bei der Gefaellestrecke) die horizontale PROJIZIERTE
|
||||
;; Gesamtlaenge des VF (Vorlauf L_GF1 + Foerderer L_VF + Nachlauf L_GF2 +
|
||||
;; Boegen/AS-ES-Elemente), analog foerderer_tests.json/object_data.md 3.1 -
|
||||
;; Boegen/AS-ES-Elemente), analog foerderer_tests.json/json-input-lisp.md 3 -
|
||||
;; KEIN abgeleiteter Wert. "winkel" erzwingt einen bestimmten Bogenwinkel aus
|
||||
;; der Kandidatenliste von berechne-alle-winkel (wie foerderer:winkel-
|
||||
;; erzwingen in test_foerderer.lsp), statt den automatisch kleinsten
|
||||
@@ -295,7 +295,7 @@
|
||||
;; --- Eine einzelne Gefaellestrecke bauen (Modus 1) ---
|
||||
;; Aufbau AUSSCHLIESSLICH aus Anfangspunkt (start-mm) und horizontaler
|
||||
;; Gesamtlaenge deltaL - KEIN Endpunkt (wie Produktion/gefaellestrecke.dcl
|
||||
;; Modus 1, siehe object_data.md 2.1). L_stau wird aus deltaL abgeleitet
|
||||
;; Modus 1, siehe json-input-lisp.md 4.1). L_stau wird aus deltaL abgeleitet
|
||||
;; (identische Formel wie test_gefaellestrecke.lsp):
|
||||
;; L_stau = (deltaL - aus-dx - ein-dx - sep_x) / cos(v)
|
||||
;; sep_x = 300 * cos(v), v = Element-Winkel (winkel_grad, Default 3 Grad)
|
||||
|
||||
+119
-8
@@ -69,7 +69,56 @@
|
||||
;; --- Hilfsfunktion: String-Wert aus JSON-Objekt-Zeile lesen ---
|
||||
;; Sucht "key": "value" in obj-str und gibt value zurueck.
|
||||
;; Rueckgabe: String (nicht leer) oder nil (key fehlt, null, leer).
|
||||
(defun alltests:get-str (obj-str key / pat pos val-start val-end val)
|
||||
;; ------------------------------------------------------------
|
||||
;; Laufprotokoll je Test (Debug-Schalter "testlauf", Standard EIN)
|
||||
;; ------------------------------------------------------------
|
||||
;; DXFM_LOG/testlauf_<name>.dbg - eine Datei je Test, bei jedem Lauf neu.
|
||||
;; Bewusst NICHT ueber dbgopen/*dbg-path*: die getesteten Module oeffnen und
|
||||
;; schliessen dort ihre eigenen .dbg-Dateien (vfl_modus1.dbg ...) und wuerden
|
||||
;; das Protokoll mitten im Test umlenken. Jede Zeile wird SOFORT angehaengt
|
||||
;; (kein Puffer) - haengt ein Test, steht der letzte erreichte Schritt drin.
|
||||
(if (not (boundp '*testrun-log*)) (setq *testrun-log* nil))
|
||||
|
||||
(defun testrun:log-start (name / dir fh)
|
||||
(setq *testrun-log* nil)
|
||||
(if (and (car (atoms-family 1 '("DBG-SCHALTER-P"))) (dbg-schalter-p "testlauf"))
|
||||
(progn
|
||||
(setq dir (cond ((getenv "DXFM_LOG")) ((strcat (getenv "DXFMAKRO") "/logs"))))
|
||||
(vl-mkdir dir)
|
||||
(setq *testrun-log* (strcat dir "/testlauf_" name ".dbg"))
|
||||
(if (setq fh (open *testrun-log* "w"))
|
||||
(progn (write-line (strcat "=== TESTLAUF " name " ===") fh) (close fh))
|
||||
(setq *testrun-log* nil))))
|
||||
*testrun-log*)
|
||||
|
||||
(defun testrun:log (text / fh)
|
||||
(if (and *testrun-log* (setq fh (open *testrun-log* "a")))
|
||||
(progn
|
||||
(write-line (strcat (if (car (atoms-family 1 '("DBG-TIMESTAMP"))) (dbg-timestamp) "")
|
||||
" " text)
|
||||
fh)
|
||||
(close fh)))
|
||||
(princ))
|
||||
|
||||
;; Schalter, die in einem Testlauf eine Rueckfrage ausloesen koennen.
|
||||
(defun testrun:zustand ()
|
||||
(strcat "GUI=" (if (and (boundp '*ssg-gui-aus*) *ssg-gui-aus*) "aus" "AN")
|
||||
" hoehencheck-fragen=" (vl-princ-to-string (if (boundp '*csv-hoehencheck-fragen*) *csv-hoehencheck-fragen*))
|
||||
" bereinigen=" (vl-princ-to-string (if (boundp '*csv-bereinigen-vor-export*) *csv-bereinigen-vor-export*))
|
||||
" wizard=" (vl-princ-to-string (if (boundp '*vfl-wizard-mode*) *vfl-wizard-mode*))
|
||||
" DWGNAME=" (getvar "DWGNAME")))
|
||||
|
||||
;; Dateiname ohne fuehrenden Praefix (sonst unveraendert). Gegenstueck zu
|
||||
;; export:dwg-praefix, den der Export selbst vor den Namen setzt.
|
||||
(defun testrun:ohne-praefix (dateiname praefix)
|
||||
(if (and praefix
|
||||
(/= praefix "")
|
||||
(> (strlen dateiname) (strlen praefix))
|
||||
(= (strcase (substr dateiname 1 (strlen praefix))) (strcase praefix)))
|
||||
(substr dateiname (1+ (strlen praefix)))
|
||||
dateiname))
|
||||
|
||||
(defun alltests:get-str(obj-str key / pat pos val-start val-end val)
|
||||
(setq pat (strcat "\"" key "\": \""))
|
||||
(setq pos (vl-string-search pat obj-str))
|
||||
(if pos
|
||||
@@ -151,7 +200,8 @@
|
||||
namen befehl datei export-fn new-doc
|
||||
out-path dwg-pfad dxf-pfad old-json test-result
|
||||
old-filenames csv-name sivas-name csv-pfad
|
||||
sivas-pfad csv-ok sivas-ok old-filedia)
|
||||
sivas-pfad csv-ok sivas-ok old-filedia
|
||||
praefix old-hoehencheck old-bereinigen)
|
||||
|
||||
(setq tests-pfad (strcat (getenv "DXFMAKRO") "/tests"))
|
||||
(setq tests-out-dir (strcat tests-pfad "/output"))
|
||||
@@ -209,6 +259,13 @@
|
||||
;; oeffnet DCL-/Wizard-Dialoge, die den automatischen Lauf blockieren wuerden.
|
||||
;; Am Ende wieder einschalten. Siehe ssg-gui-aus/-an in ssg_core.lsp.
|
||||
(if (car (atoms-family 1 '("SSG-GUI-AUS"))) (ssg-gui-aus))
|
||||
;; Rueckfragen des Exports (export.lsp) fuer den ganzen Lauf abschalten -
|
||||
;; zusaetzlich zur GUI-Sperre, damit auch ein Test, der die GUI wieder
|
||||
;; einschaltet, den Export nicht anhalten kann.
|
||||
(setq old-hoehencheck (if (boundp '*csv-hoehencheck-fragen*) *csv-hoehencheck-fragen*)
|
||||
old-bereinigen (if (boundp '*csv-bereinigen-vor-export*) *csv-bereinigen-vor-export*))
|
||||
(setq *csv-hoehencheck-fragen* nil
|
||||
*csv-bereinigen-vor-export* 'aus)
|
||||
|
||||
;; Tests laden und ausfuehren
|
||||
;; Jeder Test bekommt eine eigene neue Zeichnung (statt die aktuelle
|
||||
@@ -261,11 +318,25 @@
|
||||
(setq modelspace (vla-get-modelspace new-doc))
|
||||
;; Block-Library-Flag zuruecksetzen (Bloecke sind pro Zeichnung neu zu laden)
|
||||
(setq *lib-initialized* nil)
|
||||
;; Nummernzaehler zuruecksetzen: der Lauf bleibt im LISP-Namensraum des
|
||||
;; Startdokuments, die Zaehler (max aus Zeichnung UND Zaehler, +1) liefen
|
||||
;; sonst ueber alle Tests weiter - VF_5/Kreisel12 statt VF_1/Kreisel1 in
|
||||
;; einer frischen Zeichnung, die Namen hingen damit von der
|
||||
;; Testreihenfolge ab und jeder Referenz-Diff wurde unruhig.
|
||||
(setq #VF_LetzteNr 0 #GF_LetzteNr 0 #Kreisel_LetzteNr 0 #Eckrad_LetzteNr 0)
|
||||
|
||||
(testrun:log-start name)
|
||||
(testrun:log (strcat "Test " (itoa idx) "/" (itoa anz) ": " befehl
|
||||
" Modul=" (if module module "-")
|
||||
" save=" (if save-fmt save-fmt "-")
|
||||
" Modus=" (if auto-export "Automatik" "Kontrolle")))
|
||||
(testrun:log (strcat "Vor Test: " (testrun:zustand)))
|
||||
|
||||
(if (findfile datei)
|
||||
(progn
|
||||
(load datei)
|
||||
;; Test mit Fehlerbehandlung ausfuehren
|
||||
(testrun:log (strcat "Starte " befehl))
|
||||
(setq test-result
|
||||
(vl-catch-all-apply
|
||||
'(lambda ()
|
||||
@@ -275,12 +346,18 @@
|
||||
)
|
||||
)
|
||||
(if (vl-catch-all-error-p test-result)
|
||||
(princ (strcat "\n FEHLER in " befehl ": "
|
||||
(vl-catch-all-error-message test-result)))
|
||||
)
|
||||
(progn
|
||||
(princ (strcat "\n FEHLER in " befehl ": "
|
||||
(vl-catch-all-error-message test-result)))
|
||||
(testrun:log (strcat "FEHLER in " befehl ": "
|
||||
(vl-catch-all-error-message test-result))))
|
||||
(testrun:log (strcat befehl " beendet")))
|
||||
(testrun:log (strcat "Nach Test: " (testrun:zustand)))
|
||||
|
||||
;; JSON-Export (immer)
|
||||
(apply export-fn (list tests-out-dir))
|
||||
(testrun:log (strcat "Ergebnis-JSON " name "_results.json: "
|
||||
(if (findfile old-json) "vorhanden" "FEHLT")))
|
||||
|
||||
(setq out-path (strcat tests-out-dir "/" name "_tests"))
|
||||
|
||||
@@ -328,31 +405,59 @@
|
||||
;; Nur die beiden CSV-Namen ersetzen, alle uebrigen Keys
|
||||
;; (z.B. kreisel_weichen_datei) unveraendert uebernehmen -
|
||||
;; eine hart nachgebaute Liste verliert sonst neue Keys.
|
||||
;; Nach vla-saveas (save "dwg") ist die Zeichnung benannt
|
||||
;; (DWGTITLED=1, DWGNAME=<name>_tests.dwg), und der Export
|
||||
;; setzt selbst "<name>_tests_" davor (export:dwg-praefix).
|
||||
;; Diesen Praefix hier abziehen, sonst entsteht
|
||||
;; "<name>_tests_<name>_tests_export.csv" und das Warten auf
|
||||
;; csv-pfad laeuft ins Timeout. DXFOUT benennt die Zeichnung
|
||||
;; nicht um -> Praefix leer, Name bleibt vollstaendig.
|
||||
(setq praefix (export:dwg-praefix))
|
||||
(setq old-filenames *export-filenames*)
|
||||
(setq *export-filenames*
|
||||
(mapcar
|
||||
'(lambda (p)
|
||||
(cond ((= (car p) "sivas_csv") (cons "sivas_csv" sivas-name))
|
||||
((= (car p) "csv_csv") (cons "csv_csv" csv-name))
|
||||
(cond ((= (car p) "sivas_csv")
|
||||
(cons "sivas_csv" (testrun:ohne-praefix sivas-name praefix)))
|
||||
((= (car p) "csv_csv")
|
||||
(cons "csv_csv" (testrun:ohne-praefix csv-name praefix)))
|
||||
(T p)))
|
||||
old-filenames))
|
||||
|
||||
;; Unmittelbar vor dem Export erneut erzwingen: export.lsp setzt
|
||||
;; *csv-hoehencheck-fragen* beim (Nach-)Laden von nil auf T, und
|
||||
;; ein Test kann die GUI wieder eingeschaltet haben.
|
||||
(if (not (and (boundp '*ssg-gui-aus*) *ssg-gui-aus*))
|
||||
(progn
|
||||
(testrun:log "WARNUNG: GUI war nach dem Test wieder AN - fuer den Export abgeschaltet")
|
||||
(princ "\n WARNUNG: GUI war nach dem Test wieder an - abgeschaltet.")
|
||||
(ssg-gui-aus)))
|
||||
(setq *csv-hoehencheck-fragen* nil
|
||||
*csv-bereinigen-vor-export* 'aus)
|
||||
(testrun:log (strcat "Vor Export: " (testrun:zustand)))
|
||||
|
||||
(princ (strcat "\n CSV-Export -> " csv-name))
|
||||
(testrun:log (strcat "EXPORTCSV -> " csv-pfad))
|
||||
(c:EXPORTCSV)
|
||||
(setq csv-ok (testrun:wait-for-file csv-pfad 30.0))
|
||||
(princ (if csv-ok "\n CSV OK" "\n CSV TIMEOUT/FEHLER"))
|
||||
(testrun:log (if csv-ok "EXPORTCSV OK" "EXPORTCSV TIMEOUT/FEHLER - Datei nicht entstanden"))
|
||||
|
||||
(princ (strcat "\n Sivas-Export -> " sivas-name))
|
||||
(testrun:log (strcat "EXPORTSIVAS -> " sivas-pfad))
|
||||
(c:EXPORTSIVAS)
|
||||
(setq sivas-ok (testrun:wait-for-file sivas-pfad 30.0))
|
||||
(princ (if sivas-ok "\n Sivas OK" "\n Sivas TIMEOUT/FEHLER"))
|
||||
(testrun:log (if sivas-ok "EXPORTSIVAS OK" "EXPORTSIVAS TIMEOUT/FEHLER - Datei nicht entstanden"))
|
||||
|
||||
(setq *export-filenames* old-filenames)
|
||||
|
||||
;; Zeichnung schliessen: der urspruenglich schon offene Tab
|
||||
;; bleibt unangetastet, BricsCAD erzeugt daher kein neues
|
||||
;; Blank-Dokument samt Modul-/Menue-Reload.
|
||||
(testrun:log "Zeichnung schliessen")
|
||||
(vla-close new-doc :vlax-false)
|
||||
(testrun:log "Test fertig")
|
||||
)
|
||||
|
||||
;; ==========================================================
|
||||
@@ -414,7 +519,9 @@
|
||||
)
|
||||
)
|
||||
)
|
||||
(princ (strcat "\n WARNUNG: " datei " nicht gefunden - uebersprungen"))
|
||||
(progn
|
||||
(princ (strcat "\n WARNUNG: " datei " nicht gefunden - uebersprungen"))
|
||||
(testrun:log (strcat "WARNUNG: " datei " nicht gefunden - uebersprungen")))
|
||||
)
|
||||
) ;; end (progn ...) des aktiven Zweigs
|
||||
) ;; end (if (cdr (assoc "disabled" entry)) ...)
|
||||
@@ -422,6 +529,10 @@
|
||||
|
||||
;; GUI wieder einschalten (Batch fertig).
|
||||
(if (car (atoms-family 1 '("SSG-GUI-AN"))) (ssg-gui-an))
|
||||
;; nil = "nie gesetzt" (export.lsp belegt dann mit der Vorgabe vor)
|
||||
(setq *csv-hoehencheck-fragen* (if old-hoehencheck old-hoehencheck T)
|
||||
*csv-bereinigen-vor-export* (if old-bereinigen old-bereinigen 'an))
|
||||
(setq *testrun-log* nil)
|
||||
|
||||
(setq *export-test-override* nil)
|
||||
|
||||
|
||||
+762
-2
@@ -399,6 +399,342 @@
|
||||
)
|
||||
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; TESTS: vf_linienzug.lsp - "Parallel zum Kreisel" (Rechenkerne)
|
||||
;; ------------------------------------------------------------
|
||||
;; Die Bau-Funktion vfl-gf-parallel-kreisel braucht eine Zeichnung (sie misst
|
||||
;; AS und Bogen an echten Bloecken); ihre beiden Rechenkerne sind davon frei
|
||||
;; und stehen deshalb hier:
|
||||
;; vfl-par-bogen-waehlen - welcher Bogen hebt den AS-Schwenk auf?
|
||||
;; vfl-par-gf-laenge - wie lang wird das GF-Stueck dazwischen?
|
||||
;; Die Plan-Turn-Werte unten sind die Vorzeichen-Konvention aus
|
||||
;; vf-element-plan-turn (KS_EIN -> KS_AUS in der XY-Ebene, links positiv).
|
||||
(defun tu-tests-vfl-parallel ( / _b30 _b60 _b90 _kand _l _plan _plan3 _g _p _w _ez _plan2)
|
||||
(princ "\n[vf_linienzug Parallel zum Kreisel]")
|
||||
|
||||
;; --- Bogenwahl: der Bogen muss den AS-Schwenk GENAU aufheben ---
|
||||
;; Rechts-Boegen schwenken negativ, Links-Boegen positiv.
|
||||
(setq _b30 '(30 . -30.0) _b60 '(60 . -60.0) _b90 '(90 . -90.0))
|
||||
(setq _kand (list _b30 _b60 _b90))
|
||||
;; AS links 30 Grad (Schwenk +30) -> 30-Grad-Bogen nach rechts
|
||||
(tu-eq "vfl-par-bogen/as30-rechts" 30 (vfl-par-bogen-waehlen 30.0 _kand 2.0))
|
||||
;; AS links 90 Grad (Schwenk +90) -> 90-Grad-Bogen nach rechts
|
||||
(tu-eq "vfl-par-bogen/as90-rechts" 90 (vfl-par-bogen-waehlen 90.0 _kand 2.0))
|
||||
;; Generisch: auch ein 60-Grad-Schwenk findet seinen Bogen - die Zuordnung
|
||||
;; folgt den gemessenen Bloecken, nicht einer gepflegten Tabelle.
|
||||
(tu-eq "vfl-par-bogen/as60-rechts" 60 (vfl-par-bogen-waehlen 60.0 _kand 2.0))
|
||||
;; kleine Messabweichung bleibt in der Toleranz
|
||||
(tu-eq "vfl-par-bogen/toleranz-ok" 30 (vfl-par-bogen-waehlen 31.2 _kand 2.0))
|
||||
;; ausserhalb der Toleranz: lieber nil als ein schiefer Bogen
|
||||
(tu-nil "vfl-par-bogen/zu-weit-weg" (vfl-par-bogen-waehlen 45.0 _kand 2.0))
|
||||
(tu-nil "vfl-par-bogen/leere-liste" (vfl-par-bogen-waehlen 30.0 '() 2.0))
|
||||
;; Gegenseite: Links-Boegen heben einen negativen AS-Schwenk auf
|
||||
(setq _kand (list '(30 . 30.0) '(60 . 60.0) '(90 . 90.0)))
|
||||
(tu-eq "vfl-par-bogen/as-rechts30-links" 30 (vfl-par-bogen-waehlen -30.0 _kand 2.0))
|
||||
|
||||
;; --- GF-Laenge: abstand = perp-as + L*k + perp-bogen ---
|
||||
;; Glatter Fall: k = 1 (AS schwenkt 90 Grad aus der Achse), feste Anteile
|
||||
;; zusammen 500 -> fuer 2000 mm Abstand bleiben 1500 mm GF.
|
||||
(tu-eqf "vfl-par-laenge/k1" 1500.0 (vfl-par-gf-laenge 2000.0 200.0 300.0 1.0))
|
||||
;; Gegenseite: k negativ -> der Abstand zaehlt auf der anderen Seite, der
|
||||
;; Betrag der Eingabe bleibt derselbe (Seite kommt aus der AS-Variante).
|
||||
(tu-eqf "vfl-par-laenge/k-negativ" 1500.0
|
||||
(vfl-par-gf-laenge 2000.0 -200.0 -300.0 -1.0))
|
||||
;; Schraege Ausschleusung: k = sin(60 Grad)
|
||||
(setq _l (vfl-par-gf-laenge 2000.0 0.0 0.0 (sin (/ (* 60.0 pi) 180.0))))
|
||||
(tu-eqf "vfl-par-laenge/k-sin60" (/ 2000.0 (sin (/ (* 60.0 pi) 180.0))) _l)
|
||||
;; Abstand kleiner als der feste Anteil -> negative Laenge (der Aufrufer
|
||||
;; meldet das als "Abstand zu klein", die Rechnung selbst raet nicht).
|
||||
(tu-true "vfl-par-laenge/zu-klein-negativ"
|
||||
(< (vfl-par-gf-laenge 100.0 200.0 300.0 1.0) 0.0))
|
||||
;; AS schwenkt gar nicht aus der Achse -> keine Loesung
|
||||
(tu-nil "vfl-par-laenge/kein-versatz" (vfl-par-gf-laenge 2000.0 0.0 0.0 0.0))
|
||||
|
||||
;; --- Grenzen einer VF-Einheit (Modus 2) ---
|
||||
;; Zwischen Umlenk- und Motorstation: hoechstens 2 Vario-Kurven und 25 m.
|
||||
;; Plan-Eintraege: ("Linie" hz laenge ...) / ("Bogen" hz chord ...) - nur
|
||||
;; Typ und Laenge (3. Feld) zaehlen hier.
|
||||
(setq _plan (list '("Linie" 0.0 9000.0 "VF") '("Bogen" 0.0 500.0)
|
||||
'("Linie" 0.0 8000.0 "VF") '("Bogen" 0.0 500.0)
|
||||
'("Linie" 0.0 6000.0 "VF")))
|
||||
;; 24000 mm, 2 Kurven -> alles im Rahmen
|
||||
(setq _g (vfl-m2-lauf-grenzen _plan 0 4 25000.0 2))
|
||||
(tu-eqf "vfl-m2-grenzen/laenge" 24000.0 (nth 0 _g))
|
||||
(tu-eq "vfl-m2-grenzen/kurven" 2 (nth 1 _g))
|
||||
(tu-nil "vfl-m2-grenzen/ok" (nth 2 _g))
|
||||
;; Dritte Kurve -> an ihr (Index 5) teilen, obwohl die Laenge noch passt
|
||||
(setq _plan3 (append _plan (list '("Bogen" 0.0 400.0) '("Linie" 0.0 300.0 "VF"))))
|
||||
(tu-eq "vfl-m2-grenzen/dritte-kurve" 5 (nth 2 (vfl-m2-lauf-grenzen _plan3 0 6 25000.0 2)))
|
||||
;; Zu lang -> am ersten Bogen teilen, nach dem die Grenze reisst (Index 3:
|
||||
;; bis dahin sind 9000+500+8000 = 17500 drin, die Grenze liegt bei 15000).
|
||||
(tu-eq "vfl-m2-grenzen/zu-lang" 3 (nth 2 (vfl-m2-lauf-grenzen _plan 0 4 15000.0 2)))
|
||||
;; Eine einzige lange Gerade: zu lang, aber kein Bogen zum Teilen -> -1
|
||||
(tu-eq "vfl-m2-grenzen/unteilbar" -1
|
||||
(nth 2 (vfl-m2-lauf-grenzen (list '("Linie" 0.0 30000.0 "VF")) 0 0 25000.0 2)))
|
||||
|
||||
;; --- Vorgabewert aus einem Prompt ziehen (Dialog-Feld vorbelegen) ---
|
||||
;; Die Konsolen-Prompts tragen ihre Vorgabe in Klammern; der Zahlen-Dialog
|
||||
;; liest sie daraus. Gesucht ist die LETZTE Klammergruppe MIT Zahl - die
|
||||
;; echten Texte enthalten davor "<" ohne Partner ("0 < Winkel <= 3") und
|
||||
;; runde Klammern mit Fliesstext, beides darf nicht stoeren.
|
||||
(tu-eq "vflw-vorgabe/neigungswinkel" "3"
|
||||
(vflw-vorgabe-aus-prompt "\nNeigungswinkel (Grad, 0 < Winkel <= 3) [3]: "))
|
||||
(tu-eq "vflw-vorgabe/neigungswinkel-berechnet" "3"
|
||||
(vflw-vorgabe-aus-prompt
|
||||
"\nNeigungswinkel (Grad, 0 < Winkel <= 3) [3] (deltaL wird berechnet und eingefuegt): "))
|
||||
(tu-eq "vflw-vorgabe/spitze-klammer" "2154.0"
|
||||
(vflw-vorgabe-aus-prompt "\nGewuenschte Hoehe am Kettenanfang (mm) <2154.0>: "))
|
||||
(tu-eq "vflw-vorgabe/negativ" "-12.5"
|
||||
(vflw-vorgabe-aus-prompt "Hoehendifferenz <-12.5>: "))
|
||||
;; Ohne Klammergruppe bleibt das Feld leer (nil), nicht geraten.
|
||||
(tu-nil "vflw-vorgabe/ohne-vorgabe"
|
||||
(vflw-vorgabe-aus-prompt "\nAbstand zum Kreisel (mm, senkrecht zur Achse): "))
|
||||
(tu-nil "vflw-vorgabe/keine-zahl"
|
||||
(vflw-vorgabe-aus-prompt "Bitte Namen eingeben [frei]: "))
|
||||
|
||||
;; --- Modus-2-Lauf-Anfang: Journal-Wert normieren ---
|
||||
;; Die Antwort wird als selbstbeschreibender Wert gefuehrt, damit ein
|
||||
;; Umsortieren/Umnummerieren der Optionen bestehende Ketten nicht
|
||||
;; umdeutet. Alte Ketten tragen dort noch die Ziffern der ALTEN Folge -
|
||||
;; die Zuordnung dafuer steht als Tabelle in *vfl-m2-anfang-alt* und wird
|
||||
;; hier komplett durchlaufen, statt einzelne Faelle abzuschreiben.
|
||||
(foreach _p *vfl-m2-anfang-alt*
|
||||
(tu-eq (strcat "vfl-m2-anfang/alt-" (car _p))
|
||||
(cdr _p) (vfl-m2-anfang-norm (car _p))))
|
||||
;; Jeder Tabellenwert muss auch ein gueltiger heutiger Wert sein - sonst
|
||||
;; laeuft eine Alt-Kette in den Unbekannt-Abbruch.
|
||||
(foreach _p *vfl-m2-anfang-alt*
|
||||
(tu-true (strcat "vfl-m2-anfang/alt-ziel-gueltig-" (car _p))
|
||||
(and (member (cdr _p) *vfl-m2-anfang-werte*) t)))
|
||||
;; Neue Werte gehen unveraendert durch.
|
||||
(foreach _w *vfl-m2-anfang-werte*
|
||||
(tu-eq (strcat "vfl-m2-anfang/neu-" _w) _w (vfl-m2-anfang-norm _w)))
|
||||
;; Unbekanntes wird NICHT geraten - nil heisst fuer den Aufrufer Abbruch.
|
||||
(tu-nil "vfl-m2-anfang/unbekannte-ziffer" (vfl-m2-anfang-norm "4"))
|
||||
(tu-nil "vfl-m2-anfang/leer" (vfl-m2-anfang-norm ""))
|
||||
(tu-nil "vfl-m2-anfang/tippfehler" (vfl-m2-anfang-norm "mit_gf1"))
|
||||
(tu-nil "vfl-m2-anfang/kein-string" (vfl-m2-anfang-norm 3))
|
||||
(tu-nil "vfl-m2-anfang/nil" (vfl-m2-anfang-norm nil))
|
||||
|
||||
;; --- Eck-Korrektur: gezeichneter Bogen gegen Eck-Bauteil ---
|
||||
;; Die Ecke des Pfads wird durch ein reales Bauteil ersetzt, dessen
|
||||
;; Fussabdruck abweichen darf. Die Differenz wird auf die Richtungen der
|
||||
;; beiden angrenzenden Geraden zerlegt. Werte aus dem echten Lauf vom
|
||||
;; 2026-10-26: 90-Grad-Ecke, Pfad R500 (Sehne 707.1 -> 500/-500), gebaute
|
||||
;; Vario-Kurve wirkt wie R406.2 -> je 93.78 mm auf beide Nachbargeraden.
|
||||
(setq _ez (vfl-eck-zerlegen 500.0 -500.0 406.22 -406.22 (- (/ pi 2.0))))
|
||||
(tu-eqf "vfl-eck-zerlegen/90-grad-davor" 93.78 (car _ez))
|
||||
(tu-eqf "vfl-eck-zerlegen/90-grad-danach" 93.78 (cadr _ez))
|
||||
;; 30-Grad-Ecke links, Gefaellebogen R500 trifft den Pfad fast exakt:
|
||||
;; nur 0.85 mm, und zwar ausschliesslich auf der Geraden DAVOR.
|
||||
(setq _ez (vfl-eck-zerlegen 250.0 66.99 249.15 66.99 (/ pi 6.0)))
|
||||
(tu-eqf "vfl-eck-zerlegen/30-grad-davor" 0.85 (car _ez))
|
||||
(tu-eqf "vfl-eck-zerlegen/30-grad-danach" 0.0 (cadr _ez))
|
||||
;; Deckungsgleiches Bauteil -> kein Zuschlag auf keiner Seite.
|
||||
(setq _ez (vfl-eck-zerlegen 500.0 -500.0 500.0 -500.0 (- (/ pi 2.0))))
|
||||
(tu-eqf "vfl-eck-zerlegen/gleich-davor" 0.0 (car _ez))
|
||||
(tu-eqf "vfl-eck-zerlegen/gleich-danach" 0.0 (cadr _ez))
|
||||
;; Ohne Schwenk ist die Zerlegung nicht eindeutig - nil statt Division durch 0.
|
||||
(tu-nil "vfl-eck-zerlegen/ohne-schwenk"
|
||||
(vfl-eck-zerlegen 100.0 0.0 90.0 0.0 0.0))
|
||||
;; GF-Boegen werden GENEIGT eingebaut: ihr Grundriss-Fussabdruck ist kuerzer
|
||||
;; als flach gemessen, und genau diese Differenz muss in die Eck-Korrektur.
|
||||
;; Werte aus dem echten Lauf 2026-10-26: Gefaellebogen_rechts_90_R500 flach
|
||||
;; dx=500 dz=-28.6, bei 3 Grad eingebaut 497.8 - die 2.2 mm blieben vorher
|
||||
;; als Rest am Kettenende stehen. Negatives dz muss dabei VERKUERZEN.
|
||||
(tu-eqf "vfl-projiziere-neigung/gf-bogen-3-grad"
|
||||
(- (* 500.0 (cos (* 3.0 (/ pi 180.0))))
|
||||
(* 28.6 (sin (* 3.0 (/ pi 180.0)))))
|
||||
(car (vfl-projiziere-neigung 500.0 -28.6 3.0)))
|
||||
(tu-true "vfl-projiziere-neigung/gf-bogen-kuerzer-als-flach"
|
||||
(< (car (vfl-projiziere-neigung 500.0 -28.6 3.0)) 500.0))
|
||||
;; Waagerecht eingebaut (Vario-Kurve) bleibt der Fussabdruck unveraendert.
|
||||
(tu-eqf "vfl-projiziere-neigung/waagerecht" 500.0
|
||||
(car (vfl-projiziere-neigung 500.0 -28.6 0.0)))
|
||||
|
||||
;; --- Bau-Funktion aus dem Journal ableiten (vf_spec.lsp) ---
|
||||
;; vsp-bau-journal waehlt die Modus-Funktion anhand des Journals, statt sie
|
||||
;; als zusaetzliches Argument zu bekommen (exakte Argumentzahl, siehe
|
||||
;; CLAUDE.md). Kein SEGS = Modus 1; SEGS mit der Formatmarke "m2v2" =
|
||||
;; Modus 2 (nur vf-linienzug-modus2 schreibt sie); SEGS ohne = Modus 3.
|
||||
(tu-true "vsp-bau-fn/ohne-segs-ist-modus1"
|
||||
(eq (vsp-bau-fn-fuer-journal
|
||||
(list (cons "PT" '(0.0 0.0 0.0)) (cons "STR" "1")))
|
||||
'vf-linienzug-modus))
|
||||
(tu-true "vsp-bau-fn/segs-mit-marke-ist-modus2"
|
||||
(eq (vsp-bau-fn-fuer-journal
|
||||
(list (cons "PT" '(0.0 0.0 0.0)) (cons "SEGS" '(("Linie")))
|
||||
(cons "STR" "m2v2") (cons "STR" "2")))
|
||||
'vf-linienzug-modus2))
|
||||
(tu-true "vsp-bau-fn/segs-ohne-marke-ist-modus3"
|
||||
(eq (vsp-bau-fn-fuer-journal
|
||||
(list (cons "PT" '(0.0 0.0 0.0)) (cons "SEGS" '(("Linie")))
|
||||
(cons "STR" "2")))
|
||||
'vf-linienzug-modus3))
|
||||
;; Die Marke zaehlt nur als STR-Eintrag - ein gleichlautender Wert in einem
|
||||
;; anderen Eintragstyp darf nicht faelschlich auf Modus 2 schliessen lassen.
|
||||
(tu-true "vsp-bau-fn/marke-nur-als-str"
|
||||
(eq (vsp-bau-fn-fuer-journal
|
||||
(list (cons "SEGS" '(("Linie"))) (cons "INT" "m2v2")))
|
||||
'vf-linienzug-modus3))
|
||||
|
||||
;; --- Segment-Klassifizierung: Wert statt Menue-Ziffer ---
|
||||
;; Gemeinsamer Normalisierer fuer alle selbstbeschreibenden Antworten.
|
||||
;; Bestandsketten tragen die Alt-Ziffer, neue Ketten den Wert; beide Mengen
|
||||
;; sind disjunkt. Unbekanntes gibt nil - der Aufrufer bricht dann ab.
|
||||
(foreach _p *vfl-m2-linie-alt*
|
||||
(tu-eq (strcat "vfl-wert-norm/linie-alt-" (car _p)) (cdr _p)
|
||||
(vfl-wert-norm (car _p) *vfl-m2-linie-werte* *vfl-m2-linie-alt*)))
|
||||
(foreach _p *vfl-m2-bogen-alt*
|
||||
(tu-eq (strcat "vfl-wert-norm/bogen-alt-" (car _p)) (cdr _p)
|
||||
(vfl-wert-norm (car _p) *vfl-m2-bogen-werte* *vfl-m2-bogen-alt*)))
|
||||
(foreach _p *vfl-m2-variante-alt*
|
||||
(tu-eq (strcat "vfl-wert-norm/variante-alt-" (car _p)) (cdr _p)
|
||||
(vfl-wert-norm (car _p) *vfl-m2-variante-werte* *vfl-m2-variante-alt*)))
|
||||
;; Neue Werte gehen unveraendert durch.
|
||||
(foreach _w *vfl-m2-bogen-werte*
|
||||
(tu-eq (strcat "vfl-wert-norm/bogen-neu-" _w) _w
|
||||
(vfl-wert-norm _w *vfl-m2-bogen-werte* *vfl-m2-bogen-alt*)))
|
||||
;; Jeder Alt-Zielwert muss ein gueltiger heutiger Wert sein, sonst laeuft
|
||||
;; eine Bestandskette in den Unbekannt-Abbruch.
|
||||
(foreach _p *vfl-m2-linie-alt*
|
||||
(tu-true (strcat "vfl-wert-norm/linie-ziel-gueltig-" (car _p))
|
||||
(and (member (cdr _p) *vfl-m2-linie-werte*) t)))
|
||||
;; Typ und Variante benutzten frueher BEIDE "1"/"2" und waren im Journal
|
||||
;; nicht zu unterscheiden - die neuen Wertevorraete muessen disjunkt sein.
|
||||
(tu-nil "vfl-wert-norm/bogen-und-variante-disjunkt"
|
||||
(vl-some (function (lambda (w) (if (member w *vfl-m2-variante-werte*) w)))
|
||||
*vfl-m2-bogen-werte*))
|
||||
(tu-nil "vfl-wert-norm/unbekannt-gibt-nil"
|
||||
(vfl-wert-norm "3" *vfl-m2-linie-werte* *vfl-m2-linie-alt*))
|
||||
(tu-nil "vfl-wert-norm/kein-string"
|
||||
(vfl-wert-norm 1 *vfl-m2-linie-werte* *vfl-m2-linie-alt*))
|
||||
|
||||
;; --- Gefalteter VF-Lauf erkennen (Schenkel = Fahrtrichtungen) ---
|
||||
;; Der Modus-2-Solver bilanziert skalar ueber EINE Achse. Liegt der Lauf
|
||||
;; gefaltet (U-Form), sitzen die festen Teile in einem anderen Schenkel als
|
||||
;; die Kletterstrecke und die Kette wird sichtbar falsch gebaut. Bis die
|
||||
;; Bilanz achsenweise rechnet, wird so ein Lauf abgewiesen - diese
|
||||
;; Erkennung entscheidet darueber.
|
||||
;; Plan-Eintraege: Linie = ("Linie" hz laenge typ ...), Bogen = ("Bogen" hz ...)
|
||||
(setq _plan2 (list (list "Linie" 0.0 9700.0 "VF" nil)
|
||||
(list "Bogen" 0.0 707.1 90 "rechts" "Vario-Kurve" "aussen")
|
||||
(list "Linie" -90.0 4296.0 "VF" nil)))
|
||||
(tu-eq "vfl-m2-schenkel/u-form-zwei-richtungen" 2
|
||||
(length (vfl-m2-schenkel _plan2 0 2)))
|
||||
(tu-true "vfl-m2-gefaltet/u-form" (vfl-m2-gefaltet-p _plan2 0 2))
|
||||
;; Gerader Lauf: eine Richtung, auch ueber mehrere Geraden hinweg.
|
||||
(setq _plan2 (list (list "Linie" 0.0 9700.0 "VF" nil)
|
||||
(list "Linie" 0.0 2000.0 "VF" nil)))
|
||||
(tu-eq "vfl-m2-schenkel/gerade-eine-richtung" 1
|
||||
(length (vfl-m2-schenkel _plan2 0 1)))
|
||||
(tu-nil "vfl-m2-gefaltet/gerade" (vfl-m2-gefaltet-p _plan2 0 1))
|
||||
;; Zurueck auf dieselbe Richtung zaehlt als NEUER Schenkel - die Kette ist
|
||||
;; dann seitlich versetzt, die Laengen liegen nicht mehr auf einer Linie.
|
||||
(setq _plan2 (list (list "Linie" 0.0 3000.0 "VF" nil)
|
||||
(list "Bogen" 0.0 707.1 90 "rechts" "Vario-Kurve" "aussen")
|
||||
(list "Linie" -90.0 1000.0 "VF" nil)
|
||||
(list "Bogen" -90.0 707.1 90 "links" "Vario-Kurve" "aussen")
|
||||
(list "Linie" 0.0 3000.0 "VF" nil)))
|
||||
(tu-eq "vfl-m2-schenkel/u-form-drei" 3
|
||||
(length (vfl-m2-schenkel _plan2 0 4)))
|
||||
;; Winkel werden normalisiert: 270 und -90 sind dieselbe Richtung.
|
||||
(setq _plan2 (list (list "Linie" -90.0 1000.0 "VF" nil)
|
||||
(list "Linie" 270.0 1000.0 "VF" nil)))
|
||||
(tu-eq "vfl-m2-schenkel/270-gleich-minus90" 1
|
||||
(length (vfl-m2-schenkel _plan2 0 1)))
|
||||
|
||||
;; --- Eingangs-Hardware auf einem Fueller-Segment ---
|
||||
;; Steht der Lauf-Eingang (GF1 + Separator + Umlenkstation + Bogen) auf
|
||||
;; einem FUELLER, muss dessen Laenge abgezogen werden - sonst bekommt der
|
||||
;; Fueller die volle Restlaenge, als staende dort nichts (real 2026-10-27:
|
||||
;; 5855 mm Plan, 10668 mm belegt, Kette 8005 mm daneben).
|
||||
;; Ist das Eingangs-Segment selbst der Kletterer, steckt dieselbe Laenge
|
||||
;; schon in feste-vf - dann MUSS der Abzug 0 sein, sonst doppelt.
|
||||
(tu-eqf "vfl-m2-eingang-fp/kletterer-kein-abzug" 0.0
|
||||
(vfl-m2-eingang-fp 0 0 '(0) 3726.34 (* 3.0 (/ pi 180.0))))
|
||||
;; Anderes Segment als der Eingang: ebenfalls nichts.
|
||||
(tu-eqf "vfl-m2-eingang-fp/fremdes-segment" 0.0
|
||||
(vfl-m2-eingang-fp 2 0 '(2) 3726.34 (* 3.0 (/ pi 180.0))))
|
||||
;; Eingang ist Fueller (Kletterer liegt woanders): GF1 + 300 + 500,
|
||||
;; projiziert auf 3 Grad, plus der Uebergangsbogen aus der Tabelle.
|
||||
;; Die DIFFERENZ zweier Aufrufe prueft den GF-Anteil exakt und kommt ohne
|
||||
;; die Bogen-Tabelle aus - die ist im file-freien Unit-Test leer
|
||||
;; (init-bibliothek laeuft hier nicht), der Bogenanteil faellt also weg.
|
||||
;; Eine absolute Schranke waere dadurch umgebungsabhaengig gewesen.
|
||||
(tu-eqf "vfl-m2-eingang-fp/gf-anteil-exakt"
|
||||
(* 3726.34 (cos (* 3.0 (/ pi 180.0))))
|
||||
(- (vfl-m2-eingang-fp 0 0 '(2) 3726.34 (* 3.0 (/ pi 180.0)))
|
||||
(vfl-m2-eingang-fp 0 0 '(2) 0.0 (* 3.0 (/ pi 180.0)))))
|
||||
;; Separator + Umlenkstation sind IMMER dabei, auch ohne GF und ohne Tabelle.
|
||||
(setq _l (vfl-m2-eingang-fp 0 0 '(2) 0.0 (* 3.0 (/ pi 180.0))))
|
||||
(tu-true "vfl-m2-eingang-fp/stationen-immer-dabei"
|
||||
(>= _l (* (+ *vfk-separator-laenge* *vfk-stations-laenge*)
|
||||
(cos (* 3.0 (/ pi 180.0))))))
|
||||
|
||||
;; --- Fremdanteil der Gefaellestrecke (fuer den stillen Nachrechner) ---
|
||||
;; Wieviel der vom Solver berechneten GF liegt NICHT auf dem Schenkel des
|
||||
;; Kletterers? Nur das darf dessen Spanne wieder zugeschlagen werden.
|
||||
;; Liegt der Eingang auf dem Kletterer selbst (gerader Normalfall), ist
|
||||
;; nichts fremd - dann MUSS 0 herauskommen, sonst wuerde der funktionierende
|
||||
;; Fall veraendert.
|
||||
(tu-eqf "vfl-m2-gf-fremd/eingang-ist-kletterer" 0.0
|
||||
(vfl-m2-gf-fremdanteil 3726.34 1 T))
|
||||
(tu-eqf "vfl-m2-gf-fremd/alles-einlauf" 3726.34
|
||||
(vfl-m2-gf-fremdanteil 3726.34 1 nil))
|
||||
(tu-eqf "vfl-m2-gf-fremd/halb-halb" 1863.17
|
||||
(vfl-m2-gf-fremdanteil 3726.34 2 nil))
|
||||
;; Alles am Auslauf (Modus 3, erzwungen bei offenem Anfang): die GF liegt
|
||||
;; dann beim Kletterer, nichts ist fremd.
|
||||
(tu-eqf "vfl-m2-gf-fremd/alles-auslauf" 0.0
|
||||
(vfl-m2-gf-fremdanteil 3726.34 3 nil))
|
||||
|
||||
;; --- ES-Reservierung auf die KS_AUS-Achse ---
|
||||
;; Vorgabe: quer zur KS_AUS-Achse MUSS 0 sein, laengs darf abweichen.
|
||||
;; Der reine Laengsanteil reicht dafuer NICHT - er laesst den bauteileigenen
|
||||
;; Querversatz stehen. Werte aus dem echten Lauf 2026-10-26:
|
||||
;; ES_Element_30_rechts an einer Geraden mit hz=-60, Schwenk -30 Grad,
|
||||
;; Fussabdruck (laengs 575.84 | quer -52.54). Reserve 484.8 statt 575.8 -
|
||||
;; die Gerade wird also rund 91 mm laenger und hebt den Querversatz auf.
|
||||
(tu-eqf "vfl-es-achs-reserve/echt-30-grad" 484.838050570331
|
||||
(vfl-es-achs-reserve 575.84 -52.54 -60.0 -30.0))
|
||||
;; Ohne Querversatz bleibt es beim reinen Laengsanteil.
|
||||
(tu-eqf "vfl-es-achs-reserve/ohne-quer" 500.0
|
||||
(vfl-es-achs-reserve 500.0 0.0 -60.0 -30.0))
|
||||
;; Ohne Schwenk faellt die Achse mit der Fahrtrichtung zusammen - dann gibt
|
||||
;; es keinen aufhebbaren Querversatz und der Laengsanteil ist richtig
|
||||
;; (Nenner 0, Rueckfall statt Division durch null).
|
||||
(tu-eqf "vfl-es-achs-reserve/ohne-schwenk" 575.84
|
||||
(vfl-es-achs-reserve 575.84 -52.54 -60.0 0.0))
|
||||
;; Richtungsunabhaengig: dieselbe Geometrie um 90 Grad gedreht gibt
|
||||
;; denselben Wert - die Reserve haengt an den Winkeln zueinander, nicht
|
||||
;; an der Lage im Welt-KS.
|
||||
(tu-eqf "vfl-es-achs-reserve/gedreht" 484.838050570331
|
||||
(vfl-es-achs-reserve 575.84 -52.54 30.0 -30.0))
|
||||
|
||||
;; --- Rueckwaerts bauen: Punkt entgegen der Fahrtrichtung zuruecksetzen ---
|
||||
;; vfl-rueck-punkt ist der Rechenkern des Rueckwaerts-Baus: zu einem
|
||||
;; BEKANNTEN Endpunkt den Startpunkt eines Bausteins finden. Vorwaerts gilt
|
||||
;; P_next = P + (L*cos hz, L*sin hz, -L*tan w) - hier also mit umgekehrtem
|
||||
;; Vorzeichen. Die Hoehe muss STEIGEN (der Vorgaenger liegt hoeher).
|
||||
(tu-eqf "vfl-rueck-punkt/ost-flach"
|
||||
(list 0.0 0.0 0.0) (vfl-rueck-punkt '(1000.0 0.0 0.0) 0.0 1000.0 0.0))
|
||||
(tu-eqf "vfl-rueck-punkt/nord-flach"
|
||||
(list 0.0 0.0 0.0) (vfl-rueck-punkt '(0.0 1000.0 0.0) 90.0 1000.0 0.0))
|
||||
;; 45 Grad Gefaelle: 1000 mm horizontal zurueck = 1000 mm hoeher
|
||||
(tu-eqf "vfl-rueck-punkt/45-grad"
|
||||
(list 0.0 0.0 1000.0) (vfl-rueck-punkt '(1000.0 0.0 0.0) 0.0 1000.0 45.0))
|
||||
;; Rundlauf: vorwaerts wieder auf den Ausgangspunkt (3 Grad, schraeg)
|
||||
(setq _l (vfl-rueck-punkt '(5000.0 3000.0 1800.0) 30.0 2000.0 3.0))
|
||||
(tu-eqf "vfl-rueck-punkt/rundlauf-x" 5000.0
|
||||
(+ (car _l) (* 2000.0 (cos (/ (* 30.0 pi) 180.0)))))
|
||||
(tu-eqf "vfl-rueck-punkt/rundlauf-y" 3000.0
|
||||
(+ (cadr _l) (* 2000.0 (sin (/ (* 30.0 pi) 180.0)))))
|
||||
(tu-eqf "vfl-rueck-punkt/rundlauf-z" 1800.0
|
||||
(- (caddr _l) (* 2000.0 (/ (sin (/ (* 3.0 pi) 180.0)) (cos (/ (* 3.0 pi) 180.0))))))
|
||||
)
|
||||
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; TESTS: vf_linienzug.lsp - Laenge aus einer Ziellinie (X/Y)
|
||||
;; ------------------------------------------------------------
|
||||
@@ -446,6 +782,86 @@
|
||||
(+ (cadr _ks) (sin (/ pi 6.0))) 0.0)))
|
||||
(tu-true "vfl-laenge-bis-ziellinie/realfall-plausibel"
|
||||
(and _l (> _l 1430.0) (< _l 1431.0)))
|
||||
|
||||
;; --- AS-Seite aus der Lage des naechsten Punkts zur Basislinie ---
|
||||
;; Basislinie zeigt nach +X; ein Ziel mit +Y liegt links davon, mit -Y rechts.
|
||||
(tu-eq "vfl-seite-aus-lage/links"
|
||||
"links" (vfl-seite-aus-lage '(0.0 0.0 0.0) '(1000.0 0.0 0.0) '(500.0 800.0 0.0)))
|
||||
(tu-eq "vfl-seite-aus-lage/rechts"
|
||||
"rechts" (vfl-seite-aus-lage '(0.0 0.0 0.0) '(1000.0 0.0 0.0) '(500.0 -800.0 0.0)))
|
||||
;; Richtung der Basislinie umdrehen -> Seite dreht mit
|
||||
(tu-eq "vfl-seite-aus-lage/basislinie-umgedreht"
|
||||
"rechts" (vfl-seite-aus-lage '(1000.0 0.0 0.0) '(0.0 0.0 0.0) '(500.0 800.0 0.0)))
|
||||
;; schraege Basislinie (45 Grad): Ziel oberhalb davon liegt links
|
||||
(tu-eq "vfl-seite-aus-lage/schraeg"
|
||||
"links" (vfl-seite-aus-lage '(0.0 0.0 0.0) '(1000.0 1000.0 0.0) '(0.0 1000.0 0.0)))
|
||||
;; Z spielt keine Rolle (rein planare Entscheidung)
|
||||
(tu-eq "vfl-seite-aus-lage/z-ignoriert"
|
||||
"rechts" (vfl-seite-aus-lage '(0.0 0.0 5000.0) '(1000.0 0.0 -200.0) '(500.0 -800.0 999.0)))
|
||||
|
||||
;; --- VF-Hoehe je SEGMENT (Attribut VF_HOEHE_m, Sivas 4433-4437) ---
|
||||
;; Ein Eintrag je GERADEM VF-Abschnitt: Mittelwert aus dessen KS_EIN und
|
||||
;; KS_AUS, in METERN mit 3 Nachkommastellen. Zwischen Umlenk- und
|
||||
;; Motorstation koennen mehrere Abschnitte liegen (auf/ab/horizontal), die
|
||||
;; Liste laeuft darum parallel zu L_VF_m und VF_WINKEL.
|
||||
(vf-vfhoehe-reset)
|
||||
(tu-eq "vf-vfhoehe/leer-nach-reset" "" (vfl-join-komma *vf-acc-vfhoehe*))
|
||||
|
||||
;; 2000 mm und 3000 mm -> Mittel 2500 mm -> "2.500"
|
||||
(vf-vfhoehe-segment 2000.0 3000.0)
|
||||
(tu-eq "vf-vfhoehe/mittelwert-meter" "2.500" (vfl-join-komma *vf-acc-vfhoehe*))
|
||||
|
||||
;; Drei Abschnitte wie im realen Block (L_VF_m hatte dort 3 Eintraege):
|
||||
;; horizontal, horizontal, steigend - alle drei bekommen einen Wert.
|
||||
(vf-vfhoehe-reset)
|
||||
(vf-vfhoehe-segment 2076.0 2076.0) ; horizontal
|
||||
(vf-vfhoehe-segment 2076.0 2076.0) ; horizontal
|
||||
(vf-vfhoehe-segment 2076.0 2600.0) ; steigend -> Mittel 2338
|
||||
(tu-eq "vf-vfhoehe/drei-abschnitte"
|
||||
"2.076,2.076,2.338" (vfl-join-komma *vf-acc-vfhoehe*))
|
||||
|
||||
;; Unvollstaendige Messung haengt NICHTS an - sonst verschoebe sich die
|
||||
;; Liste gegen L_VF_m und eine Hoehe landete beim falschen Foerderer.
|
||||
(vf-vfhoehe-reset)
|
||||
(vf-vfhoehe-segment 1000.0 2000.0)
|
||||
(vf-vfhoehe-segment nil 3000.0)
|
||||
(vf-vfhoehe-segment 4000.0 nil)
|
||||
(tu-eq "vf-vfhoehe/unvollstaendig-ignoriert" "1.500" (vfl-join-komma *vf-acc-vfhoehe*))
|
||||
|
||||
;; negative Hoehen (Kette unter Null) muessen durchgehen
|
||||
(vf-vfhoehe-reset)
|
||||
(vf-vfhoehe-segment -500.0 -1500.0)
|
||||
(tu-eq "vf-vfhoehe/negativ" "-1.000" (vfl-join-komma *vf-acc-vfhoehe*))
|
||||
(vf-vfhoehe-reset)
|
||||
|
||||
;; vf-meter-3: GENAU 3 Nachkommastellen, unabhaengig von DIMZIN.
|
||||
;; (rtos x 2 3) allein kuerzt nachfolgende Nullen ("2.5", "-1") - real im
|
||||
;; Testlauf aufgetreten, deshalb eigene Formatierung.
|
||||
(tu-eq "vf-meter-3/glatt" "2.500" (vf-meter-3 2500.0))
|
||||
(tu-eq "vf-meter-3/ganzzahlig" "3.000" (vf-meter-3 3000.0))
|
||||
(tu-eq "vf-meter-3/negativ" "-1.000" (vf-meter-3 -1000.0))
|
||||
(tu-eq "vf-meter-3/null" "0.000" (vf-meter-3 0.0))
|
||||
(tu-eq "vf-meter-3/drei-stellen" "1.234" (vf-meter-3 1234.0))
|
||||
|
||||
;; --- SONDERFALL Standard/Etage: Hoehe ueber die GANZE Kette ---
|
||||
;; Nur ein Motor und nur ein gerader VF-Abschnitt, darum zaehlt dort
|
||||
;; AS-KS_EIN .. ES-KS_AUS statt des Segmentwerts (Nutzer-Vorgabe 2026-10-21).
|
||||
(vf-vfhoehe-reset)
|
||||
(vf-vfhoehe-kette 1000.0 3000.0)
|
||||
(tu-eq "vf-vfhoehe-kette/mittelwert" "2.000" (vfl-join-komma *vf-acc-vfhoehe*))
|
||||
|
||||
;; ERSETZT den beim Bau gesammelten Segmentwert, haengt ihn NICHT an -
|
||||
;; sonst stuenden fuer eine Standard-Anlage zwei Hoehen in der Liste.
|
||||
(vf-vfhoehe-reset)
|
||||
(vf-vfhoehe-segment 5000.0 5000.0) ; Segmentwert aus vfs-vf-koerper
|
||||
(vf-vfhoehe-kette 1000.0 3000.0)
|
||||
(tu-eq "vf-vfhoehe-kette/ersetzt-segmentwert" "2.000" (vfl-join-komma *vf-acc-vfhoehe*))
|
||||
|
||||
;; fehlender Endpunkt -> lieber leer als geraten
|
||||
(vf-vfhoehe-reset)
|
||||
(vf-vfhoehe-kette 1000.0 nil)
|
||||
(tu-eq "vf-vfhoehe-kette/ohne-endpunkt-leer" "" (vfl-join-komma *vf-acc-vfhoehe*))
|
||||
(vf-vfhoehe-reset)
|
||||
)
|
||||
|
||||
|
||||
@@ -2278,6 +2694,349 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; TESTS: KettenFoerderer.lsp + ssg_ks_insert.lsp (KS-Orientierung)
|
||||
;; ------------------------------------------------------------
|
||||
;; Reine Rechenkerne des Kettenfoerderers: Hoehenbilanz, Massstab,
|
||||
;; Grenzpruefung, KS-Winkel. Alles ohne Zeichnung und ohne Blockdateien -
|
||||
;; die zeichnungsabhaengigen Teile (kf-geometrie-messen, kf-kette-bauen)
|
||||
;; brauchen BricsCAD und bleiben dem Befehl KF_KS_PRUEFEN vorbehalten.
|
||||
(defun tu-tests-kf ( / _l _s _defs)
|
||||
(princ "\n[KettenFoerderer]")
|
||||
(if (not (car (atoms-family 1 '("KF-LAENGE-BERECHNEN"))))
|
||||
(tu-record nil "KettenFoerderer-Modul geladen"
|
||||
"KettenFoerderer.lsp nicht geladen - siehe tests/test_unit.scr")
|
||||
(progn
|
||||
;; --- ks-winkel-normalisieren: auf -180..180 falten ---
|
||||
(tu-eqf "ks-winkel-norm/190" -170.0 (ks-winkel-normalisieren 190.0))
|
||||
(tu-eqf "ks-winkel-norm/-190" 170.0 (ks-winkel-normalisieren -190.0))
|
||||
(tu-eqf "ks-winkel-norm/26" 26.0 (ks-winkel-normalisieren 26.0))
|
||||
(tu-eqf "ks-winkel-norm/360" 0.0 (ks-winkel-normalisieren 360.0))
|
||||
(tu-nil "ks-winkel-norm/nil" (ks-winkel-normalisieren nil))
|
||||
|
||||
;; --- ks-xy-winkel: X-Achse eines KS-Eintrags (origin x-end y-end z-end)
|
||||
(tu-eqf "ks-xy-winkel/entlang-X" 0.0
|
||||
(ks-xy-winkel '((0.0 0.0 0.0) (1.0 0.0 0.0) (0.0 2.0 0.0) (0.0 0.0 3.0))))
|
||||
(tu-eqf "ks-xy-winkel/entlang-Y" 90.0
|
||||
(ks-xy-winkel '((0.0 0.0 0.0) (0.0 1.0 0.0) (-2.0 0.0 0.0) (0.0 0.0 3.0))))
|
||||
;; versetzter Ursprung: nur die RICHTUNG zaehlt, nicht die Lage
|
||||
(tu-eqf "ks-xy-winkel/versetzt-45" 45.0
|
||||
(ks-xy-winkel (list '(100.0 50.0 0.0) '(101.0 51.0 0.0) '(99.0 51.0 0.0) '(100.0 50.0 1.0))))
|
||||
;; senkrechte X-Achse (keine XY-Laenge) -> nil statt Division durch 0
|
||||
(tu-nil "ks-xy-winkel/senkrecht"
|
||||
(ks-xy-winkel '((0.0 0.0 0.0) (0.0 0.0 1.0) (0.0 2.0 0.0) (0.0 0.0 3.0))))
|
||||
|
||||
;; --- kf-hz-folge: Folgebaustein an KS_AUS des Vorgaengers ausrichten ---
|
||||
;; Vorgaenger zeigt 26 Grad, Folgebaustein ist waagerecht gezeichnet (0)
|
||||
(tu-eqf "kf-hz-folge/26-auf-0" 26.0 (kf-hz-folge 26.0 0.0))
|
||||
;; Folgebaustein ist selbst schon um 26 Grad gezeichnet -> keine Drehung
|
||||
(tu-eqf "kf-hz-folge/26-auf-26" 0.0 (kf-hz-folge 26.0 26.0))
|
||||
;; fehlende Eigenrichtung -> Baustein uebernimmt die Vorgaengerrichtung
|
||||
(tu-eqf "kf-hz-folge/ohne-beta" 26.0 (kf-hz-folge 26.0 nil))
|
||||
(tu-nil "kf-hz-folge/ohne-phi" (kf-hz-folge nil 0.0))
|
||||
|
||||
;; --- kf-dy-eingebaut: Hoehenbeitrag nach Rz(hz) und X-Massstab ---
|
||||
;; waagerechter Baustein, waagerecht eingebaut -> kein Hoehengewinn
|
||||
(tu-eqf "kf-dy/0-grad" 0.0 (kf-dy-eingebaut 1000.0 0.0 0.0 1.0))
|
||||
;; 1000 mm unter 30 Grad -> 500 mm (sin 30 = 0.5)
|
||||
(tu-eqf "kf-dy/30-grad" 500.0 (kf-dy-eingebaut 1000.0 0.0 30.0 1.0))
|
||||
;; derselbe Baustein doppelt skaliert -> doppelter Hoehengewinn
|
||||
(tu-eqf "kf-dy/30-grad-skaliert-2" 1000.0 (kf-dy-eingebaut 1000.0 0.0 30.0 2.0))
|
||||
;; senkrecht eingebaut -> die volle Laenge als Hoehe
|
||||
(tu-eqf "kf-dy/90-grad" 1000.0 (kf-dy-eingebaut 1000.0 0.0 90.0 1.0))
|
||||
|
||||
;; --- kf-laenge-berechnen: Hoehenbilanz nach der Laenge aufloesen ---
|
||||
;; H=1000, Stationen tragen nichts bei, 30 Grad -> L = 1000/sin30 = 2000
|
||||
(tu-eqf "kf-laenge/30-grad-glatt" 2000.0
|
||||
(kf-laenge-berechnen 1000.0 0.0 0.0 0.0 30.0))
|
||||
;; Stationen tragen 100+150 bei -> nur 750 mm bleiben fuer das Stueck
|
||||
(tu-eqf "kf-laenge/mit-stationen" 1500.0
|
||||
(kf-laenge-berechnen 1000.0 100.0 150.0 0.0 30.0))
|
||||
;; Gegenprobe: die errechnete Laenge ergibt wieder genau H
|
||||
(setq _l (kf-laenge-berechnen 1000.0 100.0 150.0 0.0 30.0))
|
||||
(tu-eqf "kf-laenge/rundlauf-ergibt-H" 1000.0
|
||||
(+ 100.0 150.0 (kf-dy-eingebaut _l 0.0 30.0 1.0)))
|
||||
;; bereits geneigt gezeichnetes Zwischenstueck: dy-nativ wird abgezogen
|
||||
;; (dy-nativ skaliert NICHT mit, nur X wird skaliert)
|
||||
(tu-eqf "kf-laenge/mit-dy-nativ" 1800.0
|
||||
(kf-laenge-berechnen 1000.0 0.0 0.0 (/ 100.0 (cos (/ pi 6.0))) 30.0))
|
||||
;; waagerecht -> keine Hoehe erreichbar
|
||||
(tu-nil "kf-laenge/0-grad-unloesbar"
|
||||
(kf-laenge-berechnen 1000.0 0.0 0.0 0.0 0.0))
|
||||
|
||||
;; --- kf-skala-berechnen ---
|
||||
(tu-eqf "kf-skala/2000-von-1000" 2.0 (kf-skala-berechnen 2000.0 1000.0))
|
||||
(tu-nil "kf-skala/ohne-nativlaenge" (kf-skala-berechnen 2000.0 0.0))
|
||||
(tu-nil "kf-skala/ohne-laenge" (kf-skala-berechnen nil 1000.0))
|
||||
|
||||
;; --- kf-laenge-pruefen: Grenzen aus der JSON ---
|
||||
(tu-nil "kf-pruefen/in-ordnung" (kf-laenge-pruefen 2000.0 100.0 20000.0))
|
||||
(tu-eq "kf-pruefen/zu-kurz" "kf-fehler-laenge-unter-min"
|
||||
(kf-laenge-pruefen 50.0 100.0 20000.0))
|
||||
(tu-eq "kf-pruefen/zu-lang" "kf-fehler-laenge-ueber-max"
|
||||
(kf-laenge-pruefen 99999.0 100.0 20000.0))
|
||||
;; negative Laenge = Stationen bringen mehr Hoehe mit als gefordert
|
||||
(tu-eq "kf-pruefen/negativ" "kf-fehler-hoehe-zu-klein"
|
||||
(kf-laenge-pruefen -10.0 100.0 20000.0))
|
||||
(tu-eq "kf-pruefen/nil" "kf-fehler-winkel-null"
|
||||
(kf-laenge-pruefen nil 100.0 20000.0))
|
||||
|
||||
;; --- kf-zahl: JSON-Wert als Zahl (Parser liefert Zahl ODER String) ---
|
||||
(tu-eqf "kf-zahl/int" 26.0 (kf-zahl 26))
|
||||
(tu-eqf "kf-zahl/real" 26.0 (kf-zahl 26.0))
|
||||
(tu-eqf "kf-zahl/string" 26.0 (kf-zahl "26"))
|
||||
(tu-nil "kf-zahl/nil" (kf-zahl nil))
|
||||
|
||||
;; --- kf-attrib-defs: VF-Schema + KF-Zusatz, KEIN Tag doppelt ---
|
||||
(setq _defs (kf-attrib-defs))
|
||||
(tu-true "kf-attrib-defs/hat-ID" (assoc "ID" _defs))
|
||||
(tu-true "kf-attrib-defs/hat-FOERDERERTYP" (assoc "FOERDERERTYP" _defs))
|
||||
(tu-true "kf-attrib-defs/hat-WINKEL" (assoc "WINKEL" _defs))
|
||||
(tu-true "kf-attrib-defs/hat-STANDARD_STEUERUNG"
|
||||
(assoc "STANDARD_STEUERUNG" _defs))
|
||||
;; Reihenfolge wie im Sivas-Merkmalstamm: 361 folgt direkt auf den Typ,
|
||||
;; STANDARD_STEUERUNG steht also unmittelbar hinter WINKEL
|
||||
(tu-eq "kf-attrib-defs/361-folgt-auf-winkel" "STANDARD_STEUERUNG"
|
||||
(car (nth (1+ (kf-tag-index "WINKEL" _defs)) _defs)))
|
||||
;; FOERDERERTYP ist die BAUART im Klartext, der Winkel steht in WINKEL
|
||||
(tu-eq "kf-attrib-defs/FOERDERERTYP-ist-bauart" "Schraegfoerderer Stahl"
|
||||
(cadr (assoc "FOERDERERTYP" _defs)))
|
||||
(tu-true "kf-attrib-defs/hat-MOVIMOT" (assoc "MOVIMOT" _defs))
|
||||
;; Farbe und Antriebsmotor sind ZWEI Eigenschaften (Sivas 354 bzw. 355), nicht
|
||||
;; ein kombiniertes AUSFUEHRUNG-Attribut
|
||||
(tu-true "kf-attrib-defs/hat-FARBE" (assoc "FARBE" _defs))
|
||||
(tu-true "kf-attrib-defs/hat-ANTRIEBSMOTOR" (assoc "ANTRIEBSMOTOR" _defs))
|
||||
(tu-nil "kf-attrib-defs/kein-AUSFUEHRUNG" (assoc "AUSFUEHRUNG" _defs))
|
||||
;; Der Kettenfoerderer traegt sich selbst - die Geruest-Tags aus dem
|
||||
;; VF-Schema werden bewusst NICHT mitgefuehrt
|
||||
(tu-nil "kf-attrib-defs/kein-GERUEST_EINZELMODUL"
|
||||
(assoc "GERUEST_EINZELMODUL" _defs))
|
||||
(tu-nil "kf-attrib-defs/kein-GERUEST_TYP" (assoc "GERUEST_TYP" _defs))
|
||||
;; Jeder Tag darf nur EINMAL vorkommen (zwei ATTDEFs gleichen Tags waeren
|
||||
;; im Block ungueltig, ssg-attrib-set-on traefe nur den ersten).
|
||||
(setq _s 0)
|
||||
(foreach _d _defs (if (= (car _d) "FOERDERERTYP") (setq _s (1+ _s))))
|
||||
(tu-eq "kf-attrib-defs/FOERDERERTYP-nur-einmal" 1 _s)
|
||||
(setq _s 0)
|
||||
(foreach _d _defs (if (= (car _d) "ARTINR") (setq _s (1+ _s))))
|
||||
(tu-eq "kf-attrib-defs/ARTINR-nur-einmal" 1 _s)
|
||||
(setq _s 0)
|
||||
(foreach _d _defs (if (= (car _d) "ARTINR") (setq _s (1+ _s))))
|
||||
(tu-eq "kf-attrib-defs/ARTINR-nur-einmal" 1 _s)
|
||||
;; Der Winkel steht ALLEIN in FOERDERERTYP - kein zweites Winkel-Tag
|
||||
(tu-nil "kf-attrib-defs/kein-KF_WINKEL" (assoc "KF_WINKEL" _defs))
|
||||
(tu-nil "kf-attrib-defs/kein-KF_TYP" (assoc "KF_TYP" _defs))
|
||||
;; Das Schema ist EIGENSTAENDIG, nicht vom VF-Streckenschema geerbt -
|
||||
;; keines der VF-Tags darf durchschlagen
|
||||
(tu-nil "kf-attrib-defs/kein-SEITE_AS" (assoc "SEITE_AS" _defs))
|
||||
(tu-nil "kf-attrib-defs/kein-ANZAHL_VF" (assoc "ANZAHL_VF" _defs))
|
||||
(tu-nil "kf-attrib-defs/kein-TEILEART" (assoc "TEILEART" _defs))
|
||||
(tu-eq "kf-attrib-defs/LAYER-ist-F-3" "F-3" (cadr (assoc "LAYER" _defs)))
|
||||
|
||||
;; --- kf-variante-finden: ueber den Winkel, auch als String ---
|
||||
(tu-eq "kf-variante-finden/26" "A"
|
||||
(cdr (assoc "name"
|
||||
(kf-variante-finden 26
|
||||
'((("winkel" . 26) ("name" . "A"))
|
||||
(("winkel" . 30) ("name" . "B")))))))
|
||||
(tu-eq "kf-variante-finden/30-als-string" "B"
|
||||
(cdr (assoc "name"
|
||||
(kf-variante-finden 30
|
||||
'((("winkel" . "26") ("name" . "A"))
|
||||
(("winkel" . "30") ("name" . "B")))))))
|
||||
(tu-nil "kf-variante-finden/unbekannt"
|
||||
(kf-variante-finden 45 '((("winkel" . 26) ("name" . "A")))))
|
||||
|
||||
;; --- kf-antriebsart (Merkmal 357): Dropdown mit EINER Option ---
|
||||
;; Der Wert kommt aus dem ERSTEN Listeneintrag - nicht aus dem Code.
|
||||
(tu-eq "kf-antriebsart/aus-daten" "1.1 kW"
|
||||
(kf-antriebsart '(("antriebsart" (("name" . "1.1 kW") ("wert" . "1.1 kW"))))))
|
||||
;; eine zweite Option aendert die Vorgabe NICHT (Index 0 bleibt massgebend)
|
||||
(tu-eq "kf-antriebsart/erster-eintrag-gewinnt" "1.1 kW"
|
||||
(kf-antriebsart '(("antriebsart" (("name" . "1.1 kW") ("wert" . "1.1 kW"))
|
||||
(("name" . "0.55 kW") ("wert" . "0.55 kW"))))))
|
||||
;; Liste fehlt -> Rueckfall, aber als STRING (nicht T/nil)
|
||||
(tu-eq "kf-antriebsart/ohne-eintrag" "1.1 kW" (kf-antriebsart '(("titel" . "x"))))
|
||||
(tu-true "kf-antriebsart/ist-string"
|
||||
(= (type (kf-antriebsart '(("titel" . "x")))) 'STR))
|
||||
;; Dezimalpunkt, kein Komma (Nutzervorgabe)
|
||||
(tu-nil "kf-antriebsart/kein-komma"
|
||||
(vl-string-search "," (kf-antriebsart '(("titel" . "x")))))
|
||||
|
||||
;; --- kf-drehung-gesamt: Drehwinkel fuer KF_EDIT ---
|
||||
;; Regression: der Drehwinkel wird beim Bau in die Geometrie eingerechnet,
|
||||
;; die Blockreferenz selbst hat IMMER Drehung 0 (ssg-block-wrap-welt).
|
||||
;; KF_EDIT las nur Gruppencode 50 und baute eine mit 90 Grad gebaute
|
||||
;; Kette ungedreht neu. Der gebaute Winkel steht jetzt als XDATA.
|
||||
(tu-eqf "kf-drehung/nur-xdata" 90.0 (kf-drehung-gesamt 90.0 0.0))
|
||||
;; Referenz nachtraeglich von Hand um 90 Grad gedreht (Gruppencode 50 in
|
||||
;; Bogenmass) -> beides addiert sich
|
||||
(tu-eqf "kf-drehung/xdata-plus-referenz" 180.0
|
||||
(kf-drehung-gesamt 90.0 (/ pi 2.0)))
|
||||
;; Altbestand ohne XDATA: nur die Referenzdrehung (bisheriges Verhalten)
|
||||
(tu-eqf "kf-drehung/ohne-xdata" 45.0 (kf-drehung-gesamt nil (/ pi 4.0)))
|
||||
;; nichts bekannt -> 0, kein Absturz und kein nil
|
||||
(tu-eqf "kf-drehung/nichts" 0.0 (kf-drehung-gesamt nil nil))
|
||||
(tu-true "kf-drehung/ist-zahl" (numberp (kf-drehung-gesamt nil nil)))
|
||||
;; Summe ueber 180 Grad wird auf -180..180 gefaltet (270 = -90)
|
||||
(tu-eqf "kf-drehung/normalisiert" -90.0
|
||||
(kf-drehung-gesamt 180.0 (/ pi 2.0)))
|
||||
;; ganze Zahl aus der XDATA (nicht real) darf nicht abstuerzen
|
||||
(tu-eqf "kf-drehung/ganzzahl" 30.0 (kf-drehung-gesamt 30 0.0))
|
||||
|
||||
;; --- kf-neigung-aus-punkten: Kern der 3D-Aufrichtung ---
|
||||
;; Liefert (Schraeglaenge Neigungswinkel) aus Ketten-Start und -Ende.
|
||||
;; Die Kette wird AUFGERICHTET eingebaut, die Hoehe laeuft also in Z.
|
||||
;; 3-4-5-Dreieck: 3000 waagerecht, 4000 hoch -> 5000 schraeg
|
||||
(tu-eqf "kf-neigung/3-4-5-laenge" 5000.0
|
||||
(car (kf-neigung-aus-punkten '(0.0 0.0 0.0) '(3000.0 0.0 4000.0) 0.0)))
|
||||
;; 45 Grad: gleiche Betraege waagerecht und hoch
|
||||
(tu-eqf "kf-neigung/45-grad" 45.0
|
||||
(cadr (kf-neigung-aus-punkten '(0.0 0.0 0.0) '(1000.0 0.0 1000.0) 0.0)))
|
||||
;; waagerecht -> Winkel 0, Laenge = Horizontalabstand
|
||||
(tu-eqf "kf-neigung/waagerecht" '(2000.0 0.0)
|
||||
(kf-neigung-aus-punkten '(0.0 0.0 0.0) '(2000.0 0.0 0.0) 0.0))
|
||||
;; Der Horizontalanteil wird auf die KETTENRICHTUNG projiziert, nicht
|
||||
;; auf die Welt-X-Achse: bei 90 Grad Basisdrehung laeuft die Kette in Y.
|
||||
;; Ohne Projektion kaeme hier 0 heraus und der Winkel waere 90 statt 45.
|
||||
(tu-eqf "kf-neigung/gedreht-90" '(1414.213562 45.0)
|
||||
(kf-neigung-aus-punkten '(0.0 0.0 0.0) '(0.0 1000.0 1000.0) 90.0))
|
||||
;; fallende Kette -> negativer Winkel
|
||||
(tu-eqf "kf-neigung/fallend" -45.0
|
||||
(cadr (kf-neigung-aus-punkten '(0.0 0.0 1000.0) '(1000.0 0.0 0.0) 0.0)))
|
||||
;; Start = Ende -> nil statt Division durch 0
|
||||
(tu-nil "kf-neigung/nulllaenge"
|
||||
(kf-neigung-aus-punkten '(5.0 5.0 5.0) '(5.0 5.0 5.0) 0.0))
|
||||
|
||||
;; --- kf-matrix-aufrecht: Y_lokal wird zu Z_welt ---
|
||||
;; Das ist die Kernaussage der Aufrichtung. Geprueft wird sie an den
|
||||
;; Bildern der Einheitsvektoren, nicht an den Matrixeintraegen - so
|
||||
;; bleibt der Test lesbar und unabhaengig von der Schreibweise.
|
||||
(tu-eqf "kf-matrix/Y-lokal-wird-Z-welt" '(0.0 0.0 1.0)
|
||||
(mat3-mul-vec3 (kf-matrix-aufrecht 0.0 0.0) '(0.0 1.0 0.0)))
|
||||
;; Die Fahrtrichtung (X) bleibt bei Basisdrehung 0 die Welt-X-Achse
|
||||
(tu-eqf "kf-matrix/X-bleibt-X" '(1.0 0.0 0.0)
|
||||
(mat3-mul-vec3 (kf-matrix-aufrecht 0.0 0.0) '(1.0 0.0 0.0)))
|
||||
;; Basisdrehung 90 Grad dreht die Fahrtrichtung in die Welt-Y-Achse,
|
||||
;; die Hoehe bleibt dabei in Z
|
||||
(tu-eqf "kf-matrix/basis-90-dreht-X-nach-Y" '(0.0 1.0 0.0)
|
||||
(mat3-mul-vec3 (kf-matrix-aufrecht 90.0 0.0) '(1.0 0.0 0.0)))
|
||||
(tu-eqf "kf-matrix/basis-90-haelt-Z" '(0.0 0.0 1.0)
|
||||
(mat3-mul-vec3 (kf-matrix-aufrecht 90.0 0.0) '(0.0 1.0 0.0)))
|
||||
|
||||
;; --- Standard-Variante: steht in den DATEN, nicht im Code ---
|
||||
(tu-true "kf-variante-standard-p/markiert"
|
||||
(kf-variante-standard-p '(("winkel" . 26) ("standard" . T))))
|
||||
(tu-nil "kf-variante-standard-p/ohne-feld"
|
||||
(kf-variante-standard-p '(("winkel" . 30))))
|
||||
;; Index fuer die Vorauswahl - auch wenn der Standard NICHT der erste ist
|
||||
(tu-eq "kf-standard-index/zweiter" 1
|
||||
(kf-standard-index '((("winkel" . 26))
|
||||
(("winkel" . 30) ("standard" . T)))))
|
||||
(tu-eq "kf-standard-index/erster" 0
|
||||
(kf-standard-index '((("winkel" . 26) ("standard" . T))
|
||||
(("winkel" . 30)))))
|
||||
;; keine Variante markiert -> erste, statt nil (der Dialog braucht einen Index)
|
||||
(tu-eq "kf-standard-index/keiner" 0
|
||||
(kf-standard-index '((("winkel" . 26)) (("winkel" . 30)))))
|
||||
|
||||
;; --- kf-punkt-differenzen: zweite Hoehen-Eingabeart (2 Punkte) ---
|
||||
;; Gemessen wird die Differenz in Z - die Baugruppe steht aufgerichtet im
|
||||
;; Modell. Zurueckgegeben wird (dz dy): die HOEHE zuerst, dY nur zur
|
||||
;; Kontrolle (wer in einer Draufsicht pickt, sieht dz = 0).
|
||||
(tu-eqf "kf-punkt-diff/dz" '(1500.0 0.0)
|
||||
(kf-punkt-differenzen '(0.0 0.0 0.0) '(2000.0 0.0 1500.0)))
|
||||
;; Vorzeichen egal - die Reihenfolge der Punkte darf keine Rolle spielen
|
||||
(tu-eqf "kf-punkt-diff/umgekehrt" '(1500.0 0.0)
|
||||
(kf-punkt-differenzen '(2000.0 0.0 1500.0) '(0.0 0.0 0.0)))
|
||||
;; in einer Draufsicht gepickt: dz = 0, dY gross
|
||||
(tu-eqf "kf-punkt-diff/draufsicht" '(0.0 1200.0)
|
||||
(kf-punkt-differenzen '(0.0 0.0 0.0) '(3000.0 1200.0 0.0)))
|
||||
;; Punkte ohne Z (2D-Pick) duerfen nicht abstuerzen: dz ist dann 0
|
||||
(tu-eqf "kf-punkt-diff/ohne-z" '(0.0 800.0)
|
||||
(kf-punkt-differenzen '(0.0 0.0) '(100.0 800.0)))
|
||||
(tu-nil "kf-punkt-diff/nil" (kf-punkt-differenzen nil '(1.0 2.0 3.0)))
|
||||
|
||||
;; --- kf-auswahl-wert: "wert" vor "name", Vorgabe bei leerem Index ---
|
||||
(tu-eq "kf-auswahl-wert/wert" "Nein"
|
||||
(kf-auswahl-wert '((("name" . "Nein") ("wert" . "Nein"))) 0 "X"))
|
||||
(tu-eq "kf-auswahl-wert/ausserhalb" "X"
|
||||
(kf-auswahl-wert '((("name" . "Nein") ("wert" . "Nein"))) 5 "X"))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; TESTS: check_hoehen.lsp - Phase 3 (Buehnen-Familien), reine Kerne
|
||||
;; ------------------------------------------------------------
|
||||
(defun tu-tests-hoehen-fam ( / _els)
|
||||
(princ "\n[check_hoehen/Phase 3 Familien]")
|
||||
|
||||
;; --- ch-familien: transitive Verbindung, Sortierung nach ID-Nummer ---
|
||||
(tu-eq "ch-familien/einzeln-und-kette"
|
||||
'(("b") ("c" "a" "d") ("e"))
|
||||
(ch-familien '(("a" 3) ("b" 1) ("c" 2) ("d" 5) ("e" 4))
|
||||
'(("a" "c") ("c" "d") ("x" "a"))))
|
||||
(tu-eq "ch-familien/kette-ueber-mittleren"
|
||||
'(("a" "b" "c"))
|
||||
(ch-familien '(("a" 1) ("b" 2) ("c" 3)) '(("a" "b") ("b" "c"))))
|
||||
(tu-eq "ch-familien/ohne-kanten"
|
||||
'(("a") ("b"))
|
||||
(ch-familien '(("a" 1) ("b" 2)) nil))
|
||||
(tu-eq "ch-familien/ring"
|
||||
'(("a" "b" "c"))
|
||||
(ch-familien '(("a" 1) ("b" 2) ("c" 3)) '(("a" "b") ("b" "c") ("c" "a"))))
|
||||
|
||||
;; --- ch-kreuz-abzug ---
|
||||
(tu-eq "ch-kreuz-abzug/kein" '("kein" . 0.0) (ch-kreuz-abzug 0.0 0.0 5000.0 5000.0 1500.0))
|
||||
(tu-eq "ch-kreuz-abzug/konflikt" '("konflikt" . 0.0) (ch-kreuz-abzug 1.5 0.0 5000.0 5000.0 1500.0))
|
||||
(tu-eq "ch-kreuz-abzug/konflikt2" '("konflikt" . 0.0) (ch-kreuz-abzug 1.5 2.0 5000.0 5000.0 1500.0))
|
||||
(tu-eq "ch-kreuz-abzug/hoehe" '("hoehe" . 0.0) (ch-kreuz-abzug 1.5 1.5 5000.0 6600.0 1500.0))
|
||||
(tu-eq "ch-kreuz-abzug/grenze" '("abzug" . 1.5) (ch-kreuz-abzug 1.5 1.5 5000.0 6500.0 1500.0))
|
||||
(tu-eq "ch-kreuz-abzug/abzug" '("abzug" . 1.5) (ch-kreuz-abzug 1.5 1.5 5000.0 5200.0 1500.0))
|
||||
|
||||
;; --- ch-strecke-abzug (Familiensaetze: idx handles z b) ---
|
||||
(tu-eq "ch-strecke-abzug/innen"
|
||||
'("innen" . 1.5)
|
||||
(ch-strecke-abzug '(1 ("a") 5000.0 1.5) '(1 ("a") 5000.0 1.5) 1500.0))
|
||||
(tu-eq "ch-strecke-abzug/innen-ohne-buehne"
|
||||
'("innen" . 0.0)
|
||||
(ch-strecke-abzug '(1 ("a") 5000.0 0.0) '(1 ("a") 5000.0 0.0) 1500.0))
|
||||
(tu-eq "ch-strecke-abzug/zwischen"
|
||||
'("abzug" . 1.5)
|
||||
(ch-strecke-abzug '(1 ("a") 5000.0 1.5) '(2 ("b") 5400.0 1.5) 1500.0))
|
||||
|
||||
;; --- ch-schleife-p: gleicher Kreisel + gleiche Hoehe ---
|
||||
(tu-true "ch-schleife-p/gleicher-kreisel-flach" (ch-schleife-p "K1" "K1" 5000.0 5000.0 1.0))
|
||||
(tu-true "ch-schleife-p/toleranz" (ch-schleife-p "K1" "K1" 5000.0 5000.8 1.0))
|
||||
(tu-nil "ch-schleife-p/hoehenunterschied" (ch-schleife-p "K1" "K1" 5000.0 4800.0 1.0))
|
||||
(tu-nil "ch-schleife-p/anderer-kreisel" (ch-schleife-p "K1" "K2" 5000.0 5000.0 1.0))
|
||||
(tu-nil "ch-schleife-p/kein-kreisel" (ch-schleife-p nil nil 5000.0 5000.0 1.0))
|
||||
|
||||
;; --- ch-abzug-anwenden ---
|
||||
(tu-eqf "ch-abzug-anwenden/normal" 2.5 (ch-abzug-anwenden 3.5 1.0))
|
||||
(tu-nil "ch-abzug-anwenden/gleich" (ch-abzug-anwenden 3.5 3.5))
|
||||
(tu-nil "ch-abzug-anwenden/groesser" (ch-abzug-anwenden 3.5 4.0))
|
||||
(tu-nil "ch-abzug-anwenden/null" (ch-abzug-anwenden 3.5 0.0))
|
||||
|
||||
;; --- ch-kreisel-finden: Kreisel r=400, Achse (400,0)-(2400,0) bzw. (400,5000)-(2400,5000) ---
|
||||
(setq _els (list (tu-bp-el "KREISEL" 0.0 0.0 5000.0 0.0 2000.0 "K1")
|
||||
(tu-bp-el "KREISEL" 0.0 5000.0 5000.0 0.0 2000.0 "K2")))
|
||||
(tu-eq "ch-kreisel-finden/auf-achse"
|
||||
"K1" (ch-kreisel-finden '(1000.0 100.0 5000.0) 5000.0 _els 300.0 100.0))
|
||||
(tu-eq "ch-kreisel-finden/zweiter"
|
||||
"K2" (ch-kreisel-finden '(1000.0 4900.0 5000.0) 5000.0 _els 300.0 100.0))
|
||||
(tu-eq "ch-kreisel-finden/hinter-dem-rad"
|
||||
"K1" (ch-kreisel-finden '(-200.0 0.0 5000.0) 5000.0 _els 300.0 100.0))
|
||||
(tu-nil "ch-kreisel-finden/zu-weit"
|
||||
(ch-kreisel-finden '(1000.0 1000.0 5000.0) 5000.0 _els 300.0 100.0))
|
||||
(tu-nil "ch-kreisel-finden/falsche-hoehe"
|
||||
(ch-kreisel-finden '(1000.0 0.0 5300.0) 5300.0 _els 300.0 100.0))
|
||||
)
|
||||
|
||||
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; TESTS: ssg_core.lsp - Polygon-Helfer (reine 2D-Berechnung)
|
||||
;; ------------------------------------------------------------
|
||||
@@ -2720,11 +3479,12 @@
|
||||
(princ "\n================================================================")
|
||||
|
||||
(foreach fn '("tu-tests-core" "tu-tests-lang" "tu-tests-id" "tu-tests-vfcore"
|
||||
"tu-tests-etage" "tu-tests-vfl-es" "tu-tests-vfl-ziellinie"
|
||||
"tu-tests-etage" "tu-tests-vfl-es" "tu-tests-vfl-parallel"
|
||||
"tu-tests-vfl-ziellinie"
|
||||
"tu-tests-export" "tu-tests-hoehen" "tu-tests-gf" "tu-tests-omni" "tu-tests-kreisel" "tu-tests-kreisel-bp"
|
||||
"tu-tests-sepliste" "tu-tests-json" "tu-tests-geruest"
|
||||
"tu-tests-sepscan" "tu-tests-vfl-segs" "tu-tests-vfl-abbruch"
|
||||
"tu-tests-werkzeuge" "tu-tests-poly" "tu-tests-lager")
|
||||
"tu-tests-werkzeuge" "tu-tests-poly" "tu-tests-lager" "tu-tests-kf" "tu-tests-hoehen-fam")
|
||||
(tu-run-block fn))
|
||||
|
||||
(princ "\n\n----------------------------------------------------------------")
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
; Modul, gehoert dessen load-Zeile HIER dazu (nicht in test_unit.lsp).
|
||||
(load (strcat (getenv "DXFM_LISP") "/GeruestInsert.lsp") "GeruestInsert.lsp nicht gefunden")
|
||||
(load (strcat (getenv "DXFM_LISP") "/count_sep_scan.lsp") "count_sep_scan.lsp nicht gefunden")
|
||||
(load (strcat (getenv "DXFM_LISP") "/KettenFoerderer.lsp") "KettenFoerderer.lsp nicht gefunden")
|
||||
(load (strcat (getenv "DXFM_LISP") "/check_hoehen.lsp") "check_hoehen.lsp nicht gefunden")
|
||||
(load (strcat (getenv "DXFMAKRO") "/tests/test_unit.lsp"))
|
||||
(c:TEST_UNIT)
|
||||
(command "_.QUIT")
|
||||
|
||||
@@ -175,10 +175,12 @@ EINGABE_ERLAUBT = {
|
||||
"vfl-in-selection": {"ssget": 1},
|
||||
"vfl-in-segmente": {"ssget": 1}, # Modus-3-Wrapper: Live-Auswahl -> Segment-Essenz (SEGS), Replay aus Journal
|
||||
"vfl-winkel-live": {"getint": 1}, # livefn fuer vfl-in-value
|
||||
"vfl-menu-strwert": {"getstring": 1}, # livefn fuer vfl-in-value (Wert statt Index)
|
||||
# --- Wizard-Schicht (DCL); bei ssg-gui-aus greift sie nicht ---
|
||||
"vflw-zahl": {"getreal": 1}, # Fallback ohne Dialog
|
||||
"vflw-zahl-impl": {"new_dialog": 1},
|
||||
"vflw-wahl-impl": {"new_dialog": 1},
|
||||
"vflw-radio-wahl-impl": {"new_dialog": 1},
|
||||
"vflw-gruppe-as-impl": {"new_dialog": 1},
|
||||
"vflw-gruppe-gefaelle-impl": {"new_dialog": 1},
|
||||
"vflw-gruppe-punkt-hoehe-impl": {"new_dialog": 1},
|
||||
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
[
|
||||
{
|
||||
"beschreibung": "Linienzug Modus 2, Variante B: 90-Grad-Ecke als GF-BOGEN (geneigt eingebaut). Deckt die Neigungs-Projektion der Eck-Korrektur ab (vfl-projiziere-neigung) und den Zweig OHNE flache Zone, in dem der ES-Fussabdruck frueher faelschlich vom VF-Lauf abgezogen wurde (878 mm). Aufgezeichnet 2026-10-27 aus einem echten BricsCAD-Lauf. Startpunkt fuer die Testreihe versetzt: alle Koordinaten (Start-/Zielpunkt und Pfadsegmente) um einen gemeinsamen Vektor verschoben, damit TEST_LINIENZUG_MODUS2 die Ketten nebeneinander auf einer Grundlinie baut statt verstreut. Reine Translation - Laengen, Winkel und die geprueften Abweichungen sind davon unabhaengig; Z bleibt unveraendert, weil die Starthoehe ein Eingabewert des Solvers ist.",
|
||||
"test_id": "LZ_M2_gfbogen",
|
||||
"kurz": "Ecke als GF-Bogen",
|
||||
"erwartung_quer_mm": 0,
|
||||
"erwartung_dz_mm": 0,
|
||||
"erwartung_laengs_mm": 105,
|
||||
"erwartung_hinweis": "quer zur ES-KS_AUS-Achse MUSS ~0 sein und dZ ~0; laengs darf abweichen - das ist die Ausladung des ES-Elements und kein Fehler. Beides zugleich geht nicht: entweder liegt die letzte Gerade auf der gezeichneten Linie und der KS_AUS landet seitlich daneben, oder umgekehrt. Entschieden ist - der Hauptstrang bleibt gerade."
|
||||
},
|
||||
{
|
||||
"art": "PT",
|
||||
"x": 60000.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
{
|
||||
"art": "REAL",
|
||||
"wert": 0.0
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "90"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
},
|
||||
{
|
||||
"art": "PT",
|
||||
"x": 71000.0,
|
||||
"y": -6315.123197,
|
||||
"z": 184.3
|
||||
},
|
||||
{
|
||||
"art": "REAL",
|
||||
"wert": 184.3
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "30"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "2"
|
||||
},
|
||||
{
|
||||
"art": "SEGS",
|
||||
"wert": "Linie|0|9700|0|links|60000|0|69700|0;Bogen|0|707.106781|90|rechts|69700|0|70200|-500;Linie|-90|4295.507955|0|links|70200|-500|70200|-4795.507955;Bogen|-90|258.819045|30|links|70200|-4795.507955|70266.987298|-5045.507955;Linie|-60|1466.025404|0|links|70266.987298|-5045.507955|71000|-6315.123197"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "m2v2"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "2"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
},
|
||||
{
|
||||
"art": "REAL",
|
||||
"wert": 3.0
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "2"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "2"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
},
|
||||
{
|
||||
"art": "REAL",
|
||||
"wert": 3.0
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "2"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "2"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "mit-gf1"
|
||||
},
|
||||
{
|
||||
"art": "INT",
|
||||
"wert": 1
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
}
|
||||
]
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
[
|
||||
{
|
||||
"beschreibung": "Linienzug Modus 2, GEFALTETER Lauf (U-Form): der Pfad wechselt ueber zwei 90-Grad-Vario-Kurven dreimal die Fahrtrichtung, die Kletterstrecke liegt dadurch in einem ANDEREN Schenkel als der Lauf-Eingang. GF-Verteilung 1 (alles am Einlauf, GF1) - diese Verteilung war bis 2026-10-29 durch keinen Test abgedeckt. Aufgezeichnet 2026-10-29 aus einem echten BricsCAD-Lauf. Startpunkt fuer die Testreihe versetzt: alle Koordinaten (Start-/Zielpunkt und Pfadsegmente) um einen gemeinsamen Vektor verschoben, damit TEST_LINIENZUG_MODUS2 die Ketten nebeneinander auf einer Grundlinie baut statt verstreut. Reine Translation - Laengen, Winkel und die geprueften Abweichungen sind davon unabhaengig; Z bleibt unveraendert, weil die Starthoehe ein Eingabewert des Solvers ist.",
|
||||
"test_id": "LZ_M2_uform_gf1",
|
||||
"kurz": "U-Form, GF alles am Einlauf",
|
||||
"erwartung_quer_mm": 0,
|
||||
"erwartung_dz_mm": 0,
|
||||
"erwartung_laengs_mm": 638,
|
||||
"erwartung_hinweis": "quer zur ES-KS_AUS-Achse MUSS ~0 sein und dZ ~0; laengs darf abweichen - das ist die Ausladung des ES-Elements und kein Fehler. Der laengs-Wert von rund 638 mm ist die Ausladung des ES_Element_90_links und in allen drei U-Form-Faellen gleich; geprueft werden nur quer und dZ."
|
||||
},
|
||||
{
|
||||
"art": "PT",
|
||||
"x": 80000.0,
|
||||
"y": 0.0,
|
||||
"z": 355.289671
|
||||
},
|
||||
{
|
||||
"art": "REAL",
|
||||
"wert": 355.3
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "90"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
},
|
||||
{
|
||||
"art": "PT",
|
||||
"x": 81269.916932,
|
||||
"y": 0.0,
|
||||
"z": 355.289671
|
||||
},
|
||||
{
|
||||
"art": "REAL",
|
||||
"wert": 355.3
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "90"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
},
|
||||
{
|
||||
"art": "SEGS",
|
||||
"wert": "Linie|90|5854.769733|0|links|80000|0|80000|5854.769733;Bogen|90|707.106781|90|rechts|80000|5854.769733|80500|6354.769733;Linie|0|269.916931|0|links|80500|6354.769733|80769.916932|6354.769733;Bogen|0|707.106781|90|rechts|80769.916932|6354.769733|81269.916932|5854.769733;Linie|-90|5854.769733|0|links|81269.916932|5854.769733|81269.916932|0"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "m2v2"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "vf"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "vario-kurve"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "aussen"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "vario-kurve"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "aussen"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "mit-gf1"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "3"
|
||||
},
|
||||
{
|
||||
"art": "INT",
|
||||
"wert": 2
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
}
|
||||
]
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
[
|
||||
{
|
||||
"beschreibung": "Linienzug Modus 2, GEFALTETER Lauf (U-Form), GF-Verteilung 2 (1/2 GF1 + 1/2 GF2). DAS ist der Lauf, an dem die Laengenbilanz des gefalteten Laufs entwickelt und gemessen wurde: 1424 -> 934 -> 402 -> 0.56 mm quer (9 Grad). Er deckt alle vier Teilstuecke zugleich ab - Eingangs-Hardware im fremden Schenkel, kletter-ende-fp, GF1-Fremdanteil (Nachrechner) und das unterdrueckte Fueller-A. Aufgezeichnet 2026-10-29 aus einem echten BricsCAD-Lauf. Startpunkt fuer die Testreihe versetzt: alle Koordinaten (Start-/Zielpunkt und Pfadsegmente) um einen gemeinsamen Vektor verschoben, damit TEST_LINIENZUG_MODUS2 die Ketten nebeneinander auf einer Grundlinie baut statt verstreut. Reine Translation - Laengen, Winkel und die geprueften Abweichungen sind davon unabhaengig; Z bleibt unveraendert, weil die Starthoehe ein Eingabewert des Solvers ist.",
|
||||
"test_id": "LZ_M2_uform_halb",
|
||||
"kurz": "U-Form, GF 1/2+1/2",
|
||||
"erwartung_quer_mm": 0,
|
||||
"erwartung_dz_mm": 0,
|
||||
"erwartung_laengs_mm": 638,
|
||||
"erwartung_hinweis": "quer zur ES-KS_AUS-Achse MUSS ~0 sein und dZ ~0; laengs darf abweichen - das ist die Ausladung des ES-Elements und kein Fehler. Der laengs-Wert von rund 638 mm ist die Ausladung des ES_Element_90_links und in allen drei U-Form-Faellen gleich; geprueft werden nur quer und dZ."
|
||||
},
|
||||
{
|
||||
"art": "PT",
|
||||
"x": 100000.0,
|
||||
"y": 0.0,
|
||||
"z": 710.579341
|
||||
},
|
||||
{
|
||||
"art": "REAL",
|
||||
"wert": 710.6
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "90"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
},
|
||||
{
|
||||
"art": "PT",
|
||||
"x": 101269.916932,
|
||||
"y": -1951.333591,
|
||||
"z": 710.579341
|
||||
},
|
||||
{
|
||||
"art": "REAL",
|
||||
"wert": 710.6
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "90"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
},
|
||||
{
|
||||
"art": "SEGS",
|
||||
"wert": "Linie|90|5854.769733|0|links|100000|0|100000|5854.769733;Bogen|90|707.106781|90|rechts|100000|5854.769733|100500|6354.769733;Linie|0|269.916931|0|links|100500|6354.769733|100769.916932|6354.769733;Bogen|0|707.106781|90|rechts|100769.916932|6354.769733|101269.916932|5854.769733;Linie|-90|7806.103325|0|links|101269.916932|5854.769733|101269.916932|-1951.333591"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "m2v2"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "vf"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "vario-kurve"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "aussen"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "vario-kurve"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "aussen"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "mit-gf1"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "3"
|
||||
},
|
||||
{
|
||||
"art": "INT",
|
||||
"wert": 2
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "2"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,99 @@
|
||||
[
|
||||
{
|
||||
"beschreibung": "Linienzug Modus 2, GEFALTETER Lauf (U-Form) wie LZ_M2_uform_halb, aber mit der naechststeileren Winkel-Option. Der Restfehler der alten Bilanz skalierte mit L_GF und damit mit dem Winkel (6 Grad: 90 mm, 9 Grad: 934 mm) - zwei Winkel auf derselben Pfadfamilie sichern deshalb mehr ab als zwei Laeufe mit demselben. Aufgezeichnet 2026-10-29 aus einem echten BricsCAD-Lauf. Startpunkt fuer die Testreihe versetzt: alle Koordinaten (Start-/Zielpunkt und Pfadsegmente) um einen gemeinsamen Vektor verschoben, damit TEST_LINIENZUG_MODUS2 die Ketten nebeneinander auf einer Grundlinie baut statt verstreut. Reine Translation - Laengen, Winkel und die geprueften Abweichungen sind davon unabhaengig; Z bleibt unveraendert, weil die Starthoehe ein Eingabewert des Solvers ist.",
|
||||
"test_id": "LZ_M2_uform_halb_steil",
|
||||
"kurz": "U-Form, GF 1/2+1/2, steilere Winkel-Option",
|
||||
"erwartung_quer_mm": 0,
|
||||
"erwartung_dz_mm": 0,
|
||||
"erwartung_laengs_mm": 638,
|
||||
"erwartung_hinweis": "quer zur ES-KS_AUS-Achse MUSS ~0 sein und dZ ~0; laengs darf abweichen - das ist die Ausladung des ES-Elements und kein Fehler. Der laengs-Wert von rund 638 mm ist die Ausladung des ES_Element_90_links und in allen drei U-Form-Faellen gleich; geprueft werden nur quer und dZ."
|
||||
},
|
||||
{
|
||||
"art": "PT",
|
||||
"x": 120000.0,
|
||||
"y": 0.0,
|
||||
"z": 709.285191
|
||||
},
|
||||
{
|
||||
"art": "REAL",
|
||||
"wert": 709.3
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "90"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
},
|
||||
{
|
||||
"art": "PT",
|
||||
"x": 121269.916932,
|
||||
"y": 0.077406,
|
||||
"z": 709.275779
|
||||
},
|
||||
{
|
||||
"art": "REAL",
|
||||
"wert": 709.3
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "90"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
},
|
||||
{
|
||||
"art": "SEGS",
|
||||
"wert": "Linie|90|5854.769733|0|links|120000|-21.403816|120000|5833.365917;Bogen|90|707.106781|90|rechts|120000|5833.365917|120500|6333.365917;Linie|0|269.916931|0|links|120500|6333.365917|120769.916932|6333.365917;Bogen|0|707.106781|90|rechts|120769.916932|6333.365917|121269.916932|5833.365917;Linie|-90|5854.769733|0|links|121269.916932|5833.365917|121269.916932|-21.403816"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "m2v2"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "vf"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "vario-kurve"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "aussen"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "vario-kurve"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "aussen"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "mit-gf1"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "3"
|
||||
},
|
||||
{
|
||||
"art": "INT",
|
||||
"wert": 3
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "2"
|
||||
}
|
||||
]
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
[
|
||||
{
|
||||
"beschreibung": "Linienzug Modus 2, Variante A: 90-Grad-Ecke als VARIO-KURVE (waagerecht eingebaut), Segment 3 dadurch automatisch VF. Deckt die flache Zone ab (Abschluss-Fussabdruck Bogen+Motorstation) und die Eck-Korrektur von 93.8 mm je Nachbargerade. Aufgezeichnet 2026-10-27 aus einem echten BricsCAD-Lauf. Startpunkt fuer die Testreihe versetzt: alle Koordinaten (Start-/Zielpunkt und Pfadsegmente) um einen gemeinsamen Vektor verschoben, damit TEST_LINIENZUG_MODUS2 die Ketten nebeneinander auf einer Grundlinie baut statt verstreut. Reine Translation - Laengen, Winkel und die geprueften Abweichungen sind davon unabhaengig; Z bleibt unveraendert, weil die Starthoehe ein Eingabewert des Solvers ist.",
|
||||
"test_id": "LZ_M2_variokurve",
|
||||
"kurz": "Ecke als Vario-Kurve",
|
||||
"erwartung_quer_mm": 0,
|
||||
"erwartung_dz_mm": 0,
|
||||
"erwartung_laengs_mm": 105,
|
||||
"erwartung_hinweis": "quer zur ES-KS_AUS-Achse MUSS ~0 sein und dZ ~0; laengs darf abweichen - das ist die Ausladung des ES-Elements und kein Fehler. Beides zugleich geht nicht: entweder liegt die letzte Gerade auf der gezeichneten Linie und der KS_AUS landet seitlich daneben, oder umgekehrt. Entschieden ist - der Hauptstrang bleibt gerade."
|
||||
},
|
||||
{
|
||||
"art": "PT",
|
||||
"x": 40000.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
{
|
||||
"art": "REAL",
|
||||
"wert": 0.0
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "90"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
},
|
||||
{
|
||||
"art": "PT",
|
||||
"x": 51000.0,
|
||||
"y": -6315.123197,
|
||||
"z": 184.3
|
||||
},
|
||||
{
|
||||
"art": "REAL",
|
||||
"wert": 184.3
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "30"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "2"
|
||||
},
|
||||
{
|
||||
"art": "SEGS",
|
||||
"wert": "Linie|0|9700|0|links|40000|0|49700|0;Bogen|0|707.106781|90|rechts|49700|0|50200|-500;Linie|-90|4295.507955|0|links|50200|-500|50200|-4795.507955;Bogen|-90|258.819045|30|links|50200|-4795.507955|50266.987298|-5045.507955;Linie|-60|1466.025404|0|links|50266.987298|-5045.507955|51000|-6315.123197"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "m2v2"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "2"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "2"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
},
|
||||
{
|
||||
"art": "REAL",
|
||||
"wert": 3.0
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "2"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "2"
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "mit-gf1"
|
||||
},
|
||||
{
|
||||
"art": "INT",
|
||||
"wert": 1
|
||||
},
|
||||
{
|
||||
"art": "STR",
|
||||
"wert": "1"
|
||||
}
|
||||
]
|
||||
Vendored
+11
-2
@@ -8,14 +8,19 @@
|
||||
},
|
||||
{
|
||||
"typ": "point_abs",
|
||||
"wert": [-1289.407125, 95.871332, 2154],
|
||||
"kommentar": "getpoint Startpunkt der Kette"
|
||||
"wert": [0.0, 0.0, 2154],
|
||||
"kommentar": "getpoint Startpunkt der Kette - fuer die Testreihe auf X=0/Y=0 versetzt, damit die Ketten aller Linienzug-Tests nebeneinander auf einer Grundlinie entstehen statt verstreut. Unkritisch, weil dies der EINZIGE absolute Punkt des Skripts ist: alle weiteren Punkte sind relativ (point_rel mit dL/hz), die Geometrie also unveraendert. Z bleibt stehen - das ist die Starthoehe und ein echter Eingabewert."
|
||||
},
|
||||
{
|
||||
"typ": "real",
|
||||
"wert": 2154.0,
|
||||
"kommentar": "getreal Hoehe (Z) Startpunkt"
|
||||
},
|
||||
{
|
||||
"typ": "string",
|
||||
"wert": "1",
|
||||
"kommentar": "getstring Bau-Richtung (1 = vorwaerts) - seit 2026-10-25 (Commit fb56794, Rueckwaerts-Bau). Die Frage steht VOR der AS-Praeambel. Fuer JOURNALE ist sie abwaertskompatibel (fehlt der Eintrag, gilt das Journal als Alt-Format), fuer dieses MOCK-Skript aber nicht: der Mock beantwortet jede getstring-Abfrage aus der Queue, eine fehlende Antwort verschiebt also alles Folgende um eine Position. Sichtbar wurde das als Abbruch in cdr mit dem String 5, weil die Achsen-Punktabfrage dann diesen String zog statt eines Punktes."
|
||||
},
|
||||
{
|
||||
"typ": "string",
|
||||
"wert": "1",
|
||||
@@ -31,6 +36,10 @@
|
||||
"wert": "1",
|
||||
"kommentar": "getstring AS-Seite (links)"
|
||||
},
|
||||
{
|
||||
"typ": "point_none",
|
||||
"kommentar": "getpoint AS-Zufuehrungsachse (2. Punkt, optional seit 2026-10-21) - Enter ohne Punkt, Kette laeuft wie frueher ueber den naechsten Klick"
|
||||
},
|
||||
{
|
||||
"typ": "string",
|
||||
"wert": "5",
|
||||
|
||||
+11
-2
@@ -8,14 +8,19 @@
|
||||
},
|
||||
{
|
||||
"typ": "point_abs",
|
||||
"wert": [21377.904954, -10300, 2067],
|
||||
"kommentar": "getpoint Startpunkt der Kette"
|
||||
"wert": [20000.0, 0.0, 2067],
|
||||
"kommentar": "getpoint Startpunkt der Kette - fuer die Testreihe auf X=20000/Y=0 versetzt, damit die Ketten aller Linienzug-Tests nebeneinander auf einer Grundlinie entstehen statt verstreut. Unkritisch, weil dies der EINZIGE absolute Punkt des Skripts ist: alle weiteren Punkte sind relativ (point_rel mit dL/hz), die Geometrie also unveraendert. Z bleibt stehen - das ist die Starthoehe und ein echter Eingabewert."
|
||||
},
|
||||
{
|
||||
"typ": "real",
|
||||
"wert": 2154.0,
|
||||
"kommentar": "getreal Hoehe (Z) Startpunkt"
|
||||
},
|
||||
{
|
||||
"typ": "string",
|
||||
"wert": "1",
|
||||
"kommentar": "getstring Bau-Richtung (1 = vorwaerts) - seit 2026-10-25 (Commit fb56794, Rueckwaerts-Bau). Siehe gleichlautenden Eintrag in linienzug_tests.json: fuer Journale abwaertskompatibel, fuer dieses Mock-Skript nicht."
|
||||
},
|
||||
{
|
||||
"typ": "string",
|
||||
"wert": "1",
|
||||
@@ -31,6 +36,10 @@
|
||||
"wert": "1",
|
||||
"kommentar": "getstring AS-Seite (links)"
|
||||
},
|
||||
{
|
||||
"typ": "point_none",
|
||||
"kommentar": "getpoint AS-Zufuehrungsachse (2. Punkt, optional seit 2026-10-21) - Enter ohne Punkt"
|
||||
},
|
||||
{
|
||||
"typ": "string",
|
||||
"wert": "5",
|
||||
|
||||
Vendored
+2
-1
@@ -8,6 +8,7 @@
|
||||
"abstand": 5000,
|
||||
"rotation": 0.0,
|
||||
"typ": "STANDARD",
|
||||
"drehrichtung": "GUZ",
|
||||
"expect_block_prefix": "KREISEL_",
|
||||
"expect_hoehe": "1554",
|
||||
"expect_kreiselart": "STANDARD",
|
||||
@@ -22,7 +23,7 @@
|
||||
"abstand": 20015,
|
||||
"rotation": 90.0,
|
||||
"typ": "STANDARD",
|
||||
"drehrichtung": "GUZ",
|
||||
"drehrichtung": "UZS",
|
||||
"expect_block_prefix": "KREISEL_",
|
||||
"expect_hoehe": "1554",
|
||||
"expect_kreiselart": "STANDARD",
|
||||
|
||||
Reference in New Issue
Block a user