[FEAT] Verpackte Separator_SP-Sensoren in VF_n/GF_n/KREISEL_n vor Export erfassen

Separator_SP_2D/_3D-Sensorsymbole, die beim Zusammenbau der Compound-Bloecke
(VF_n/GF_n/KREISEL_n) als Sub-INSERT in deren Blockdefinition verpackt
wurden, waren fuer (ssget "X" ...) unsichtbar und blieben daher ohne eigene
ID und ohne Zeile im Export-JSON. csv:sep-proxies-erzeugen (export.lsp)
sucht solche verpackten Symbole jetzt vor jedem EXPORTCSV/EXPORTSIVAS ueber
den neuen rekursiven Helfer ssg-collect-nested-inserts (ssg_core.lsp) und
legt fuer jeden Fund eine echte, temporaere Kopie an seiner Weltposition an
(silent ueber vla-InsertBlock statt command-line INSERT). Diese Kopie
durchlaeuft ID-Vergabe/Export unveraendert ueber die bestehenden Funktionen
und wird danach wieder entfernt (csv:sep-proxies-loeschen).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-02 10:03:00 +02:00
parent 04a12e5981
commit e2f038465b
3 changed files with 166 additions and 2 deletions
+120 -1
View File
@@ -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)
)