;; ============================================================ ;; tests.lsp - Test- und Hilfsfunktionen ;; ============================================================ (defun c:CALLPYTHON ( / log-pfad py-skript return-datei cmd fh zeile) (setq log-pfad (getenv "DXFM_LOG")) (setq py-skript (strcat (getenv "DXFM_LIB") "\\testpycall.py")) (setq return-datei (strcat log-pfad "\\testpycall_return.txt")) (if (findfile py-skript) (progn (setq cmd (strcat "python \"" py-skript "\" \"" log-pfad "\"")) (command "_.SHELL" cmd) (if (findfile return-datei) (progn (setq fh (open return-datei "r")) (setq zeile (read-line fh)) (close fh) (princ (strcat "\n[SSG_LIB] Python Rueckgabe: " zeile)) ) (princ "\n[SSG_LIB] WARNUNG: Keine Rueckgabe von Python erhalten.") ) ) (princ (strcat "\n[SSG_LIB] FEHLER: " py-skript " nicht gefunden!")) ) (princ) ) ;; ============================================================ ;; EXPORT - Relevante INSERT-Entities sammeln und als JSON exportieren ;; Anschliessend Python-Skript aufrufen fuer CSV-Erzeugung ;; ============================================================ ;; --- String fuer JSON escapen (Anfuehrungszeichen/Backslash) --- ;; Nutzt vl-string-subst fuer die haeufigsten Faelle statt ;; zeichenweiser Verkettung (deutlich schneller bei langen Strings). (defun csv:json-escape (s) (setq s (vl-string-subst "\\\\" "\\" s)) (vl-string-subst "\\\"" "\"" s) ) ;; --- Attribute eines INSERT-Blocks als JSON-Objekt lesen --- ;; ename = Entity-Name des INSERT ;; Rueckgabe: String wie {"TAG1":"Wert1","TAG2":"Wert2"} (defun csv:read-attribs (ename / obj ed typ tag wert parts) (setq obj (entnext ename)) (setq parts nil) (while obj (setq ed (entget obj)) (setq typ (cdr (assoc 0 ed))) (if (equal typ "SEQEND") (setq obj nil) (progn (if (equal typ "ATTRIB") (setq parts (cons (strcat "\"" (csv:json-escape (cdr (assoc 2 ed))) "\":\"" (csv:json-escape (cdr (assoc 1 ed))) "\"") parts)) ) (setq obj (entnext obj)) ) ) ) (if parts (progn (setq parts (reverse parts)) (strcat "{" (car parts) (apply 'strcat (mapcar '(lambda (p) (strcat "," p)) (cdr parts))) "}") ) "{}" ) ) ;; --- Einen INSERT-Block als JSON-Objekt schreiben --- (defun csv:block-to-json (ename / ed blk-name layer pt rotation handle attribs) (setq ed (entget ename)) (setq blk-name (cdr (assoc 2 ed))) (setq layer (cdr (assoc 8 ed))) (setq pt (cdr (assoc 10 ed))) (setq rotation (cdr (assoc 50 ed))) (setq handle (cdr (assoc 5 ed))) (if (null rotation) (setq rotation 0.0)) (if (cdr (assoc 66 ed)) (setq attribs (csv:read-attribs ename)) (setq attribs "{}") ) (strcat " {\"block_name\":\"" (csv:json-escape blk-name) "\"" ",\"layer\":\"" (csv:json-escape layer) "\"" ",\"handle\":\"" (csv:json-escape handle) "\"" ",\"x\":" (rtos (car pt) 2 4) ",\"y\":" (rtos (cadr pt) 2 4) ",\"z\":" (rtos (if (caddr pt) (caddr pt) 0.0) 2 4) ",\"rotation\":" (rtos (* (/ rotation pi) 180.0) 2 4) ",\"attribs\":" attribs "}" ) ) ;; --- Relevante Bloecke sammeln --- ;; Filtert INSERT-Entities auf exportierbare Bloecke: ;; KR_* = Kreisel Compound-Bloecke ;; AP110* = Omniflo Geraden ;; Omniflo Boegen/Weichen = rein numerische Blocknamen (SivasNr) ;; Vario* = VarioFoerderer-Bloecke ;; Gibt Auswahlsatz zurueck oder nil. (defun csv:collect-export-blocks ( / ss-all ss-out i ename ed bname) (setq ss-all (ssget "X" (list (cons 0 "INSERT")))) (if (null ss-all) (setq ss-out nil) (progn (setq ss-out (ssadd)) (setq i 0) (while (setq ename (ssname ss-all i)) (setq ed (entget ename)) (setq bname (cdr (assoc 2 ed))) (if (or (wcmatch bname "KR_*,KREISEL_*,ECKRAD_*") (wcmatch (strcase bname) "AP110*,AP_110*") (wcmatch bname "Vario*,Staustrecke*,AUS_Element*,EIN_Element*") ;; Rein numerische Namen = Omniflo SivasNr (Boegen/Weichen) (wcmatch bname "#*") ) (ssadd ename ss-out) ) (setq i (1+ i)) ) (if (= (sslength ss-out) 0) (setq ss-out nil)) ) ) ss-out ) ;; --- Gemeinsame Export-Funktion --- ;; Sammelt relevante Bloecke, schreibt JSON, ruft Python auf. ;; label = Anzeigename (z.B. "EXPORTCSV") ;; py-name = Python-Skript-Name (z.B. "export_csv.py") ;; csv-name = Ergebnis-CSV-Name (z.B. "export.csv") (defun csv:run-export (label py-name csv-name / ss i ename fh out-pfad py-skript ergebnis-pfad cmd first-block count) (princ (strcat "\n[" label "] Sammle relevante Bloecke...")) (setq ss (csv:collect-export-blocks)) (if (null ss) (progn (princ (strcat "\n[" label "] Keine relevanten Bloecke gefunden.")) (princ) ) (progn (setq count (sslength ss)) (princ (strcat "\n[" label "] " (itoa count) " Bloecke gefunden.")) ;; JSON-Datei zusammenbauen (setq out-pfad (strcat (getenv "DXFM_RESULTS") "/export_raw.json")) (setq fh (open out-pfad "w")) (if (null fh) (progn (princ (strcat "\n[" label "] FEHLER: Kann Datei nicht oeffnen: " out-pfad)) (princ) ) (progn (write-line "[" fh) (setq i 0) (setq first-block T) (while (setq ename (ssname ss i)) (if (not first-block) (write-line "," fh) ) (write-line (csv:block-to-json ename) fh) (setq first-block nil) (setq i (1+ i)) ) (write-line "]" fh) (close fh) (princ (strcat "\n[" label "] JSON geschrieben: " out-pfad)) ;; Python-Skript aufrufen (setq py-skript (strcat (getenv "DXFM_LIB") "/" py-name)) (if (findfile py-skript) (progn (setq ergebnis-pfad (strcat (getenv "DXFM_RESULTS") "/" csv-name)) (setq cmd (strcat "python \"" py-skript "\"" " \"" out-pfad "\"" " \"" (getenv "DXFM_DATA") "\"" " \"" ergebnis-pfad "\"")) (princ (strcat "\n[" label "] Rufe Python auf...")) (startapp "cmd" (strcat "/c " cmd)) (princ (strcat "\n[" label "] Export gestartet: " ergebnis-pfad)) ) (princ (strcat "\n[" label "] FEHLER: Python-Skript nicht gefunden: " py-skript)) ) ) ) ) ) (princ) ) ;; --- EXPORTSIVAS: Sivas-spezifischer CSV-Export mit Summierungszeilen --- (defun c:EXPORTSIVAS () (csv:run-export "EXPORTSIVAS" "export_sivas.py" "export_sivas.csv") ) ;; --- EXPORTCSV: Einfache Item-Liste aller Bloecke (ohne Summierung) --- (defun c:EXPORTCSV () (csv:run-export "EXPORTCSV" "export_csv.py" "export.csv") ) ;; ============================================================ ;; Omniflo-Elemente zaehlen und CSV-Export (rein LISP, ohne Python) ;; ;; Erkennt Omniflo Bloecke anhand Attribute: ;; TEILEART = "Omniflo Kurve" -> Bogen ;; TEILEART = "Omniflo Weiche" -> Weiche ;; Blockname AP110* -> Gerade ;; ============================================================ ;; --- Attribut-Wert eines INSERT-Blocks nach Tag lesen --- (defun csv:get-attrib (ename tag / obj ed typ atag) (setq obj (entnext ename)) (while obj (setq ed (entget obj)) (setq typ (cdr (assoc 0 ed))) (if (equal typ "SEQEND") (setq obj nil) (progn (if (and (equal typ "ATTRIB") (= (strcase (cdr (assoc 2 ed))) (strcase tag))) (progn (setq obj nil) (setq atag (cdr (assoc 1 ed)))) (setq obj (entnext obj)) ) ) ) ) atag ) ;; --- Omniflo-Block klassifizieren --- ;; Gibt "bogen", "weiche", "gerade" oder nil zurueck (defun csv:omni-classify (ename bname / teileart) (setq teileart (csv:get-attrib ename "TEILEART")) (cond ((and teileart (= teileart "Omniflo Kurve")) "bogen") ((and teileart (= teileart "Omniflo Weiche")) "weiche") ((wcmatch (strcase bname) "AP110*,AP_110*") "gerade") (t nil) ) ) ;; --- Weichen-Subtyp fuer Omniflo Sum Zaehlung bestimmen --- ;; Gibt "einzelweiche", "doppelweiche", "dreiwegeweiche", ;; "deltaweiche", "sternweiche" oder "weichenkoerper" zurueck (defun csv:omni-weichensubtyp (ename / wtyp beschr) (setq wtyp (csv:get-attrib ename "WEICHENTYP")) (setq beschr (csv:get-attrib ename "BESCHR")) (if (null wtyp) (setq wtyp "")) (if (null beschr) (setq beschr "")) (cond ((vl-string-search "WEICHENK" (strcase beschr)) "weichenkoerper") ((= wtyp "Einzelweiche") "einzelweiche") ((= wtyp "Doppelweiche") "doppelweiche") ((= wtyp "Dreiwegeweiche") "dreiwegeweiche") ((= wtyp "Deltaweiche") "deltaweiche") ((= wtyp "Dreifachweiche") "deltaweiche") ((= wtyp "Sternweiche") "sternweiche") ((vl-string-search "DELTA" (strcase beschr)) "deltaweiche") ((vl-string-search "STAR" (strcase beschr)) "sternweiche") (t "einzelweiche") ) ) ;; --- Merkmale-JSON fuer einen Bogen bauen --- (defun csv:omni-bogen-merkmale (ename rotation / winkel radius sivasnr) (setq winkel (if (csv:get-attrib ename "WINKEL") (csv:get-attrib ename "WINKEL") "0")) (setq radius (if (csv:get-attrib ename "RADIUS") (csv:get-attrib ename "RADIUS") "0")) (setq sivasnr (if (csv:get-attrib ename "ARTINR") (csv:get-attrib ename "ARTINR") "")) (strcat "{\"L\\u00e4nge in Meter\":\"0\"" ",\"Kurvenwinkel\":" winkel ",\"Radius\":" radius ",\"H\\u00f6he\":\"2000\"" ",\"Drehung\":" (rtos rotation 2 1) ",\"SivasNummer\":\"" (csv:json-escape sivasnr) "\"}") ) ;; --- Merkmale-JSON fuer eine Weiche bauen --- (defun csv:omni-weiche-merkmale (ename rotation / wtyp winkel sivasnr tef-str) (setq wtyp (if (csv:get-attrib ename "WEICHENTYP") (csv:get-attrib ename "WEICHENTYP") "Einzelweiche")) (setq winkel (if (csv:get-attrib ename "WINKEL") (csv:get-attrib ename "WINKEL") "0")) (setq sivasnr (if (csv:get-attrib ename "ARTINR") (csv:get-attrib ename "ARTINR") "")) (setq tef-str (csv:get-attrib ename "SIVASNR_TEF")) (strcat "{\"L\\u00e4nge in Meter links\":null" ",\"L\\u00e4nge in Meter rechts\":null" ",\"L\\u00e4nge in Meter gerade\":null" ",\"Weichentyp\":\"" (csv:json-escape wtyp) "\"" ",\"Richtung\":\"False\"" ",\"Weichenwinkel\":" winkel ",\"H\\u00f6he\":\"2000\"" ",\"Drehung\":" (rtos rotation 2 1) ",\"Antrieb Kurve\":" (if (and tef-str (> (strlen tef-str) 0)) "true" "false") ",\"SivasNummer\":\"" (csv:json-escape sivasnr) "\"}") ) ;; --- Merkmale-JSON fuer eine Gerade bauen --- (defun csv:omni-gerade-merkmale (ename rotation / laenge) (setq laenge (csv:get-attrib ename "LAENGE")) (if (null laenge) (setq laenge (csv:get-attrib ename "A"))) (if (null laenge) (setq laenge "2000")) (strcat "{\"Anzahl der Separatoren\":\"0\"" ",\"L\\u00e4nge in Meter\":\"" (csv:json-escape (rtos (/ (atof laenge) 1000.0) 2 2)) "\"" ",\"Winkel\":\"0\"" ",\"Anzahl der Scanner\":0" ",\"H\\u00f6he oben\":\"2000\"" ",\"H\\u00f6he unten\":\"2000\"" ",\"Drehung\":" (rtos rotation 2 1) ",\"SivasNummer\":\"\"}") ) ;; --- Omniflo Sum Zeile bauen --- (defun csv:omni-sum-zeile (elem-nr cnt-boegen cnt-wk cnt-einzel cnt-delta cnt-doppel cnt-stern len-ap110 len-ap60) (strcat (itoa elem-nr) ";\"Omniflo Sum\";\"autogenerated_of_json\";\"Omniflo sum\";1;" "{\"Anzahl B\\u00f6gen\":" (itoa cnt-boegen) ",\"Anzahl Weichengrundk\\u00f6rper\":" (itoa cnt-wk) ",\"Anzahl Einwegweichen\":" (itoa cnt-einzel) ",\"Anzahl Deltaweichen\":" (itoa cnt-delta) ",\"Anzahl Doppelweichen und Dreiwegeweichen\":" (itoa cnt-doppel) ",\"Anzahl Sternweichen\":" (itoa cnt-stern) ",\"Gesamtl\\u00e4nge AP110\":" (rtos len-ap110 2 1) ",\"Gesamtl\\u00e4nge AP60\":" (rtos len-ap60 2 1) "}") ) ;; --- CSV-Zeile fuer ein Omniflo-Element bauen --- (defun csv:omni-csv-line (elem-nr teileart bezeichnung merkmale-json) (strcat (itoa elem-nr) ";\"" teileart "\"" ";\"shape_" (substr (rtos (* (getvar "CDATE") 1000000.0) 2 0) 1 8) (substr (rtos (* (getvar "TDUSRTIMER") 1000000.0) 2 0) 1 8) "\"" ";\"" bezeichnung "\"" ";1" ";" merkmale-json) ) ;; ============================================================ ;; C:OMNI_EXPORT - Omniflo-Elemente zaehlen und als CSV exportieren ;; Rein LISP-basiert, kein Python noetig. ;; ============================================================ (defun c:OMNI_EXPORT ( / ss-all i ename ed bname rotation typ elem-nr cnt-boegen cnt-weichen cnt-geraden cnt-wk cnt-einzel cnt-delta cnt-doppel cnt-stern len-ap110 len-ap60 laenge-str fh out-pfad lines subtyp merkmale) (princ "\n[OMNI_EXPORT] Sammle Omniflo-Elemente...") (setq ss-all (ssget "X" (list (cons 0 "INSERT")))) (if (null ss-all) (progn (princ "\n[OMNI_EXPORT] Keine INSERT-Bloecke in der Zeichnung.") (princ)) (progn ;; Zaehler initialisieren (setq elem-nr 0) (setq cnt-boegen 0 cnt-weichen 0 cnt-geraden 0) (setq cnt-wk 0 cnt-einzel 0 cnt-delta 0 cnt-doppel 0 cnt-stern 0) (setq len-ap110 0.0 len-ap60 0.0) (setq lines '()) ;; Alle INSERT-Entities durchgehen (setq i 0) (while (setq ename (ssname ss-all i)) (setq ed (entget ename)) (setq bname (cdr (assoc 2 ed))) (setq rotation (cdr (assoc 50 ed))) (if (null rotation) (setq rotation 0.0)) (setq rotation (* (/ rotation pi) 180.0)) (setq typ (csv:omni-classify ename bname)) (cond ;; --- Bogen --- ((= typ "bogen") (setq elem-nr (1+ elem-nr)) (setq cnt-boegen (1+ cnt-boegen)) (setq merkmale (csv:omni-bogen-merkmale ename rotation)) (setq lines (cons (csv:omni-csv-line elem-nr "Omniflo Kurve" (strcat "OFBogen :" (itoa cnt-boegen)) merkmale) lines)) ) ;; --- Weiche --- ((= typ "weiche") (setq elem-nr (1+ elem-nr)) (setq cnt-weichen (1+ cnt-weichen)) (setq subtyp (csv:omni-weichensubtyp ename)) (cond ((= subtyp "weichenkoerper") (setq cnt-wk (1+ cnt-wk))) ((= subtyp "einzelweiche") (setq cnt-einzel (1+ cnt-einzel))) ((= subtyp "deltaweiche") (setq cnt-delta (1+ cnt-delta))) ((= subtyp "sternweiche") (setq cnt-stern (1+ cnt-stern))) (t (setq cnt-doppel (1+ cnt-doppel))) ) (setq merkmale (csv:omni-weiche-merkmale ename rotation)) (setq lines (cons (csv:omni-csv-line elem-nr "Omniflo Weiche" (strcat "OFWeiche :" (itoa cnt-weichen)) merkmale) lines)) ) ;; --- Gerade (AP110) --- ((= typ "gerade") (setq elem-nr (1+ elem-nr)) (setq cnt-geraden (1+ cnt-geraden)) (setq laenge-str (csv:get-attrib ename "LAENGE")) (if (null laenge-str) (setq laenge-str (csv:get-attrib ename "A"))) (if (and laenge-str (> (strlen laenge-str) 0)) (setq len-ap110 (+ len-ap110 (atof laenge-str))) (setq len-ap110 (+ len-ap110 2000.0)) ) (setq merkmale (csv:omni-gerade-merkmale ename rotation)) (setq lines (cons (csv:omni-csv-line elem-nr "Omniflo Gerade" (strcat "OFGerade :" (itoa cnt-geraden)) merkmale) lines)) ) ) ;; cond (setq i (1+ i)) ) ;; while ;; Ergebnis ausgeben (princ (strcat "\n[OMNI_EXPORT] Gefunden: " (itoa cnt-boegen) " Boegen, " (itoa cnt-weichen) " Weichen, " (itoa cnt-geraden) " Geraden")) (if (= elem-nr 0) (princ "\n[OMNI_EXPORT] Keine Omniflo-Elemente gefunden.") (progn ;; CSV schreiben (setq out-pfad (strcat (getenv "DXFM_RESULTS") "/omniflo_export.csv")) (setq fh (open out-pfad "w")) (if (null fh) (princ (strcat "\n[OMNI_EXPORT] FEHLER: Kann Datei nicht oeffnen: " out-pfad)) (progn ;; Header (write-line "Elementnummer;TeileArt;TeileId;Bezeichnung;Anzahl;Merkmale" fh) ;; Einzelzeilen (lines ist rueckwaerts aufgebaut) (foreach ln (reverse lines) (write-line ln fh) ) ;; Omniflo Sum Zeile (write-line (csv:omni-sum-zeile (1+ elem-nr) cnt-boegen cnt-wk cnt-einzel cnt-delta cnt-doppel cnt-stern len-ap110 len-ap60) fh) (close fh) (princ (strcat "\n[OMNI_EXPORT] CSV geschrieben: " out-pfad)) (princ (strcat "\n[OMNI_EXPORT] Omniflo Sum: " (itoa cnt-boegen) " Boegen, " (itoa (+ cnt-einzel cnt-doppel cnt-delta cnt-stern cnt-wk)) " Weichen, " (rtos len-ap110 2 0) " mm AP110")) ) ) ) ) ) ) (princ) ) ;; ============================================================ ;; TEST_FOERDERER - Automatischer Test ohne Benutzereingabe ;; Erzeugt 12 Variofoerderer (6x Auf, 6x Ab) mit deltaL=7000 ;; und verschiedenen Hoehenstufen. Tabellarische Zusammenfassung. ;; ============================================================ (defun c:TEST_FOERDERER ( / deltaL deltaH richtung ergebnis best-winkel L_GF L_VF dateiname y-offset hoehen-liste idx anz-gebaut anz-nicht-gebaut result-pfad erfolgsquote zusammenfassung-liste nr deltaH_val status winkel L_GF_val L_VF_val) ;; Bibliothek initialisieren (laedt Block-Library und extrahiert Masse) (if (not *lib-initialized*) (init-bibliothek) ) (ssg-start "TEST_FOERDERER" '(("OSMODE") ("CECOLOR") ("ATTREQ") ("ATTDIA"))) (setvar "OSMODE" 0) (setvar "ATTREQ" 0) (setvar "ATTDIA" 0) (setq deltaL 7000) (setq hoehen-liste '(0 1000 2000 3000 4000 5000)) (setq y-offset 0) (setq idx 0) (setq zusammenfassung-liste '()) (setq anz-gebaut 0) (setq anz-nicht-gebaut 0) (princ "\n") (princ "\n================================================================") (princ "\n FOERDERTEST - PRODUKTIONSPROTOKOLL") (princ "\n================================================================") (princ (strcat "\n Distanz dL = " (rtos deltaL 2 0) " mm")) (princ "\n Hoehenstufen: 0, 1000, 2000, 3000, 4000, 5000 mm") (princ "\n Richtungen: Auf + Ab") (princ "\n================================================================") (princ "\n Nr. Richtung dH (mm) Status Winkel L_GF (mm) L_VF (mm)") (princ "\n================================================================") ;; ========================================================== ;; TEIL 1: Aufwaerts-Tests (6 Foerderer) ;; ========================================================== (foreach deltaH hoehen-liste (setq idx (1+ idx)) (setq richtung "Auf") (setq ergebnis (berechne-alle-winkel deltaL deltaH richtung)) (setq best-winkel (car ergebnis)) (setq L_GF (cadr ergebnis)) (setq L_VF (caddr ergebnis)) (if (and best-winkel L_GF L_VF (> L_GF 0) (> L_VF 0)) (progn (setq anz-gebaut (1+ anz-gebaut)) (princ (strcat "\n " (itoa idx) " " (if (< idx 10) " " "") "Auf " (rtos deltaH 4 0) " " "GEBAUT " (itoa best-winkel) " Grad " (rtos L_GF 2 1) " " (rtos L_VF 2 1))) (foerderanlage-einfuegen deltaL deltaH richtung best-winkel (/ L_GF 2.0) (/ L_GF 2.0) L_VF (list 0 y-offset 0)) (setq zusammenfassung-liste (cons (list idx richtung deltaH "GEBAUT" best-winkel L_GF L_VF) zusammenfassung-liste)) ) (progn (setq anz-nicht-gebaut (1+ anz-nicht-gebaut)) (princ (strcat "\n " (itoa idx) " " (if (< idx 10) " " "") "Auf " (rtos deltaH 4 0) " " "NICHT " "--- " "--- " "---")) (cond ((and (<= L_GF 0) (<= L_VF 0)) (princ "\n -> Grund: L_GF und L_VF sind negativ (Strecke zu kurz)")) ((<= L_GF 0) (princ "\n -> Grund: L_GF ist negativ (Gefaellestrecke zu kurz)")) ((<= L_VF 0) (princ "\n -> Grund: L_VF ist negativ (keine passende Steigung moeglich)")) ((null best-winkel) (princ "\n -> Grund: Kein passender Winkel (Hoehendifferenz zu gross/klein)")) (t (princ "\n -> Grund: Unbekannter Fehler in der Berechnung")) ) (setq zusammenfassung-liste (cons (list idx richtung deltaH "NICHT_GEBAUT" nil nil nil) zusammenfassung-liste)) ) ) (setq y-offset (- y-offset 200)) ) ;; ========================================================== ;; TEIL 2: Abwaerts-Tests (6 Foerderer) ;; ========================================================== (foreach deltaH hoehen-liste (setq idx (1+ idx)) (setq richtung "Ab") (if (< deltaH 1) (progn ;; deltaH = 0 bei Abwaerts ist prinzipiell unmoeglich (setq anz-nicht-gebaut (1+ anz-nicht-gebaut)) (princ (strcat "\n " (itoa idx) " " (if (< idx 10) " " "") "Ab " (rtos deltaH 4 0) " " "NICHT " "--- " "--- " "---")) (princ "\n -> Grund: Bei Richtung 'Ab' mit dH=0 ist aus geometrischen Gruenden") (princ "\n keine Foerderanlage moeglich (immer negative Netto-Hoehe)") (setq zusammenfassung-liste (cons (list idx richtung deltaH "GEOMETRISCH_UNMOEGLICH" nil nil nil) zusammenfassung-liste)) ) (progn (setq ergebnis (berechne-alle-winkel deltaL deltaH richtung)) (setq best-winkel (car ergebnis)) (setq L_GF (cadr ergebnis)) (setq L_VF (caddr ergebnis)) (if (and best-winkel L_GF L_VF (> L_GF 0) (> L_VF 0)) (progn (setq anz-gebaut (1+ anz-gebaut)) (princ (strcat "\n " (itoa idx) " " (if (< idx 10) " " "") "Ab " (rtos deltaH 4 0) " " "GEBAUT " (itoa best-winkel) " Grad " (rtos L_GF 2 1) " " (rtos L_VF 2 1))) (foerderanlage-einfuegen deltaL deltaH richtung best-winkel (/ L_GF 2.0) (/ L_GF 2.0) L_VF (list 0 y-offset 0)) (setq zusammenfassung-liste (cons (list idx richtung deltaH "GEBAUT" best-winkel L_GF L_VF) zusammenfassung-liste)) ) (progn (setq anz-nicht-gebaut (1+ anz-nicht-gebaut)) (princ (strcat "\n " (itoa idx) " " (if (< idx 10) " " "") "Ab " (rtos deltaH 4 0) " " "NICHT " "--- " "--- " "---")) (cond ((and (<= L_GF 0) (<= L_VF 0)) (princ "\n -> Grund: L_GF und L_VF sind negativ (Strecke zu kurz)")) ((<= L_GF 0) (princ "\n -> Grund: L_GF ist negativ (Gefaellestrecke zu kurz)")) ((<= L_VF 0) (princ "\n -> Grund: L_VF ist negativ (Hoehendifferenz zu klein fuer diesen Weg)")) ((null best-winkel) (princ "\n -> Grund: Kein passender Winkel (Hoehendifferenz zu gross)")) (t (princ "\n -> Grund: Unbekannter Fehler in der Berechnung")) ) (setq zusammenfassung-liste (cons (list idx richtung deltaH "NICHT_GEBAUT" nil nil nil) zusammenfassung-liste)) ) ) ) ) (setq y-offset (- y-offset 200)) ) ;; ========================================================== ;; TEIL 3: ZUSAMMENFASSUNG ;; ========================================================== (princ "\n\n================================================================================") (princ "\n ZUSAMMENFASSUNG") (princ (strcat "\n dL = " (rtos deltaL 2 0) " mm")) (princ "\n================================================================================") (foreach item (reverse zusammenfassung-liste) (setq nr (car item)) (setq richtung (cadr item)) (setq deltaH_val (caddr item)) (setq status (cadddr item)) (setq winkel (car (cddddr item))) (setq L_GF_val (cadr (cddddr item))) (setq L_VF_val (caddr (cddddr item))) (cond ((= status "GEBAUT") (princ (strcat "\n " (itoa nr) ". " richtung (if (= richtung "Auf") " " " ") (rtos deltaH_val 2 0) " mm " (itoa winkel) " Grad " (rtos L_GF_val 2 2) " mm " (rtos L_VF_val 2 2) " mm GEBAUT"))) ((= status "GEOMETRISCH_UNMOEGLICH") (princ (strcat "\n " (itoa nr) ". " richtung (if (= richtung "Auf") " " " ") (rtos deltaH_val 2 0) " mm " "--- " "--- mm " "--- mm GEOMETRISCH UNMOEGLICH"))) (t (princ (strcat "\n " (itoa nr) ". " richtung (if (= richtung "Auf") " " " ") (rtos deltaH_val 2 0) " mm " "--- " "--- mm " "--- mm NICHT GEBAUT"))) ) ) (princ "\n\n================================================================================") (princ (strcat "\n Erfolgreich gebaut: " (itoa anz-gebaut) " von " (itoa idx))) (princ (strcat "\n Erfolgsquote: " (rtos (/ (* anz-gebaut 100.0) idx) 2 1) "%")) (princ "\n================================================================================") (princ "\n\n Erklaerung:") (princ "\n ----------") (princ "\n GEBAUT:") (princ "\n - Auf, dH=0 -> L_VF > 0 kompensiert 3 Grad-Gefaellestrecken") (princ "\n - Auf, dH>0 -> Normalfall") (princ "\n - Ab, dH>=1000 -> Normalfall") (princ "\n") (princ "\n NICHT GEBAUT:") (princ "\n - Ab, dH=0 -> Geometrisch unmoeglich (Netto-Hoehe immer negativ)") (princ "\n - Auf, dH=5000 -> 48 Grad Steigung reicht nicht aus (L_VF negativ)") (princ "\n - Ab, dH=5000 -> 48 Grad Gefaelle reicht nicht aus") (princ "\n================================================================================") (ssg-end) ;; Datei speichern (if (getenv "DXFM_RESULTS") (setq result-pfad (getenv "DXFM_RESULTS")) (setq result-pfad (strcat (getenv "DXFM_BLOCKS") "/../results")) ) (setq dateiname (strcat result-pfad "/" (menucmd "M=$(edtime,$(getvar,date),YYYYMODD-HHmm)") ".dxf")) (princ (strcat "\n\nSpeichere als: " dateiname)) (command "_.DXFOUT" dateiname "V" "2018" "16") (princ "\n\n>>> FOERDERTEST abgeschlossen (12 Foerderer)! <<<") (princ) ) ;; ============================================================ ;; TEST_KSEINAUS - KS_EIN/KS_AUS Ausrichtungstest ;; ;; Fuegt alle Vario-Bloecke in 3 Gruppen ein, jeweils 2 Reihen: ;; Gruppe 1: Stationaere Elemente (AUS, EIN, Separator, Umlenk, Motor) ;; Gruppe 2: Alle Boegen aufwaerts (in Z verschoben) ;; Gruppe 3: Alle Boegen abwaerts (in Z verschoben) ;; ;; Pro Gruppe: ;; Reihe A: nach KS_EIN ausgerichtet (KS_EIN X/Y = Referenz-X/Y) ;; Reihe B: nach KS_AUS ausgerichtet (KS_AUS X/Y = Referenz-X/Y) ;; Luecke von 400mm zwischen den Reihen ;; ============================================================ ;; Hilfsfunktion: Eine Liste von Bloecken in 2 Reihen aufreihen ;; x-start: X-Position der Gruppe ;; y-start: Y-Startposition (wird zurueckgegeben als naechster freier Y) ;; z-offset: Z-Verschiebung (fuer Boegen) ;; Rueckgabe: naechste freie Y-Position (defun ks-test-reihe (namen x-start y-start z-offset y-abstand y-luecke / bname block-obj ks-data ks-ein ks-aus insert-pt offset-vec y-pos idx) ;; --- Reihe A: nach KS_EIN --- (princ "\n Reihe KS_EIN:") (setq y-pos y-start) (setq idx 0) (foreach bname namen (setq idx (1+ idx)) (setq insert-pt (list x-start y-pos z-offset)) (setq block-obj (vla-InsertBlock modelspace (vlax-3D-point insert-pt) bname 1.0 1.0 1.0 0)) (setq ks-data (extract-ks-from-block block-obj)) (setq ks-ein (cadr (assoc "KS_EIN" ks-data))) (if ks-ein (progn (setq offset-vec (list (- x-start (car (car ks-ein))) (- y-pos (cadr (car ks-ein))) (- z-offset (caddr (car ks-ein))))) (vla-Move block-obj (vlax-3D-point '(0 0 0)) (vlax-3D-point offset-vec)) (princ (strcat "\n " (itoa idx) ". " bname " OK")) ) (princ (strcat "\n " (itoa idx) ". " bname " WARNUNG: KS_EIN fehlt!")) ) (setq y-pos (- y-pos y-abstand)) ) ;; --- Luecke --- (setq y-pos (- y-pos y-luecke)) ;; --- Reihe B: nach KS_AUS --- (princ "\n Reihe KS_AUS:") (setq idx 0) (foreach bname namen (setq idx (1+ idx)) (setq insert-pt (list x-start y-pos z-offset)) (setq block-obj (vla-InsertBlock modelspace (vlax-3D-point insert-pt) bname 1.0 1.0 1.0 0)) (setq ks-data (extract-ks-from-block block-obj)) (setq ks-aus (cadr (assoc "KS_AUS" ks-data))) (if ks-aus (progn (setq offset-vec (list (- x-start (car (car ks-aus))) (- y-pos (cadr (car ks-aus))) (- z-offset (caddr (car ks-aus))))) (vla-Move block-obj (vlax-3D-point '(0 0 0)) (vlax-3D-point offset-vec)) (princ (strcat "\n " (itoa idx) ". " bname " OK")) ) (princ (strcat "\n " (itoa idx) ". " bname " WARNUNG: KS_AUS fehlt!")) ) (setq y-pos (- y-pos y-abstand)) ) ;; Naechste freie Y-Position zurueckgeben y-pos ) (defun c:TEST_KSEINAUS ( / stationen boegen-auf-liste boegen-ab-liste bname y-pos y-abstand y-luecke z-bogen) ;; Bibliothek initialisieren (if (not *lib-initialized*) (init-bibliothek) ) (ssg-start "TEST_KSEINAUS" '(("OSMODE") ("CECOLOR") ("ATTREQ") ("ATTDIA"))) (setvar "OSMODE" 0) (setvar "ATTREQ" 0) (setvar "ATTDIA" 0) (setq y-abstand 200) (setq y-luecke 400) (setq z-bogen 2500) ;; Gruppe 1: Stationaere Elemente (setq stationen (list "_3D_AS_90_links" "Staustrecke_Separator_SP_300_mm" "Vario_Umlenkstation_500mm" "Vario_Motorstation_500mm" "_3D_ES_90_links" )) ;; Gruppe 2+3: Boegen sammeln (setq boegen-auf-liste '()) (setq boegen-ab-liste '()) (foreach w '(3 6 9 12 15 18 21 27 33 39 45 51) (setq bname (strcat "Vario_Bogen_auf_" (itoa w) grad-zeichen)) (if (tblsearch "BLOCK" bname) (setq boegen-auf-liste (append boegen-auf-liste (list bname))) ) (setq bname (strcat "Vario_Bogen_ab_" (itoa w) grad-zeichen)) (if (tblsearch "BLOCK" bname) (setq boegen-ab-liste (append boegen-ab-liste (list bname))) ) ) (princ "\n================================================================") (princ "\n TEST_KSEINAUS - KS-Ausrichtungstest") (princ (strcat "\n Stationen: " (itoa (length stationen)))) (princ (strcat "\n Boegen auf: " (itoa (length boegen-auf-liste)))) (princ (strcat "\n Boegen ab: " (itoa (length boegen-ab-liste)))) (princ (strcat "\n Z-Offset Boegen: " (rtos z-bogen 2 0) " mm")) (princ "\n================================================================") ;; Gruppe 1: Stationaere Elemente bei X=0, Z=0 (princ "\n\n GRUPPE 1: Stationaere Elemente (Z=0)") (setq y-pos (ks-test-reihe stationen 0 0 0 y-abstand y-luecke)) ;; Gruppe 2: Boegen aufwaerts bei X=3000, Z=z-bogen (princ "\n\n GRUPPE 2: Boegen aufwaerts (Z=" ) (princ (strcat (rtos z-bogen 2 0) ")")) (setq y-pos (ks-test-reihe boegen-auf-liste 3000 0 z-bogen y-abstand y-luecke)) ;; Gruppe 3: Boegen abwaerts bei X=6000, Z=z-bogen (princ "\n\n GRUPPE 3: Boegen abwaerts (Z=") (princ (strcat (rtos z-bogen 2 0) ")")) (setq y-pos (ks-test-reihe boegen-ab-liste 6000 0 z-bogen y-abstand y-luecke)) (ssg-end) (princ "\n\n================================================================") (princ "\n TEST_KSEINAUS abgeschlossen") (princ "\n X=0: Stationen (KS_EIN + KS_AUS)") (princ "\n X=3000: Boegen auf (KS_EIN + KS_AUS)") (princ "\n X=6000: Boegen ab (KS_EIN + KS_AUS)") (princ "\n================================================================") (princ) )