;; ============================================================ ;; 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_*") (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") )