erste Fassung der Erzeugung von Mubea als Test hinzugefügt
This commit is contained in:
@@ -0,0 +1,339 @@
|
||||
;; ============================================================
|
||||
;; test_mubea.lsp - Integrationstest: erzeugt das Mubea-Gesamtmodell
|
||||
;;
|
||||
;; Liest tests/testdata/mubea.json und baut in EINER Zeichnung:
|
||||
;; - Kreisel (Eintraege mit "id", Block KREISEL_*) via kreisel-insert-script
|
||||
;; - Vario (test_id "VF_*") Block VF_* via variofoerderer-einfuegen
|
||||
;; + vf-block-erstellen
|
||||
;; (deltaL/L_VF werden fuer winkel+deltaH geloest, L_GF Split 500/4230)
|
||||
;; - Gefaelle (test_id "GF_*", Modus 1) Block GF_* via gefaellestrecke-einfuegen
|
||||
;; - Separator (Eintraege mit "block") Block S-LP/Separator_SP via _.INSERT
|
||||
;;
|
||||
;; Speichert (via SSG_RUN_ALL_TESTS bei "save":"dxf"):
|
||||
;; tests/output/mubea_tests.dxf
|
||||
;; tests/output/mubea_results.json (via mubea:export-results)
|
||||
;;
|
||||
;; Voraussetzungen:
|
||||
;; - SSG_LIB geladen (KreiselInsert, VarioFoerderer, Gefaellestrecke,
|
||||
;; SSG_LIB_Commands, ssg_core, vf_core)
|
||||
;; - Umgebungsvariable DXFMAKRO gesetzt
|
||||
;;
|
||||
;; Aufruf in BricsCAD:
|
||||
;; (load (strcat (getenv "DXFMAKRO") "/tests/test_mubea.lsp"))
|
||||
;; TEST_MUBEA
|
||||
;; ============================================================
|
||||
|
||||
|
||||
;; --- Ergebnis eines Bau-Schritts als JSON-String erzeugen ---
|
||||
(defun mubea:result-json (test-id kind status block-name block-handle insert-point attribs /
|
||||
json tag val first)
|
||||
(setq json (strcat " {\n"
|
||||
" \"test_id\": \"" test-id "\",\n"
|
||||
" \"kind\": \"" kind "\",\n"
|
||||
" \"status\": \"" status "\",\n"
|
||||
" \"block_name\": \"" (if block-name block-name "") "\",\n"
|
||||
" \"block_handle\": \"" (if block-handle block-handle "") "\",\n"
|
||||
" \"insert_point\": ["
|
||||
(if insert-point
|
||||
(strcat (rtos (car insert-point) 2 1) ", "
|
||||
(rtos (cadr insert-point) 2 1) ", "
|
||||
(rtos (if (caddr insert-point) (caddr insert-point) 0.0) 2 1))
|
||||
"0.0, 0.0, 0.0")
|
||||
"],\n"
|
||||
" \"actual_attributes\": {"))
|
||||
(setq first T)
|
||||
(foreach att attribs
|
||||
(setq tag (car att) val (cdr att))
|
||||
(if (not first) (setq json (strcat json ",")))
|
||||
(setq json (strcat json "\n \"" tag "\": \"" (if val val "") "\""))
|
||||
(setq first nil))
|
||||
(setq json (strcat json "\n }\n }"))
|
||||
json
|
||||
)
|
||||
|
||||
|
||||
;; --- Aus einer Block-ENAME ein Ergebnis-JSON erzeugen ---
|
||||
(defun mubea:ent-json (test-id kind ent / ed)
|
||||
(if ent
|
||||
(progn
|
||||
(setq ed (entget ent))
|
||||
(mubea:result-json test-id kind "executed"
|
||||
(cdr (assoc 2 ed)) (cdr (assoc 5 ed)) (cdr (assoc 10 ed))
|
||||
(ssg-attrib-read ent)))
|
||||
(mubea:result-json test-id kind "failed" nil nil nil nil))
|
||||
)
|
||||
|
||||
|
||||
;; --- Letzten INSERT mit Blocknamen-Praefix (rueckwaerts) suchen ---
|
||||
(defun mubea:last-insert-prefix (pref / ent found ed bn)
|
||||
(setq ent (entlast))
|
||||
(while (and ent (null found))
|
||||
(setq ed (entget ent) bn (cdr (assoc 2 ed)))
|
||||
(if (and (= (cdr (assoc 0 ed)) "INSERT") bn
|
||||
(>= (strlen bn) (strlen pref))
|
||||
(= (substr bn 1 (strlen pref)) pref))
|
||||
(setq found ent))
|
||||
(setq ent (entprev ent)))
|
||||
found
|
||||
)
|
||||
|
||||
|
||||
;; ============================================================
|
||||
;; Bau-Funktionen je Elementtyp
|
||||
;; ============================================================
|
||||
|
||||
;; --- Kreisel (wie test_kreisel: kreisel-insert-script) ---
|
||||
(defun mubea:build-kreisel (e / id x y z abstand rotation typ pt ent)
|
||||
(setq id (ssg-val e "id")
|
||||
x (float (ssg-val e "x"))
|
||||
y (float (ssg-val e "y"))
|
||||
z (float (ssg-val e "z"))
|
||||
abstand (float (ssg-val e "abstand"))
|
||||
rotation (float (ssg-val e "rotation"))
|
||||
typ (ssg-val e "typ"))
|
||||
(if (null typ) (setq typ "STANDARD"))
|
||||
(setq pt (list x y z))
|
||||
(princ (strcat "\n [KREISEL] " id " -> (" (rtos x 2 0) "," (rtos y 2 0)
|
||||
"," (rtos z 2 0) ") A=" (rtos abstand 2 0) " R=" (rtos rotation 2 1)))
|
||||
(setq ent (kreisel-insert-script pt abstand rotation typ z))
|
||||
(mubea:ent-json id "kreisel" ent)
|
||||
)
|
||||
|
||||
|
||||
;; --- Vario (VF_*): deltaL/L_VF fuer winkel+deltaH loesen, dann bauen ---
|
||||
(defun mubea:build-vario (e / tid richtung deltaH winkel gf1 gf2 gf-ziel seite hz
|
||||
startpunkt dlA dlB it1 it2 lgfA lgfB steig dL item L_VF
|
||||
hoehe-bis lastEnt ent)
|
||||
(setq tid (ssg-val e "test_id")
|
||||
richtung (ssg-val e "richtung")
|
||||
deltaH (float (ssg-val e "deltaH"))
|
||||
winkel (fix (ssg-val e "winkel"))
|
||||
gf1 (float (ssg-val e "L_GF1"))
|
||||
gf2 (float (ssg-val e "L_GF2"))
|
||||
seite (ssg-val e "seite")
|
||||
hz (ssg-val e "hz")
|
||||
startpunkt (list (float (ssg-val e "x")) (float (ssg-val e "y")) (float (ssg-val e "z"))))
|
||||
(if (or (null seite) (= seite "")) (setq seite "links"))
|
||||
(if (null hz) (setq hz 0.0) (setq hz (float hz)))
|
||||
(setq gf-ziel (+ gf1 gf2))
|
||||
(princ (strcat "\n [VARIO] " tid " -> Winkel=" (itoa winkel)
|
||||
" deltaH=" (rtos deltaH 2 0) " L_GF1=" (rtos gf1 2 0)
|
||||
" L_GF2=" (rtos gf2 2 0)))
|
||||
|
||||
;; L_GF ist linear in deltaL -> deltaL aus zwei Stuetzstellen interpolieren,
|
||||
;; sodass L_GF gesamt = gf-ziel am gewaehlten Winkel.
|
||||
(setq dlA 5000.0 dlB 10000.0)
|
||||
(setq it1 (car (vl-remove-if-not '(lambda (a) (= (car a) winkel))
|
||||
(cadddr (berechne-alle-winkel dlA deltaH richtung nil)))))
|
||||
(setq it2 (car (vl-remove-if-not '(lambda (a) (= (car a) winkel))
|
||||
(cadddr (berechne-alle-winkel dlB deltaH richtung nil)))))
|
||||
(if (and it1 it2 (numberp (cadr it1)) (numberp (cadr it2))
|
||||
(/= (cadr it1) (cadr it2)))
|
||||
(progn
|
||||
(setq lgfA (cadr it1) lgfB (cadr it2))
|
||||
(setq steig (/ (- lgfB lgfA) (- dlB dlA)))
|
||||
(setq dL (+ dlA (/ (- gf-ziel lgfA) steig)))
|
||||
(setq item (car (vl-remove-if-not '(lambda (a) (= (car a) winkel))
|
||||
(cadddr (berechne-alle-winkel dL deltaH richtung nil)))))
|
||||
(setq L_VF (caddr item))
|
||||
(princ (strcat " -> deltaL=" (rtos dL 2 1) " L_VF=" (rtos L_VF 2 1)))
|
||||
|
||||
(setq hoehe-bis (if (= richtung "Auf") deltaH (- deltaH)))
|
||||
(setq lastEnt (vf-lastent-ohne-attribute))
|
||||
(variofoerderer-einfuegen dL deltaH richtung winkel gf1 gf2 L_VF startpunkt seite hz)
|
||||
(setq ent (vf-block-erstellen "standard" seite 1 0 0 hoehe-bis
|
||||
deltaH dL L_VF gf1 gf2 richtung winkel
|
||||
startpunkt lastEnt hz "0" "Schoenenberger Geruest"))
|
||||
(if (or (null ent) (/= (type ent) 'ENAME))
|
||||
(setq ent (mubea:last-insert-prefix "VF_")))
|
||||
(mubea:ent-json tid "vario" ent))
|
||||
(progn
|
||||
(princ (strcat "\n FEHLER: Winkel " (itoa winkel) " nicht loesbar (kein gueltiges L_GF)."))
|
||||
(mubea:result-json tid "vario" "failed" nil nil nil nil)))
|
||||
)
|
||||
|
||||
|
||||
;; --- Gefaellestrecke (GF_*, Modus 1) ---
|
||||
;; Wie test_gefaellestrecke: Element-Winkel 3 Grad, L_stau berechnet.
|
||||
;; deltaL wird NICHT mehr fest auf 10000 gesetzt, sondern aus der realen
|
||||
;; 2D-Distanz zwischen start_mm und ende_mm (aus der DXF abgeleitet) berechnet -
|
||||
;; sonst haetten (wie im ersten TEST_MUBEA-Lauf beobachtet) alle 20 Strecken
|
||||
;; die gleiche Default-Laenge statt ihrer tatsaechlichen Laenge.
|
||||
;; Aus JSON: start_mm, ende_mm, hz_grad, as_seite, es_seite, as_winkel, es_winkel.
|
||||
(defun mubea:build-gf (e / tid start-mm ende-mm hz as-seite es-seite as-winkel es-winkel
|
||||
test-deltaL test-winkel test-rad sep-x test-L_stau ent
|
||||
dx dy)
|
||||
(setq tid (ssg-val e "test_id")
|
||||
start-mm (mapcar 'float (ssg-val e "start_mm"))
|
||||
ende-mm (ssg-val e "ende_mm")
|
||||
hz (float (ssg-val e "hz_grad"))
|
||||
as-seite (ssg-val e "as_seite")
|
||||
es-seite (ssg-val e "es_seite")
|
||||
as-winkel (ssg-val e "as_winkel")
|
||||
es-winkel (ssg-val e "es_winkel"))
|
||||
(if (or (null as-seite) (= as-seite "")) (setq as-seite "links"))
|
||||
(if (or (null es-seite) (= es-seite "")) (setq es-seite "links"))
|
||||
(if (or (null as-winkel) (= as-winkel "")) (setq as-winkel "90"))
|
||||
(if (or (null es-winkel) (= es-winkel "")) (setq es-winkel "90"))
|
||||
|
||||
;; deltaL = reale 2D-Distanz start_mm -> ende_mm; Fallback 10000 falls
|
||||
;; ende_mm in einem Eintrag fehlen sollte.
|
||||
(if ende-mm
|
||||
(progn
|
||||
(setq ende-mm (mapcar 'float ende-mm))
|
||||
(setq dx (- (car ende-mm) (car start-mm)))
|
||||
(setq dy (- (cadr ende-mm) (cadr start-mm)))
|
||||
(setq test-deltaL (sqrt (+ (* dx dx) (* dy dy)))))
|
||||
(setq test-deltaL 10000.0))
|
||||
|
||||
(setq test-winkel 3.0
|
||||
test-rad (* test-winkel (/ pi 180.0))
|
||||
sep-x (* 300.0 (cos test-rad)))
|
||||
(setq test-L_stau
|
||||
(/ (- test-deltaL (float aus-dx) (float ein-dx) sep-x) (cos test-rad)))
|
||||
|
||||
(princ (strcat "\n [GF] " tid " -> Start=(" (rtos (car start-mm) 2 0)
|
||||
"," (rtos (cadr start-mm) 2 0) "," (rtos (caddr start-mm) 2 0)
|
||||
") hz=" (rtos hz 2 0) " deltaL=" (rtos test-deltaL 2 1)))
|
||||
(setq ent (car (gefaellestrecke-einfuegen
|
||||
test-L_stau test-winkel start-mm as-seite es-seite hz
|
||||
test-deltaL as-winkel es-winkel "0" "Schoenenberger Geruest")))
|
||||
(mubea:ent-json tid "gefaellestrecke" ent)
|
||||
)
|
||||
|
||||
|
||||
;; --- Separator (Eintraege mit "block"): _.INSERT der Blockdatei ---
|
||||
;; Verwendet den in JSON genannten Block; faellt auf Separator_SP zurueck
|
||||
;; (Block der "Separator einfuegen"-Routine ILS_SEPARATOR_INSERT).
|
||||
(defun mubea:build-separator (e idx / blockname x y z rot pt pfad tid)
|
||||
(setq blockname (ssg-val e "block")
|
||||
x (float (ssg-val e "x"))
|
||||
y (float (ssg-val e "y"))
|
||||
z (float (ssg-val e "z"))
|
||||
rot (ssg-val e "rotation"))
|
||||
(if (null rot) (setq rot 0))
|
||||
(setq rot (float rot))
|
||||
(setq pt (list x y z))
|
||||
(setq tid (strcat "SEPARATOR_" (itoa idx)))
|
||||
(princ (strcat "\n [SEP] " tid " '" (if blockname blockname "?")
|
||||
"' -> (" (rtos x 2 0) "," (rtos y 2 0) "," (rtos z 2 0) ") R=" (rtos rot 2 0)))
|
||||
(setq pfad (and blockname (ssg-ils-block-datei blockname)))
|
||||
(if (null pfad) (setq pfad (ssg-ils-block-datei "Separator_SP")))
|
||||
(if pfad
|
||||
(progn
|
||||
(command "_.INSERT" pfad pt "" "" rot)
|
||||
(mubea:ent-json tid "separator" (entlast)))
|
||||
(progn
|
||||
;; Kein Block gefunden -> sichtbaren Platzhalter zeichnen
|
||||
(if (not (tblsearch "LAYER" "MUBEA_SEPARATOR"))
|
||||
(entmake (list '(0 . "LAYER") '(2 . "MUBEA_SEPARATOR") '(70 . 0) '(62 . 1))))
|
||||
(entmake (list '(0 . "CIRCLE") (cons 10 pt) (cons 40 150.0) '(8 . "MUBEA_SEPARATOR")))
|
||||
(princ " (Block fehlt - Platzhalter)")
|
||||
(mubea:result-json tid "separator" "placeholder"
|
||||
(if blockname blockname "S-LP") nil pt nil)))
|
||||
)
|
||||
|
||||
|
||||
;; --- JSON-Export der Mubea-Ergebnisse ---
|
||||
(defun mubea:export-results (tests-out-dir / out-json f first)
|
||||
(if (null *mubea-test-results*)
|
||||
(princ "\n Keine Mubea-Ergebnisse vorhanden.")
|
||||
(progn
|
||||
(vl-mkdir tests-out-dir)
|
||||
(setq out-json (strcat tests-out-dir "/mubea_results.json"))
|
||||
(setq f (open out-json "w"))
|
||||
(if f
|
||||
(progn
|
||||
(write-line "[" f)
|
||||
(setq first T)
|
||||
(foreach r *mubea-test-results*
|
||||
(if (not first) (write-line "," f))
|
||||
(write-line r f)
|
||||
(setq first nil))
|
||||
(write-line "]" f)
|
||||
(close f)
|
||||
(princ (strcat "\n Ergebnisse: " out-json)))
|
||||
(princ (strcat "\n FEHLER: Kann " out-json " nicht schreiben!")))))
|
||||
)
|
||||
|
||||
|
||||
;; ============================================================
|
||||
;; C:TEST_MUBEA - Hauptbefehl
|
||||
;; ============================================================
|
||||
(defun c:TEST_MUBEA ( / json-datei daten eintrag tid blk res
|
||||
results-list sep-idx anz-ok anz-fehler kind)
|
||||
|
||||
;; Benoetigte Feature-Module laden
|
||||
(ssg-ensure "KreiselInsert")
|
||||
(ssg-ensure "VarioFoerderer")
|
||||
(ssg-ensure "Gefaellestrecke")
|
||||
(ssg-ensure "SSG_LIB_Commands")
|
||||
|
||||
(ssg-start "TEST_MUBEA" '(("OSMODE") ("CECOLOR") ("ATTREQ") ("ATTDIA")))
|
||||
(setvar "OSMODE" 0)
|
||||
(setvar "ATTREQ" 0)
|
||||
(setvar "ATTDIA" 0)
|
||||
|
||||
;; Block-Bibliothek (Bogen-/AS-/ES-Masse) initialisieren - fuer Vario+GF noetig
|
||||
(if (or (not *lib-initialized*) (null bogen-auf))
|
||||
(init-bibliothek))
|
||||
|
||||
;; Testdaten laden
|
||||
(setq json-datei (strcat (getenv "DXFMAKRO") "/tests/testdata/mubea.json"))
|
||||
(if (not (findfile json-datei))
|
||||
(progn
|
||||
(princ (strcat "\n[TEST_MUBEA] FEHLER: " json-datei " nicht gefunden!"))
|
||||
(ssg-end)
|
||||
(exit)))
|
||||
(setq daten (ssg-load-json json-datei))
|
||||
(if (null daten)
|
||||
(progn
|
||||
(princ "\n[TEST_MUBEA] FEHLER: Testdaten konnten nicht geladen werden.")
|
||||
(ssg-end)
|
||||
(exit)))
|
||||
|
||||
(princ "\n\n================================================================")
|
||||
(princ "\n TEST_MUBEA - Mubea-Gesamtmodell")
|
||||
(princ (strcat "\n " (itoa (length daten)) " Eintraege geladen"))
|
||||
(princ "\n================================================================")
|
||||
|
||||
(setq results-list '() sep-idx 0 anz-ok 0 anz-fehler 0)
|
||||
|
||||
(foreach eintrag daten
|
||||
(setq tid (ssg-val eintrag "test_id"))
|
||||
(setq res
|
||||
(cond
|
||||
;; Separator: hat "block"
|
||||
((ssg-val eintrag "block")
|
||||
(setq sep-idx (1+ sep-idx))
|
||||
(mubea:build-separator eintrag sep-idx))
|
||||
;; Kreisel: hat "id"
|
||||
((ssg-val eintrag "id")
|
||||
(mubea:build-kreisel eintrag))
|
||||
;; Vario: test_id "VF_*"
|
||||
((and tid (>= (strlen tid) 3) (= (substr tid 1 3) "VF_"))
|
||||
(mubea:build-vario eintrag))
|
||||
;; Gefaellestrecke: test_id "GF_*"
|
||||
((and tid (>= (strlen tid) 3) (= (substr tid 1 3) "GF_"))
|
||||
(mubea:build-gf eintrag))
|
||||
(T
|
||||
(princ (strcat "\n WARNUNG: Unbekannter Eintrag uebersprungen"))
|
||||
nil)))
|
||||
(if res
|
||||
(progn
|
||||
(setq results-list (cons res results-list))
|
||||
(if (or (vl-string-search "\"executed\"" res)
|
||||
(vl-string-search "\"placeholder\"" res))
|
||||
(setq anz-ok (1+ anz-ok))
|
||||
(setq anz-fehler (1+ anz-fehler))))))
|
||||
|
||||
(princ "\n================================================================")
|
||||
(princ (strcat "\n Ergebnis: " (itoa anz-ok) " OK, " (itoa anz-fehler) " Fehler"))
|
||||
(princ "\n================================================================")
|
||||
|
||||
(setq *mubea-test-results* (reverse results-list))
|
||||
|
||||
(ssg-end)
|
||||
(princ "\n TEST_MUBEA abgeschlossen.")
|
||||
(princ)
|
||||
)
|
||||
Reference in New Issue
Block a user