Files
dxfmakros/tests/test_omniflo_strecke.lsp
T
m.stangl 60f2b72e39 Omniflo-Streckenzug-Test + skriptfaehige Aluprofil-Geraden
Neuer Test: 4 Geraden -> 180-Grad-Kurve (4x 45-Grad-Bogen) -> 4 Geraden
als lueckenlos verketteter Streckenzug (U-Form).

- testdata/omniflo_strecke_tests.json: 12 Elemente mit berechneter,
  verketteter Platzierung (x, y, drehung, x_ende, y_ende, Bogen-Mittelpunkt)
- test_omniflo_strecke.py: Geometrie-Validierung ohne BricsCAD (Struktur,
  Katalog-Abgleich, Verkettung, Kurvensumme 180 Grad, gemeinsamer Mittelpunkt)
- test_omniflo_strecke.lsp: C:TEST_OMNIFLO_STRECKE baut die Strecke auf
- alltests.json/README.md: Test registriert und dokumentiert

OmniModulInsert.lsp: omni:insert-block in skriptfaehigen Kern omni:make-gerade
+ omni:read-src-attribs aufgeteilt. Der Kern erzeugt eine Aluprofil-Gerade
non-interaktiv aus zwei Punkten (kein getpoint/ssg-start), sodass der Test
echte Gerade-Bloecke statt nackter Linien baut. Interaktives Verhalten von
omni:insert-block bleibt unveraendert (Vorschau-Text, Laengenpruefung).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 17:51:05 +02:00

281 lines
11 KiB
Common Lisp

;; ============================================================
;; test_omniflo_strecke.lsp - Integrationstest Omniflo-Streckenzug
;;
;; Baut aus tests/testdata/omniflo_strecke_tests.json einen verketteten
;; Streckenzug auf:
;; 4 Geraden -> 180-Grad-Kurve (4x 45-Grad-Bogen) -> 4 Geraden
;;
;; Jedes Element traegt bereits seine absolute Platzierung (x, y, drehung)
;; sowie Endpunkt (x_ende, y_ende). Die Elemente sind lueckenlos verkettet
;; (Ende[i] = Anfang[i+1]), sodass eine durchgehende U-foermige Strecke
;; entsteht.
;;
;; - Boegen (type "bogen"): DXF aus DXFM_OMNIFLO an (x,y) mit Drehung
;; einfuegen (wie test_omniflo.lsp).
;; - Geraden (type "gerade"): echter Aluprofil-Block ueber den skript-
;; faehigen Kern omni:make-gerade (aus OmniModulInsert.lsp). Fehlt die
;; Quell-.dwg (kein AP110.dwg im Blockpfad), werden Ersatz-Attribute
;; verwendet, sodass dennoch ein Compound-Block (Linie + ATTDEFs) statt
;; einer nackten Linie entsteht.
;;
;; Ergebnisse -> tests/output/omniflo_strecke_results.json
;; (via omniflo_strecke:export-results, aufgerufen von SSG_RUN_ALL_TESTS
;; oder manuell).
;;
;; Voraussetzungen:
;; - SSG_LIB geladen (ssg_core.lsp, OmniModulInsert.lsp)
;; - Umgebungsvariablen DXFMAKRO, DXFM_OMNIFLO gesetzt
;;
;; Aufruf in BricsCAD:
;; (load "tests/test_omniflo_strecke.lsp")
;; TEST_OMNIFLO_STRECKE
;; ============================================================
;; --- Bogen-DXF non-interaktiv an gegebenem Punkt einfuegen ---
(defun omnistr:insert-bogen (sivasnr-str insert-pt hoehe-str drehung-str /
dxf-pfad omniflo-pfad blockEnt angleDeg)
(setq omniflo-pfad (getenv "DXFM_OMNIFLO"))
(if (null omniflo-pfad)
(progn
(princ "\n[TEST_OMNIFLO_STRECKE] FEHLER: DXFM_OMNIFLO nicht gesetzt!")
nil
)
(progn
(setq dxf-pfad (strcat omniflo-pfad "/" sivasnr-str ".dxf"))
(if (not (findfile dxf-pfad))
(progn
(princ (strcat "\n[TEST_OMNIFLO_STRECKE] WARNUNG: DXF nicht gefunden: " dxf-pfad))
nil
)
(progn
(setq angleDeg (if drehung-str (atof drehung-str) 0.0))
(setvar "ATTREQ" 0)
(setvar "ATTDIA" 0)
(command "_.INSERT" dxf-pfad insert-pt "" "" angleDeg)
(setq blockEnt (entlast))
(if (and blockEnt
(= (cdr (assoc 0 (entget blockEnt))) "INSERT"))
(ssg-attrib-set-on blockEnt
(list (cons "HOEHE" (if hoehe-str hoehe-str "2000"))
(cons "DREHUNG" (if drehung-str drehung-str "0"))))
)
blockEnt
)
)
)
)
)
;; --- Gerade non-interaktiv als echten Aluprofil-Block erzeugen ---
;; Nutzt den skriptfaehigen Kern omni:make-gerade aus OmniModulInsert.lsp.
;; profil = Profiltyp (z.B. "AP110")
;; pt-anf = Anfangspunkt, pt-end = Endpunkt (bestimmen Laenge + Drehung)
;; hoehe-str / drehung-str = Attributwerte HOEHE/DREHUNG
;; Rueckgabe: Block-Entity oder nil.
(defun omnistr:build-gerade (profil pt-anf pt-end hoehe-str drehung-str /
srcAttribs textHeight textGap blockEnt)
(if (null (car (atoms-family 1 '("OMNI:MAKE-GERADE"))))
(progn
(princ "\n[TEST_OMNIFLO_STRECKE] FEHLER: omni:make-gerade nicht geladen (OmniModulInsert.lsp)!")
nil
)
(progn
(setq textHeight (ssg-cfg-or "omniflo" "text_height" 100.0))
(setq textGap (ssg-cfg-or "omniflo" "text_gap" 20.0))
;; Quell-Attribute lesen; falls keine .dwg vorhanden, Ersatz erzeugen
(setq srcAttribs (omni:read-src-attribs profil))
(if (null srcAttribs)
(setq srcAttribs (list (cons "PROFILTYP" profil)
(cons "HOEHE" (if hoehe-str hoehe-str "2000"))
(cons "ID" "")))
)
(setvar "ATTREQ" 0)
(setvar "ATTDIA" 0)
(setq blockEnt (omni:make-gerade profil pt-anf pt-end
srcAttribs textHeight textGap nil))
(if (and blockEnt (= (cdr (assoc 0 (entget blockEnt))) "INSERT"))
(ssg-attrib-set-on blockEnt
(list (cons "HOEHE" (if hoehe-str hoehe-str "2000"))
(cons "DREHUNG" (if drehung-str drehung-str "0"))))
)
blockEnt
)
)
)
;; --- Ergebnis eines Streckenelements als JSON-String erzeugen ---
(defun omnistr:test-result-json (test-id seq typ description status / )
(strcat " {\n"
" \"test_id\": \"" test-id "\",\n"
" \"seq\": " (itoa seq) ",\n"
" \"type\": \"" (if typ typ "") "\",\n"
" \"description\": \"" (if description description "") "\",\n"
" \"status\": \"" status "\"\n"
" }")
)
;; --- JSON-Export der Streckenzug-Testergebnisse ---
(defun omniflo_strecke:export-results (tests-out-dir / out-json f first)
(if (null *omniflo-strecke-test-results*)
(princ "\n Keine Streckenzug-Ergebnisse vorhanden.")
(progn
(vl-mkdir tests-out-dir)
(setq out-json (strcat tests-out-dir "/omniflo_strecke_results.json"))
(setq f (open out-json "w"))
(if f
(progn
(write-line "[" f)
(setq first T)
(foreach r *omniflo-strecke-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_OMNIFLO_STRECKE
;;
;; Liest omniflo_strecke_tests.json und baut den Streckenzug auf.
;; ============================================================
(defun c:TEST_OMNIFLO_STRECKE (/ tests-json-pfad elemente
idx eintrag typ sivasnr profil hoehe-str drehung-str
description x-val y-val xe-val ye-val seq
insert-pt pt-end anzahl-ok anzahl-fehler
results-list ergebnis)
(ssg-start "TEST_OMNIFLO_STRECKE"
'(("OSMODE") ("ATTREQ") ("ATTDIA") ("CLAYER")))
(setvar "OSMODE" 0)
(setvar "ATTREQ" 0)
(setvar "ATTDIA" 0)
(setq tests-json-pfad
(strcat (getenv "DXFMAKRO") "/tests/testdata/omniflo_strecke_tests.json"))
(if (not (findfile tests-json-pfad))
(progn
(princ (strcat "\n[TEST_OMNIFLO_STRECKE] FEHLER: Testdaten nicht gefunden: "
tests-json-pfad))
(ssg-end)
(princ)
)
(progn
(setq elemente (ssg-load-json tests-json-pfad))
(if (null elemente)
(progn
(princ "\n[TEST_OMNIFLO_STRECKE] FEHLER: Testdaten konnten nicht geladen werden.")
(ssg-end)
(princ)
)
(progn
(princ "\n================================================================")
(princ "\n TEST_OMNIFLO_STRECKE")
(princ (strcat "\n " (itoa (length elemente)) " Streckenelemente geladen"))
(princ "\n================================================================")
(setq anzahl-ok 0 anzahl-fehler 0 results-list nil idx 0)
(foreach eintrag elemente
(setq idx (1+ idx))
(setq seq (ssg-val eintrag "seq"))
(if (null seq) (setq seq idx))
(if (not (numberp seq)) (setq seq (atoi (vl-princ-to-string seq))))
(setq typ (ssg-val eintrag "type"))
(setq description (ssg-val eintrag "description"))
(setq hoehe-str (ssg-val eintrag "hoehe"))
(if (null hoehe-str) (setq hoehe-str "2000"))
(if (numberp hoehe-str) (setq hoehe-str (rtos hoehe-str 2 0)))
(setq drehung-str (ssg-val eintrag "drehung"))
(if (null drehung-str) (setq drehung-str "0"))
(if (numberp drehung-str) (setq drehung-str (rtos drehung-str 2 4)))
;; Anfangs- und Endpunkt lesen
(setq x-val (ssg-val eintrag "x")
y-val (ssg-val eintrag "y")
xe-val (ssg-val eintrag "x_ende")
ye-val (ssg-val eintrag "y_ende"))
(if (null x-val) (setq x-val 0.0))
(if (null y-val) (setq y-val 0.0))
(if (null xe-val) (setq xe-val x-val))
(if (null ye-val) (setq ye-val y-val))
(if (not (numberp x-val)) (setq x-val (atof x-val)))
(if (not (numberp y-val)) (setq y-val (atof y-val)))
(if (not (numberp xe-val)) (setq xe-val (atof xe-val)))
(if (not (numberp ye-val)) (setq ye-val (atof ye-val)))
(setq insert-pt (list x-val y-val (atof hoehe-str)))
(setq pt-end (list xe-val ye-val (atof hoehe-str)))
(princ (strcat "\n " (itoa seq) ". " (if typ typ "?") ": "
(if description description "")
" -> (" (rtos x-val 2 0) ", " (rtos y-val 2 0)
") @ " drehung-str))
;; Element aufbauen je nach Typ
(setq ergebnis
(cond
((= typ "bogen")
(setq sivasnr (ssg-val eintrag "sivasnr"))
(omnistr:insert-bogen sivasnr insert-pt hoehe-str drehung-str))
((= typ "gerade")
(setq profil (ssg-val eintrag "profil"))
(if (null profil) (setq profil "AP110"))
(omnistr:build-gerade profil insert-pt pt-end hoehe-str drehung-str))
(T
(princ (strcat "\n WARNUNG: unbekannter Typ '"
(if typ typ "nil") "'"))
nil)
)
)
(if ergebnis
(progn
(setq anzahl-ok (1+ anzahl-ok))
(setq results-list (cons
(omnistr:test-result-json (strcat "STRECKE_" (itoa seq))
seq typ description "OK")
results-list))
)
(progn
(setq anzahl-fehler (1+ anzahl-fehler))
(setq results-list (cons
(omnistr:test-result-json (strcat "STRECKE_" (itoa seq))
seq typ description "FEHLER")
results-list))
)
)
)
(princ "\n================================================================")
(princ (strcat "\n Aufgebaut: " (itoa anzahl-ok)
" OK, " (itoa anzahl-fehler) " Fehler"))
(princ "\n================================================================")
(setq *omniflo-strecke-test-results* (reverse results-list))
(ssg-end)
(princ "\n TEST_OMNIFLO_STRECKE abgeschlossen.")
(princ)
)
)
)
)
)