diff --git a/Lisp/README.md b/Lisp/README.md index 83eeba6..96846b0 100644 --- a/Lisp/README.md +++ b/Lisp/README.md @@ -395,7 +395,7 @@ Sammelt INSERT-Blöcke aus der Zeichnung und exportiert sie als JSON oder ruft P | `c:EXPORTSIVAS` | Alle Blöcke als JSON sammeln und `export_sivas.py` aufrufen (Sivas-CSV) | | `c:EXPORTCSV` | Alle Blöcke als JSON sammeln und `export_csv.py` aufrufen (einfache Item-Liste, inkl. Omniflo Bogen/Weiche/Gerade und abschließender "Omniflo Sum"-Zeile) | | `csv:collect-export-blocks` | Alle INSERT-Blöcke der Zeichnung als JSON-Array sammeln | -| `csv:run-export py-skript json-datei output-csv` | Python-Skript mit gesammelten Daten aufrufen | +| `csv:run-export py-skript json-datei output-csv` | Python-Skript mit gesammelten Daten aufrufen; legt vorher fuer in VF_n/GF_n/KREISEL_n **verpackte** Separator_SP_2D/_3D-Sub-INSERTs (Sensor-Symbol; siehe `ssg-collect-nested-inserts` in `ssg_core.lsp` - NICHT der interne Staustrecke_Separator_SP-Trennsteg) je eine echte, temporaere Kopie daneben an (`csv:sep-proxies-erzeugen`), damit sie ganz normal ueber `ssg-id-check-all`/`csv:collect-export-blocks` erfasst werden, und entfernt sie danach wieder (`csv:sep-proxies-loeschen`) | | `csv:read-attribs ename` | Attribute eines INSERT als JSON-Objekt lesen | | `c:OMNI_UPDATE_ATTRIBS` | HOEHE/DREHUNG aller Omniflo-Elemente aus der Zeichnung aktualisieren | diff --git a/Lisp/export.lsp b/Lisp/export.lsp index 6ec8403..dfe1556 100644 --- a/Lisp/export.lsp +++ b/Lisp/export.lsp @@ -538,6 +538,117 @@ ) +;; --- Muster fuer verpackte (in einer Compound-Blockdefinition +;; verschachtelte) Separator-Sub-INSERTs --- +;; Beim finalen Zusammenbau von VF_n/GF_n/KREISEL_n werden Separator_SP- +;; Sensor-Symbole, die zuvor als eigene top-level INSERTs eingefuegt wurden, +;; zu Sub-INSERTs der Compound-Blockdefinition - (ssget "X" ...) findet sie +;; danach nicht mehr (siehe ssg-collect-nested-inserts, ssg_core.lsp). +;; Bewusst NUR das Sensor-SYMBOL (Separator_SP_2D/_3D), NICHT der intern +;; gezeichnete Staustrecke_Separator_SP-Trennsteg (300mm) - der ist ein +;; reines Geometrie-/Laengenelement der Staustrecke, kein eigenstaendig zu +;; zaehlendes Bauteil, und soll hier nicht mitkopiert werden. +(defun csv:pattern-nested-separator () + "Separator_SP_2D,Separator_SP_3D" +) + +;; --- Muster der Compound-("Wrapper"-)Bloecke, deren Definition ueberhaupt +;; auf verpackte Separator_SP-Symbole durchsucht wird (KR_n/KREISEL_n/ +;; ECKRAD_n/VF_n/GF_n) - alle anderen INSERTs (Omniflo, eigenstaendige +;; Separator_SP, ...) koennen von vornherein nichts "verpackt" enthalten +;; und werden gar nicht erst geprueft. +(defun csv:pattern-wrapper-fuer-proxies () + (strcat (export:pattern "pattern_kreisel" "KR_*,KREISEL_*,ECKRAD_*") ",VF_*,GF_*") +) + +;; --- Versatz (mm, in Blockrichtung +X) der temporaeren Separator-Kopien --- +;; "Einfach ausserhalb" der Original-Geometrie, damit sie nicht exakt auf +;; ihr verpacktes Vorbild zu liegen kommen (rein kosmetisch/zur Unter- +;; scheidbarkeit waehrend der - sehr kurzen - Lebensdauer der Kopie). +(setq *csv-sep-proxy-versatz-mm* 500.0) + +;; --- Fuer jedes verpackte Separator_SP-Symbol eine ECHTE, temporaere Kopie +;; daneben in den Modellraum einfuegen --- +;; Separator_SP-Sensor-Symbole, die beim Zusammenbau von VF_n/GF_n/ +;; KREISEL_n in die Compound-Blockdefinition "verpackt" wurden (siehe +;; ssg-collect-nested-inserts), sind fuer (ssget "X" ...) unsichtbar - und +;; damit weder fuer ssg-id-check-all (eigene ID) noch csv:collect-export- +;; blocks (JSON-Zeile) erreichbar. Statt beide Sammel-Funktionen dafuer +;; anzupassen, wird hier VOR der ID-Vergabe (csv:run-export) fuer jeden Fund +;; eine ECHTE Kopie desselben Blocks an seiner Weltposition (+ Versatz in +;; Blockrichtung, damit sie nicht exakt auf dem Original liegt) eingefuegt. +;; Diese Kopie ist ein normaler, top-level INSERT und durchlaeuft ID- +;; Vergabe/Export danach unveraendert ueber die bestehenden Funktionen - +;; deren Blockname-Muster (Separator_SP*) trifft ja bereits zu. +;; Einfuegen ueber vla-InsertBlock (ActiveX) statt "command _.INSERT": das +;; legt fuer einen Block mit ATTDEFs automatisch ATTRIB-Entities mit den +;; Vorgabewerten an (wie TEFInsert.lsp/tefl-insert-element, ssg_ks_insert.lsp +;; u.a. bereits nutzen) - OHNE jeden einzelnen Insert-Prompt (Blockname/ +;; Einfuegepunkt/Skalierung/Drehwinkel) ins Kommandozeilen-Fenster zu +;; schreiben. "command _.INSERT" wuerde das bei JEDEM verpackten Fund tun, +;; selbst wenn alle Werte per LISP vorgegeben sind - bei mehreren Funden +;; entsprechend viel Bildschirm-Rauschen. vla-get-ModelSpace wird hier LOKAL +;; ermittelt statt den (evtl. noch unbelegten) globalen "modelspace" aus +;; vf_core.lsp/Gefaellestrecke.lsp/ssg_ks_insert.lsp vorauszusetzen - die +;; koennten in dieser Sitzung noch gar nicht geladen worden sein, falls die +;; Zeichnung mit bereits vorhandenen VF_n/GF_n-Bloecken geoeffnet und direkt +;; exportiert wird, ohne vorher FOERDERANLAGE/GEFAELLESTRECKE aufzurufen. +;; Rueckgabe: Liste der neu eingefuegten Entity-Namen (fuer csv:sep-proxies- +;; loeschen nach dem Export). +(defun csv:sep-proxies-erzeugen ( / ms ss-all i ename ed bname nested pt rotation + nested-ent nested-ed nested-bname nested-rotation + local-pt world-pt block-obj proxy-liste) + (setq ss-all (ssget "X" (list (cons 0 "INSERT")))) + (if ss-all + (progn + (setq ms (vla-get-ModelSpace (vla-get-ActiveDocument (vlax-get-acad-object)))) + (setq i 0) + (while (setq ename (ssname ss-all i)) + (setq ed (entget ename)) + (setq bname (cdr (assoc 2 ed))) + (setq nested + (if (wcmatch bname (csv:pattern-wrapper-fuer-proxies)) + (ssg-collect-nested-inserts bname (csv:pattern-nested-separator)) + ) + ) + (if nested + (progn + (setq pt (cdr (assoc 10 ed))) + (setq rotation (cdr (assoc 50 ed))) + (if (null rotation) (setq rotation 0.0)) + (foreach nested-ent nested + (setq nested-ed (entget nested-ent)) + (setq nested-bname (cdr (assoc 2 nested-ed))) + (setq local-pt (cdr (assoc 10 nested-ed))) + (setq nested-rotation (cdr (assoc 50 nested-ed))) + (if (null nested-rotation) (setq nested-rotation 0.0)) + (setq world-pt (csv:local-to-world pt rotation local-pt)) + (setq world-pt (list (+ (car world-pt) *csv-sep-proxy-versatz-mm*) + (cadr world-pt) + (caddr world-pt))) + ;; Rotation fuer vla-InsertBlock in RADIANT (ActiveX-Konvention, + ;; anders als der Grad-Winkel von "command _.INSERT"). + (setq block-obj (vla-InsertBlock ms (vlax-3D-point world-pt) + nested-bname 1.0 1.0 1.0 (+ rotation nested-rotation))) + (setq proxy-liste (cons (vlax-vla-object->ename block-obj) proxy-liste)) + ) + ) + ) + (setq i (1+ i)) + ) + ) + ) + proxy-liste +) + +;; --- Temporaere Separator_SP-Kopien (csv:sep-proxies-erzeugen) nach dem +;; Export wieder entfernen --- +(defun csv:sep-proxies-loeschen (proxy-liste) + (foreach ent proxy-liste (entdel ent)) + (princ) +) + + ;; --- Relevante Bloecke sammeln --- ;; Filtert INSERT-Entities auf exportierbare Bloecke: ;; KR_* = Kreisel Compound-Bloecke @@ -620,7 +731,11 @@ ;; (siehe csv:block-to-json); fuer EXPORTSIVAS nil. (defun csv:run-export (label py-name csv-name include-bbox / ss i ename fh out-pfad py-skript ergebnis-pfad py-exe log-pfad rc first-block - count out-dir) + count out-dir sep-proxies) + ;; Verpackte Separator_SP-Symbole (siehe csv:sep-proxies-erzeugen) VOR der + ;; ID-Vergabe durch temporaere, echte Kopien ersetzen - sie werden am Ende + ;; dieser Funktion wieder entfernt (csv:sep-proxies-loeschen). + (setq sep-proxies (csv:sep-proxies-erzeugen)) ;; Vor dem Export: IDs aller Bloecke sicherstellen und Duplikate korrigieren (princ (ssg-textf "exp-check-ids" (list label))) (ssg-id-check-all) @@ -752,6 +867,10 @@ ) ) ) + ;; Temporaere Separator-/Scanner-Kopien wieder entfernen - sie haben ihren + ;; Zweck (ID-Vergabe + JSON-Zeile ueber die obigen, unveraenderten + ;; Sammel-Funktionen) erfuellt. + (csv:sep-proxies-loeschen sep-proxies) (princ) ) diff --git a/Lisp/ssg_core.lsp b/Lisp/ssg_core.lsp index 83d7dfe..68f9508 100644 --- a/Lisp/ssg_core.lsp +++ b/Lisp/ssg_core.lsp @@ -746,6 +746,51 @@ ) ) +;; --- Sub-INSERTs einer Blockdefinition nach Namensmuster sammeln --- +;; bname = Name einer Blockdefinition (z.B. eines VF_n/GF_n-Compound-Blocks) +;; pattern = wcmatch-Muster, z.B. "Separator_SP*,S-LP*" +;; Beim finalen Zusammenbau von VF_n/GF_n/KREISEL_n (ssg-block-wrap-welt bzw. +;; das abschliessende "_.-BLOCK") werden alle bis dahin einzeln eingefuegten +;; Bauteile - inkl. Sensoren wie Separator_SP, die vorher eigene, top-level +;; INSERTs waren - zu Sub-INSERTs IN DER Compound-Blockdefinition. Sie +;; verlieren dadurch ihre Sichtbarkeit fuer (ssget "X" ...): das findet nur +;; Entities im Modell-/Papierraum, keine Entities innerhalb einer +;; Blockdefinition. csv:sep-proxies-erzeugen (export.lsp) nutzt diese +;; Funktion, um genau die verpackten Separator_SP-Symbole vor dem Export +;; aufzuspueren und je eine echte, temporaere Kopie daneben einzufuegen - +;; die durchlaeuft ID-Vergabe/Export danach ganz normal ueber die +;; unveraenderten ssg-id-check-all/csv:collect-export-blocks. Rekursiv, +;; falls ein Treffer selbst nochmal in einem weiteren Sub-Compound-Block +;; steckt. Rueckgabe: Liste von Entity-Namen (aus der Blockdefinition, kein +;; Selection-Set - sie sind nicht Space-resident und daher fuer ssadd nicht +;; sicher verwendbar), oder nil. Die gefundenen Entity-Namen bleiben ueber +;; entget normal lesbar (Blockname/Einfuegepunkt/Rotation), sollten aber +;; NICHT direkt exportiert werden - eine eigene Bounding-Box +;; (vla-getboundingbox) liefert fuer sie keine sinnvollen Weltkoordinaten, +;; da sie nicht Space-resident sind. +(defun ssg-collect-nested-inserts (bname pattern / blk-tbl sub-ent sub-ed sub-bname result) + (setq blk-tbl (tblsearch "BLOCK" bname)) + (if blk-tbl + (progn + (setq sub-ent (entnext (cdr (assoc -2 blk-tbl)))) + (while sub-ent + (setq sub-ed (entget sub-ent)) + (if (= (cdr (assoc 0 sub-ed)) "INSERT") + (progn + (setq sub-bname (cdr (assoc 2 sub-ed))) + (if (wcmatch sub-bname pattern) + (setq result (cons sub-ent result)) + (setq result (append result (ssg-collect-nested-inserts sub-bname pattern))) + ) + ) + ) + (setq sub-ent (entnext sub-ent)) + ) + ) + ) + result +) + ;; ============================================================ ;; GEMEINSAMES ATTRIBUT-SCHEMA FUER STRECKEN-BLOECKE ;; (Gefaellestrecke + VarioFoerderer, feste Reihenfolge)