;; ============================================================ ;; test_dematic_arvato.lsp - Nachbau des Abschnitts Flowpuffer/Kreisel der ;; Anlage Dematic/Arvato. ;; ;; Datenquelle: tests/testdata/dematic_arvato.json. Entstehung in zwei ;; Stufen: ;; 1. Vorlage aus der Fremdzeichnung (Scanner, raet vieles): ;; python lib/dxf_scan_components.py \ ;; C:/develop/sps_skel/data/Dematic_arvato_reduced.dxf data \ ;; tests/testdata/dematic_arvato.json --projekt Arvato \ ;; --fenster -2534 -4549 49466 29451 --ohne-hoehen \ ;; --kreisel-hoehe 35860.37 12519.72 2437 \ ;; --kreisel-hoehe 36661.24 24878.8 1826 ;; 2. Vorlage mit diesem Treiber bauen, in BricsCAD von Hand korrigieren ;; und ergaenzen (VF-Ketten, Hoehen, Sensoren aufgeraeumt), als DXF ;; speichern und daraus die Testdaten neu schreiben - AKTUELLER STAND: ;; python lib/dxf_anlage_export.py \ ;; C:/develop/sps_skel/data/Dematic_TST.dxf \ ;; tests/testdata/dematic_arvato.json --projekt Arvato ;; ;; Eintragsarten: ;; "function": "insert" ohne "block" -> Kreisel (hundm05:bau-kreisel -> ;; kreisel-insert-script; x/y = Einfuegepunkt, ;; abstand = Mittenabstand AN8-SP8) ;; "function": "insert" + "block" -> Einzelblock (hundm05:bau-sensor) ;; "typ": "standard"/"etage" + "test_id" ;; -> VarioFoerderer ueber mubea:vario-bauen ;; (mubea-Schema: deltaL, deltaH, richtung, ;; winkel, L_GF1, seite, hz, x/y/z), optional ;; "motorseite" ;; "typ": "linienzug_journal" ;; -> Linienzug-Kette: das aufgezeichnete Eingabe- ;; Journal (SSG_VF_EDIT) wird 1:1 abgespielt ;; (vsp-bau-journal) - keine Spec, weil der ;; Dialog neuer ist als die Spec-Grammatik ;; "modus": 1 -> Gefaellestrecke ueber mubea:gf-bauen ;; (start_mm + deltaL_mm, kein Endpunkt). Mit ;; hoehe_ende_mm (Hoehe des Kreisels am Ende) ;; rechnet dematic_arvato:gf-winkel den Winkel, ;; sonst gilt winkel_grad. ;; "typ": "gerade" -> waagrechter Foerderer aus der Scanner-Vorlage - ;; kein Bau-Pfad, wird gemeldet und uebersprungen ;; ;; Reihenfolge wie mubea.json (VF vor GF): gf-init-bibliothek setzt die ;; globalen AS/ES-Masse um, siehe mubea:ensure-gf-init. ;; ;; Keine eigene Bau-Logik: hundm05:bau-kreisel/-sensor aus ;; tests/test_hundm05.lsp und mubea:gf-bauen/-vario-bauen aus ;; tests/test_mubea.lsp werden mitgeladen (beide Dateien definieren nur ;; Funktionen), Linienzug-Ketten laufen ueber vsp-bau-journal (vf_spec.lsp). ;; ;; Aufruf in BricsCAD: ;; (load (strcat (getenv "DXFMAKRO") "/tests/test_dematic_arvato.lsp")) ;; TEST_DEMATIC_ARVATO ;; ============================================================ (if (not (boundp '*dematic-arvato-records*)) (setq *dematic-arvato-records* nil)) ;; Module und die Bau-Funktionen aus test_hundm05.lsp beim LADEN dieser Datei ;; holen, nicht erst in c:TEST_DEMATIC_ARVATO: in BricsCAD werden per load ;; definierte Funktionen erst nach Rueckkehr zum Top-Level sichtbar (siehe ;; tests/test_unit.scr). (ssg-ensure "KreiselInsert") (ssg-ensure "VarioFoerderer") (ssg-ensure "SSG_LIB_Commands") (ssg-ensure "Gefaellestrecke") (if (null (car (atoms-family 1 '("HUNDM05:BAU-SENSOR")))) (load (strcat (getenv "DXFMAKRO") "/tests/test_hundm05.lsp"))) (if (null (car (atoms-family 1 '("MUBEA:VARIO-BAUEN")))) (load (strcat (getenv "DXFMAKRO") "/tests/test_mubea.lsp"))) (defun dematic_arvato:datei () (strcat (getenv "DXFMAKRO") "/tests/testdata/dematic_arvato.json")) ;; Record um den gebauten Block ergaenzen (oder als Abbruch markieren). (defun dematic_arvato:rec-block (rec ent fehlertext / ed) (if (and ent (= (type ent) 'ENAME)) (progn (setq ed (entget ent)) (princ (strcat " -> Block " (cdr (assoc 2 ed)))) (setq rec (vsp-set rec "block_name" (cdr (assoc 2 ed)))) (setq rec (vsp-set rec "block_handle" (cdr (assoc 5 ed)))) (setq rec (vsp-set rec "insert_point" (cdr (assoc 10 ed)))) (setq rec (vsp-set rec "attribs" (ssg-attrib-read ent))) (vsp-set rec "status" "executed")) (progn (princ (strcat " FEHLER: " fehlertext)) (vsp-set (vsp-set rec "status" "abbruch") "fehler_text" fehlertext)))) ;; Foerderer "gerade": noch kein Bau-Pfad - nur melden. (defun dematic_arvato:gerade-melden (obj / tid rec) (setq tid (ssg-val obj "test_id")) (princ (strcat "\n [GERADE] " (if tid tid "?") " uebersprungen - waagrechter Foerderer noch nicht unterstuetzt")) (setq rec (vsp-rec-neu (if tid tid "(ohne id)"))) (setq rec (vsp-set rec "kind" "gerade")) (vsp-set (vsp-set rec "status" "uebersprungen") "fehler_text" "kein Bau-Pfad fuer typ gerade")) ;; Gefaellewinkel aus Start- und Endhoehe - derselbe Loeser wie Modus 3 ;; (gf-winkel-berechnen, Gefaellestrecke.lsp) mit den AS/ES-Massen der ;; aktuellen 2D/3D-Bibliothek. Die Kette ist eine einzige Gerade plus der ;; eine Separator vor dem ES (extra-sep 1); ihre Laenge ohne AS/ES/Separator ;; ist deltaL - aus-dx - ein-dx - 300, damit ergibt der Loeser als ;; Gesamtlaenge wieder genau deltaL (deltaL reicht von AS- bis ES-Ursprung). ;; VORZEICHEN: vf-set-as-masse (vf_core) misst dz als KS_AUS.z - KS_EIN.z ;; (bei AS/ES negativ), gf-winkel-berechnen erwartet die Konvention von ;; gf-init-bibliothek (KS_EIN.z - KS_AUS.z, positiv) und zieht den Wert ab. ;; Mit der VF-Konvention wurde der feste AS/ES-Abfall addiert statt ;; abgezogen - real gebaut: 3.79 statt ~2.49 Grad, GF endete 258 mm unter ;; dem Kreisel (HOEHE_BIS 1568 statt 1826). Darum hier der Betrag. (defun dematic_arvato:gf-winkel (deltaL hz as-seite es-seite as-winkel es-winkel z-start z-ende / winkel) (mubea:ensure-gf-init) (vf-set-as-masse as-winkel as-seite) (vf-set-es-masse es-winkel es-seite) (setq aus-dz (abs (float aus-dz)) ein-dz (abs (float ein-dz))) (setq winkel (gf-winkel-berechnen (list (list "Linie" hz (- deltaL (float aus-dx) (float ein-dx) 300.0) 0 "links")) (- z-start z-ende) 1)) (vf-set-as-masse "90" as-seite) (vf-set-es-masse "90" es-seite) winkel) ;; Gefaellestrecke (Modus 1) bauen - Felder wie mubea:build-gf, ohne dessen ;; anzahl/delta-Vervielfaeltigung (jede GF steht einzeln in der Datei). ;; Mit "hoehe_ende_mm" (Hoehe des Kreisels am Ende) wird der Winkel daraus ;; gerechnet, sonst gilt "winkel_grad" (Default 3.0). (defun dematic_arvato:bau-gf (obj / tid start deltaL hz winkel z-ende as-seite es-seite as-winkel es-winkel rec) (setq tid (ssg-val obj "test_id") start (ssg-val obj "start_mm") deltaL (ssg-val obj "deltaL_mm") hz (ssg-val obj "hz_grad") winkel (ssg-val obj "winkel_grad") z-ende (ssg-val obj "hoehe_ende_mm") as-seite (cond ((ssg-val obj "as_seite")) ("links")) es-seite (cond ((ssg-val obj "es_seite")) ("links")) as-winkel (cond ((ssg-val obj "as_winkel")) ("90")) es-winkel (cond ((ssg-val obj "es_winkel")) ("90"))) (setq rec (vsp-rec-neu (if tid tid "(ohne id)"))) (setq rec (vsp-set rec "kind" "gefaellestrecke")) (setq rec (vsp-set rec "dimension" (vsp-dim-text))) (cond ((not (and (= (type start) 'LIST) (= (length start) 3) (numberp deltaL) (numberp hz))) (princ (strcat "\n [GF] " (if tid tid "?") " - FEHLER: start_mm, deltaL_mm und hz_grad muessen gesetzt sein")) (vsp-set (vsp-set rec "status" "spec-fehler") "fehler_text" "start_mm, deltaL_mm oder hz_grad fehlt bzw. ist ungueltig")) ((and (numberp z-ende) (>= z-ende (caddr start))) (princ (strcat "\n [GF] " (if tid tid "?") " - FEHLER: hoehe_ende_mm liegt nicht unter der Starthoehe")) (vsp-set (vsp-set rec "status" "spec-fehler") "fehler_text" "hoehe_ende_mm >= start_mm.z - kein Gefaelle")) (T (setq winkel (cond ((numberp z-ende) (dematic_arvato:gf-winkel (float deltaL) (float hz) as-seite es-seite as-winkel es-winkel (float (caddr start)) (float z-ende))) ((numberp winkel) (float winkel)) (T 3.0))) ;; Winkel und Soll-Endhoehe als Meldung (das Record-Schema aus vf_spec ;; kennt dafuer kein Feld); die Ist-Endhoehe steht in attribs HOEHE_BIS. (setq rec (vsp-set rec "meldungen" (list (strcat "winkel_grad " (rtos winkel 2 3) (if (numberp z-ende) (strcat " aus Hoehe " (rtos (caddr start) 2 1) " -> " (rtos z-ende 2 1)) ""))))) (dematic_arvato:rec-block rec (mubea:gf-bauen tid (mapcar 'float start) (float deltaL) (float hz) as-seite es-seite as-winkel es-winkel winkel) "gefaellestrecke-einfuegen lieferte keinen GF-Block")))) ;; VarioFoerderer "standard"/"etage" - mubea-Schema, Bau ueber ;; mubea:vario-bauen. "motorseite" wirkt wie im Edit-Dialog ueber den ;; Override *vf-motorseite* (vf-block-erstellen liest ihn). (defun dematic_arvato:bau-vf (obj / tid typ rec ent) (setq tid (ssg-val obj "test_id") typ (cond ((ssg-val obj "typ")) ("standard"))) (setq rec (vsp-rec-neu (if tid tid "(ohne id)"))) (setq rec (vsp-set rec "kind" "vario")) (setq rec (vsp-set rec "dimension" (vsp-dim-text))) (setq *vf-motorseite* (ssg-val obj "motorseite")) (setq ent (vl-catch-all-apply 'mubea:vario-bauen (list tid typ (ssg-val obj "richtung") (float (ssg-val obj "deltaL")) (float (ssg-val obj "deltaH")) (ssg-val obj "winkel") (float (cond ((ssg-val obj "L_GF1")) (0.0))) (ssg-val obj "seite") (ssg-val obj "hz") (list (float (ssg-val obj "x")) (float (ssg-val obj "y")) (float (ssg-val obj "z")))))) (setq *vf-motorseite* nil) (if (vl-catch-all-error-p ent) (vsp-set (vsp-set rec "status" "abbruch") "fehler_text" (vl-catch-all-error-message ent)) (dematic_arvato:rec-block rec ent "kein VF-Block (deltaL beim gewuenschten Winkel nicht loesbar?)"))) ;; Linienzug-Kette: aufgezeichnetes Journal ("ART:wert"-Tokens, wie in der ;; SSG_VF_EDIT-XDATA) 1:1 abspielen. Headless-Rahmen wie vsp-bau-datei; er ;; MUSS auch nach einem Fehler zurueck, sonst bleiben getstring/getpoint der ;; Sitzung ersetzt. (defun dematic_arvato:bau-journal (obj / tid journal res) (setq tid (cond ((ssg-val obj "test_id")) ("(ohne id)"))) (setq journal (mapcar 'vfl-string->entry (ssg-val obj "journal"))) (vsp-headless-an) (setq res (vl-catch-all-apply 'vsp-bau-journal (list tid journal nil (if journal nil (list "Feld \"journal\" fehlt oder ist leer"))))) (vsp-headless-aus) (if (vl-catch-all-error-p res) (vsp-set (vsp-set (vsp-rec-neu tid) "status" "abbruch") "fehler_text" (vl-catch-all-error-message res)) res)) (defun dematic_arvato:bau-eintrag (obj / kind res typ) (setq typ (ssg-val obj "typ")) (cond ((ssg-val obj "modus") (setq kind "gefaellestrecke") (setq res (vl-catch-all-apply 'dematic_arvato:bau-gf (list obj)))) ((= typ "linienzug_journal") (setq kind "linienzug") (setq res (dematic_arvato:bau-journal obj))) ((and (member typ '("standard" "etage")) (ssg-val obj "test_id")) (setq kind "vario") (setq res (dematic_arvato:bau-vf obj))) ((and (= (ssg-val obj "function") "insert") (ssg-val obj "block")) (setq kind "sensor") (setq res (vl-catch-all-apply 'hundm05:bau-sensor (list obj)))) ((= (ssg-val obj "function") "insert") (setq kind "kreisel") (setq res (vl-catch-all-apply 'hundm05:bau-kreisel (list obj)))) ((= typ "gerade") (setq kind "gerade") (setq res (dematic_arvato:gerade-melden obj))) (T (setq kind "unbekannt") (princ "\n WARNUNG: unbekannter Eintrag uebersprungen") (setq res (vsp-set (vsp-rec-neu "(unbekannt)") "status" "uebersprungen")))) (if (vl-catch-all-error-p res) (progn (princ (strcat "\n [" (strcase kind) "] Ausnahme: " (vl-catch-all-error-message res))) (vsp-set (vsp-set (vsp-set (vsp-rec-neu (cond ((ssg-val obj "id")) ((ssg-val obj "test_id")) ((ssg-val obj "block")) ("?"))) "kind" kind) "status" "abbruch") "fehler_text" (vl-catch-all-error-message res))) res)) (defun c:TEST_DEMATIC_ARVATO ( / datei daten out zaehler st) (setq datei (dematic_arvato:datei)) (princ "\n\n================================================================") (princ "\n TEST_DEMATIC_ARVATO - Abschnitt Flowpuffer/Kreisel") (princ (strcat "\n " datei)) (princ "\n================================================================") (cond ((null (car (atoms-family 1 '("VSP-BAU-JOURNAL")))) (princ "\n[TEST_DEMATIC_ARVATO] FEHLER: vf_spec.lsp nicht geladen" " (VarioFoerderer laden).") (setq *dematic-arvato-records* nil)) ((null (findfile datei)) (princ (strcat "\n[TEST_DEMATIC_ARVATO] FEHLER: " datei " nicht gefunden!")) (setq *dematic-arvato-records* nil)) (T (setq daten (ssg-json-laden datei)) (princ (strcat "\n " (itoa (length daten)) " Eintraege geladen")) (ssg-start "TEST_DEMATIC_ARVATO" '(("OSMODE") ("CECOLOR") ("ATTREQ") ("ATTDIA"))) (setvar "OSMODE" 0) (setvar "ATTREQ" 0) (setvar "ATTDIA" 0) ;; Vario-Bibliothek (Bogen-/AS-/ES-Masse) wie C:TEST_MUBEA, und die ;; GF-Elementmasse in jeder Zeichnung neu ermitteln. (if (vsp-lib-noetig-p) (init-bibliothek)) (setq *mubea-gf-init-done* nil) (setq out '()) (foreach obj daten (setq out (cons (dematic_arvato:bau-eintrag obj) out))) (ssg-end) (setq *dematic-arvato-records* (reverse out)) ;; Zusammenfassung je Status (setq zaehler '()) (foreach r *dematic-arvato-records* (setq st (cond ((ssg-val r "status")) ("?"))) (if (assoc st zaehler) (setq zaehler (subst (cons st (1+ (cdr (assoc st zaehler)))) (assoc st zaehler) zaehler)) (setq zaehler (cons (cons st 1) zaehler)))) (princ "\n================================================================") (foreach z (reverse zaehler) (princ (strcat "\n " (car z) ": " (itoa (cdr z))))) (princ "\n================================================================") (command "_.ZOOM" "_E"))) (princ)) ;; Ergebnis-Export (Konvention :export-results fuer test_run_all.lsp) (defun dematic_arvato:export-results (out-dir / pfad) (if (null *dematic-arvato-records*) (princ "\n Keine Dematic/Arvato-Ergebnisse vorhanden.") (progn (vl-mkdir out-dir) (setq pfad (strcat out-dir "/dematic_arvato_results.json")) (vsp-results-schreiben *dematic-arvato-records* pfad))) (princ)) (princ "\nTEST_DEMATIC_ARVATO geladen. Aufruf: TEST_DEMATIC_ARVATO") (princ)