;; ============================================================ ;; test_hundm05.lsp - Integrationstest: baut die 5 VarioFoerderer-Linienzuege ;; der Anlage HundM (Kreisel mit fuenf daran haengenden Ketten) aus ihrer ;; SPEC nach. ;; ;; Datenquelle: tests/testdata/hundm05.json - die Ketten im Spec-Format ;; (Domaenenwerte statt Menue-Codes, siehe Lisp/vf_spec.lsp und ;; doc/variofoerderer.md Abschnitt 8b). Erzeugt aus den echten ;; Aufzeichnungen mit ;; python lib/vf_spec_export.py tests/testdata/hm_recformat.json \ ;; tests/testdata/hundm05.json ;; und damit nachweislich dasselbe Journal wie die Vorlage ;; (Rundlauf-Beweis in tests/test_vf_spec.py). Die Datei ist die Stelle, an ;; der weitere Ketten der Anlage nachgetragen werden. ;; ;; Dieser Test hat KEINE eigene Bau-Logik: er ruft vsp-bau-datei aus ;; Lisp/vf_spec.lsp - denselben Weg, den auch der Befehl VF_SPEC_BAU nimmt. ;; Es gibt also genau einen Code-Pfad, der aus einer Spec Geometrie erzeugt. ;; ;; ABGRENZUNG zu TEST_HM_RECFORMAT (tests/test_hm_recformat.lsp): dort werden ;; dieselben Ketten aus dem ROHEN Journal der Kundenzeichnung gebaut. Das ist ;; der Regressionstest fuer das Aufzeichnungsformat (bleibt ein bestehender ;; VF_n-Block abspielbar - Doppelklick-Edit, 2D/3D-Konvertierung?) und ;; deshalb dort auf "disabled": true, um nicht zweimal dieselbe Geometrie zu ;; bauen. ;; ;; Voraussetzung: ;; - SSG_LIB geladen (VarioFoerderer inkl. vf_linienzug + vf_spec, ;; Gefaellestrecke, ssg_core, ssg_dbg) ;; - Umgebungsvariable DXFMAKRO gesetzt ;; ;; Speichert (via SSG_RUN_ALL_TESTS bei "save":"dxf"): ;; tests/output/hundm05_tests.dxf ;; tests/output/hundm05_results.json (via hundm05:export-results) ;; ;; Aufruf in BricsCAD: ;; (load (strcat (getenv "DXFMAKRO") "/tests/test_hundm05.lsp")) ;; TEST_HUNDM05 ; in der aktuellen Dimension (ssg-ils-dim-aktuell) ;; TEST_HUNDM05_2D ; erzwungen 2D ;; TEST_HUNDM05_3D ; erzwungen 3D ;; ============================================================ (if (not (boundp '*hundm05-records*)) (setq *hundm05-records* nil)) (defun hundm05:spec-datei () (strcat (getenv "DXFMAKRO") "/tests/testdata/hundm05.json")) ;; ============================================================ ;; Weitere Objekte der Anlage (nicht-Ketten) ;; ============================================================ ;; Neben den Spec-Ketten (Kopf "spec_id" + "glied"/"sub") duerfen in ;; 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). ;; 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). ;; ;; Bisher unterstuetzt: Kreisel (function "insert", wie test_kreisel.lsp). ;; Weitere Arten kommen als eigener cond-Zweig dazu. (defun hundm05:zusatz-objekt-p (obj) (and (ssg-val obj "function") (null (ssg-val obj "spec_id")) (null (ssg-val obj "glied")) (null (ssg-val obj "sub")))) ;; Kreisel bauen (kreisel-insert-script wie in tests/test_kreisel.lsp). ;; Rueckgabe: Ergebnis-Record in derselben Form wie die Ketten, damit ;; vsp-results-schreiben beide in EINE Datei schreibt (unterschieden ueber ;; das Feld "kind"). (defun hundm05:bau-kreisel (obj / id x y z abstand rotation typ pt ent ed rec) (setq id (ssg-val obj "id")) (setq x (ssg-val obj "x") y (ssg-val obj "y") z (ssg-val obj "z") abstand (ssg-val obj "abstand") rotation (ssg-val obj "rotation") typ (ssg-val obj "typ")) (if (numberp x) (setq x (float x))) (if (numberp y) (setq y (float y))) (if (numberp z) (setq z (float z))) (if (numberp abstand) (setq abstand (float abstand))) (if (numberp rotation) (setq rotation (float rotation))) (if (null typ) (setq typ "STANDARD")) (setq rec (vsp-rec-neu (if id id "(ohne id)"))) (setq rec (vsp-set rec "kind" "kreisel")) (setq rec (vsp-set rec "dimension" (vsp-dim-text))) (cond ((not (and (numberp x) (numberp y) (numberp abstand))) (princ (strcat "\n [KREISEL] " (if id id "?") " - FEHLER: x, y und abstand muessen Zahlen sein")) (vsp-set (vsp-set rec "status" "spec-fehler") "fehler_text" "x, y oder abstand fehlt bzw. ist keine Zahl")) (T (setq pt (list x y z)) (princ (strcat "\n [KREISEL] " id " -> (" (rtos x 2 0) ", " (rtos y 2 0) ", " (rtos (if z z 0.0) 2 0) ") A=" (rtos abstand 2 0) " R=" (rtos (if rotation rotation 0.0) 2 1) " " typ)) (setq ent (kreisel-insert-script pt abstand (if rotation rotation 0.0) typ z)) (if ent (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 " FEHLER: kein Kreisel-Block entstanden") (vsp-set (vsp-set rec "status" "abbruch") "fehler_text" "kreisel-insert-script lieferte nil")))))) ;; Alle Zusatzobjekte der Datei bauen. Eigener ssg-start-Rahmen, weil ;; vsp-bau-datei seinen schon geschlossen hat; ATTREQ/ATTDIA 0 ist Pflicht - ;; sonst fragt (command "_.INSERT" ...) nach Attributwerten. (defun hundm05:bau-zusatzobjekte (datei / daten objekte out rec) (setq daten (ssg-load-json datei)) (setq objekte '()) (foreach obj daten (if (hundm05:zusatz-objekt-p obj) (setq objekte (cons obj objekte)))) (setq objekte (reverse objekte)) (cond ((null objekte) nil) ((null (car (atoms-family 1 '("KREISEL-INSERT-SCRIPT")))) (princ (strcat "\n[TEST_HUNDM05] WARNUNG: " (itoa (length objekte)) " Zusatzobjekt(e) uebersprungen - KreiselInsert nicht" " geladen.")) nil) (T (princ (strcat "\n " (itoa (length objekte)) " weitere(s) Objekt(e) der Anlage")) (ssg-start "TEST_HUNDM05_ZUSATZ" '(("OSMODE") ("CECOLOR") ("ATTREQ") ("ATTDIA"))) (setvar "OSMODE" 0) (setvar "ATTREQ" 0) (setvar "ATTDIA" 0) (setq out '()) (foreach obj objekte (setq rec (vl-catch-all-apply 'hundm05:bau-kreisel (list obj))) (if (vl-catch-all-error-p rec) (progn (princ (strcat "\n [KREISEL] Ausnahme: " (vl-catch-all-error-message rec))) (setq rec (vsp-set (vsp-set (vsp-set (vsp-rec-neu (ssg-val obj "id")) "kind" "kreisel") "status" "abbruch") "fehler_text" (vl-catch-all-error-message rec))))) (setq out (cons rec out))) (ssg-end) (reverse out)))) ;; ============================================================ ;; Testlauf ;; ============================================================ (defun c:TEST_HUNDM05 ( / datei) (setq datei (hundm05:spec-datei)) (princ "\n\n================================================================") (princ "\n TEST_HUNDM05 - Anlage HundM aus der Spec (5 Linienzuege)") (princ (strcat "\n " datei)) (princ "\n================================================================") (cond ((null (car (atoms-family 1 '("VSP-BAU-DATEI")))) (princ "\n[TEST_HUNDM05] FEHLER: vf_spec.lsp nicht geladen" " (VarioFoerderer laden).") (setq *hundm05-records* nil)) ((null (findfile datei)) (princ (strcat "\n[TEST_HUNDM05] FEHLER: " datei " nicht gefunden!")) (setq *hundm05-records* nil)) (T (vsp-modul-sichern "KreiselInsert") (setq *hundm05-records* (vsp-bau-datei datei)) (setq *hundm05-records* (append *hundm05-records* (hundm05:bau-zusatzobjekte datei))))) (princ)) ;; ============================================================ ;; Dieselbe Anlage in einer bestimmten Dimension bauen ;; ============================================================ ;; Die Spec ist dimensionsfrei - sie beschreibt die Eingaben, mit denen die ;; Ketten gebaut wurden. Ob daraus flache 2D-Symbole oder 3D-Modelle werden, ;; entscheidet allein die Blockvariante (_2D/_3D), die ssg-ils-dim-aktuell ;; aufloest. Unsere Bibliothek hat beide, also laesst sich dieselbe Anlage ;; ohne Datenaenderung in 2D ODER 3D aufbauen. ;; *vsp-dim-override* wird von vsp-bau-aus-spec JE KETTE angewandt (der ;; Abbruch-Handler in vf-linienzug-modus setzt *ssg-ils-dim* zurueck). (defun hundm05:mit-dimension (dim / alt) (setq alt (if (boundp '*vsp-dim-override*) *vsp-dim-override*)) (setq *vsp-dim-override* dim) (vl-catch-all-apply 'c:TEST_HUNDM05 '()) (setq *vsp-dim-override* alt) (princ)) (defun c:TEST_HUNDM05_2D () (hundm05:mit-dimension "2D")) (defun c:TEST_HUNDM05_3D () (hundm05:mit-dimension "3D")) ;; ============================================================ ;; Ergebnis-Export (Konvention :export-results fuer test_run_all.lsp) ;; ============================================================ ;; Geschrieben wird hier und nicht in c:TEST_HUNDM05, damit der Testrunner ;; das Zielverzeichnis bestimmt (er uebergibt tests/output). (defun hundm05:export-results (out-dir / pfad) (if (null *hundm05-records*) (princ "\n Keine HundM05-Ergebnisse vorhanden.") (progn (vl-mkdir out-dir) (setq pfad (strcat out-dir "/hundm05_results.json")) (vsp-results-schreiben *hundm05-records* pfad))) (princ)) (princ "\nTEST_HUNDM05 geladen. Aufruf: TEST_HUNDM05 (bzw. _2D / _3D)") (princ)