export: Hilfskopien nach dem Export loeschen, IDs stabil ueber reservierte IDs

AS/ES-Marker werden wie alle Hilfskopien geloescht (ausser csv_leave_proxies). IDs von AS/ES, Separator-Kopien und Einheiten bleiben ueber reservierte IDs (XDATA SSG_ID_RES) am VF_n/GF_n-Wrapper stabil: AS|n/ES|n, K|i, U|n.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Michael Stangl
2026-09-28 10:14:02 +02:00
co-authored by Claude Opus 5.5
parent 5a13595289
commit 96ca43eff5
10 changed files with 290 additions and 84 deletions
+151 -57
View File
@@ -1072,7 +1072,7 @@
;; Symbole - als Sub-INSERTs in der Wrapper-Blockdefinition und sind damit
;; fuer (ssget "X" ...) unsichtbar. Dieses Muster findet sie in der
;; Blockdefinition (csv:nested-welt-records); gesetzt wird an ihrer Stelle
;; NICHT eine Kopie des Elements, sondern der dauerhafte Marker
;; NICHT eine Kopie des Elements, sondern der temporaere Marker
;; ZZ_ASES_MARKER (csv:asmark-aktualisieren).
(defun csv:pattern-nested-schleus ()
(export:pattern "pattern_schleuselement" "AS_Element*,ES_Element*")
@@ -1147,8 +1147,8 @@
;; wird, entscheidet der Aufrufer:
;; - csv:sep-proxies-erzeugen -> temporaere Kopie des Symbols selbst
;; (wird nach dem Export wieder geloescht)
;; - csv:asmark-aktualisieren -> dauerhafter AS/ES-Marker (bleibt stehen
;; und traegt die ID ueber Laeufe hinweg)
;; - csv:asmark-aktualisieren -> AS/ES-Marker (ebenfalls temporaer, seine
;; ID bleibt als reservierte ID am Wrapper)
;;
;; Die Kopie steht bewusst EXAKT auf der Weltposition/-drehung/-skalierung
;; ihres verpackten Vorbilds (frueher: +500 mm Versatz in Blockrichtung, rein
@@ -1322,7 +1322,7 @@
;; Setzt csv:nested-welt-records + csv:block-einfuegen-welt zusammen: fuer
;; jeden Fund eine ECHTE Kopie DESSELBEN Blocks an derselben Weltlage.
;; Die AS-/ES-Kettenenden laufen NICHT mehr hierueber - fuer sie setzt
;; csv:asmark-aktualisieren einen dauerhaften Marker (siehe dort).
;; csv:asmark-aktualisieren einen eigenen Marker (siehe dort).
;;
;; proxy-liste-Eintrag: (proxy-ename wrapper-ename typ (x y z) strecke-typ
;; trennsteg-ent) - trennsteg-ent = der verpackte Trennsteg (Kettenbaustein,
@@ -1485,7 +1485,7 @@
(setq *csv-sepliste-id-by-handle* nil)
;; --- Einen sepliste-Eintrag mit der ID seines Bauteils vermerken ---
;; Zwei Quellen schreiben in dieselbe Zuordnung - die dauerhaften AS/ES-Marker
;; Zwei Quellen schreiben in dieselbe Zuordnung - die AS/ES-Marker
;; (csv:asmark-ids-setzen) und die temporaeren Separator-Kopien
;; (csv:sepliste-ids-setzen). Beide muessen sich den Eintrag EINES Wrappers
;; teilen: ein zweites Paar (handle . alist) waere fuer assoc unsichtbar, die
@@ -1863,22 +1863,22 @@
;; AS-/ES-Marker (ZZ_ASES_MARKER)
;; ===========================================================================
;; Ein kleines Rechteck, das der Export an JEDES AS-/ES-Ende einer VF_n/GF_n-
;; Kette setzt und das dort DAUERHAFT stehen bleibt. Es ist zweierlei:
;; Kette setzt. Die Kettenenden stecken verpackt in der Wrapper-
;; Blockdefinition (AS_Element_*/ES_Element_*); der Marker vertritt sie im
;; Export als eigene Zeile. Wie die Separator-/Element-Kopien ist er TEMPORAER:
;; csv:run-export loescht ihn am Ende wieder, nur der Debug-Schalter
;; "csv_leave_proxies" (csv:hilfskopien-loeschen) laesst ihn zur Ansicht stehen.
;;
;; Sichtbarmachung - die Kettenenden stecken verpackt in der Wrapper-
;; Blockdefinition (AS_Element_*/ES_Element_*) und sind in der Zeichnung
;; sonst weder anklickbar noch als eigenes Objekt erkennbar.
;; ID-Traeger - das (unsichtbare) ID-Attribut des Markers fuellt
;; ssg-id-check-all, und der naechste Export VERWENDET DENSELBEN MARKER
;; WIEDER. Ein AS/ES behaelt seine TeileId dadurch ueber Exportlaeufe
;; hinweg - anders als die temporaeren Separator-Kopien, die bei jedem Lauf
;; neu entstehen und neue IDs bekommen.
;; Die ID ist trotzdem stabil: csv:asmark-ids-setzen legt sie als reservierte
;; ID (XDATA SSG_ID_RES, Schluessel "AS|1", siehe ssg-id-res-* in ssg_id.lsp)
;; am Wrapper ab, der naechste Export gibt sie dem neuen Marker wieder. Weil
;; ssg-id-max-in-ss die reservierten IDs mitzaehlt, vergibt ssg-id-check-all
;; sie in der Zwischenzeit an niemand anderen.
;;
;; Der Marker ist abgeleitete Geometrie: csv:asmark-aktualisieren baut bei
;; JEDEM Export alle Marker neu auf (Lage folgt damit automatisch einer
;; umgebauten Kette) und uebernimmt dabei nur die ID des bisherigen Markers.
;; Nicht wiederverwendete Marker werden geloescht - ein Marker ohne Kette
;; bleibt also nicht als Karteileiche stehen.
;; Aeltere Zeichnungen (und ein Lauf mit csv_leave_proxies) haben noch Marker
;; in der Zeichnung stehen: deren ID wird uebernommen, falls der Wrapper noch
;; keine reservierte ID fuehrt (csv:asmark-finden), danach werden sie
;; geloescht.
(defun csv:asmark-blockname () "ZZ_ASES_MARKER")
@@ -1994,18 +1994,25 @@
treffer
)
;; --- Schluessel der reservierten ID eines Kettenendes am Wrapper ---
;; typ = "AS"/"ES", lfdnr = Integer oder String. Beispiel: "AS|1".
(defun csv:asmark-res-key (typ lfdnr)
(strcat typ "|" (if (numberp lfdnr) (itoa lfdnr) lfdnr))
)
;; --- Alle AS-/ES-Marker der Zeichnung neu aufbauen ---
;; Laeuft VOR ssg-id-check-all (csv:export-vorbereiten): neue Marker haben dann
;; noch kein ID-Attribut und werden dort nummeriert, uebernommene tragen die ID
;; ihres Vorgaengers und behalten sie.
;; noch kein ID-Attribut und werden dort nummeriert, uebernommene tragen die
;; reservierte ID des Wrappers (bzw. die ihres noch stehenden Vorgaengers).
;;
;; Ablauf je VF_n/GF_n-Wrapper mit sepliste:
;; 1. Weltlage aller verpackten AS-/ES-Elemente holen (csv:nested-welt-records)
;; 2. sie den AS-/ES-Eintraegen der sepliste zuordnen (csv:sepliste-paare -
;; dieselbe exklusive Zuordnung wie bei den Separator-Kopien; SEP-Eintraege
;; finden hier keinen Partner und bleiben unberuehrt)
;; 3. je Paar den bisherigen Marker suchen, seine ID merken, ihn loeschen und
;; an der AKTUELLEN Lage neu setzen
;; 3. je Paar die bisherige ID holen (reservierte ID am Wrapper, sonst ein
;; noch stehender Marker - der wird geloescht) und den Marker an der
;; AKTUELLEN Lage neu setzen
;; Was danach im Bestand uebrig ist, gehoert zu keiner Kette mehr und wird
;; geloescht.
;;
@@ -2014,7 +2021,8 @@
(defun csv:asmark-aktualisieren ( / recs bestand blockname ms wrapper-enames rec
wrapper ed bname wrapper-id app sepliste eigene
proxies paare paar elem lfdnr typ alt alt-id
mark artinr m neu uebernommen verwaist ergebnis)
mark artinr m neu uebernommen verwaist ergebnis
reserviert)
(setq neu 0 uebernommen 0 verwaist 0)
(setq recs (csv:nested-welt-records (csv:pattern-nested-schleus)))
(setq bestand (csv:asmark-sammeln))
@@ -2049,19 +2057,25 @@
(list (csv:proxy-typ (nth 2 r)) (car (nth 3 r)) (cadr (nth 3 r)))))
eigene))
(setq paare (csv:sepliste-paare sepliste proxies))
(setq reserviert (ssg-id-res-lesen wrapper))
(foreach paar paare
(setq lfdnr (nth 0 paar))
(setq elem (nth (nth 1 paar) eigene))
(setq typ (csv:proxy-typ (nth 2 elem)))
;; ID-Quelle: reservierte ID am Wrapper, sonst (Altbestand /
;; csv_leave_proxies) der noch stehende Marker.
(setq alt (csv:asmark-finden bestand wrapper-id typ (itoa lfdnr)))
(setq alt-id "")
(setq alt-id (cond ((cdr (assoc (csv:asmark-res-key typ lfdnr) reserviert)))
(alt (nth 4 alt))
("")))
(if alt
(progn
(setq alt-id (nth 4 alt))
(entdel (nth 0 alt))
(setq bestand (vl-remove alt bestand))
(setq uebernommen (1+ uebernommen))
)
)
(if (> (strlen alt-id) 0)
(setq uebernommen (1+ uebernommen))
(setq neu (1+ neu))
)
;; Marker mit Skalierung 1.0 einfuegen - die Skalierung des
@@ -2098,6 +2112,9 @@
;; 5. Feld: das verpackte Element (Schluessel fuer die ID-
;; Vergabe in Kettenfolge, csv:ketten-ids-vergeben).
(setq ergebnis (cons (list mark wrapper typ lfdnr (nth 1 elem)) ergebnis))
;; ID nach dem Export als reservierte ID am Wrapper ablegen
;; (csv:res-ids-schreiben).
(csv:res-merken wrapper (csv:asmark-res-key typ lfdnr) mark)
)
)
)
@@ -2128,6 +2145,7 @@
;; erneut an; die TeileId waere dann doch nicht stabil.
;; 2. die ID des Markers unter *csv-sepliste-id-by-handle* eintragen, damit
;; csv:block-to-json sie als Feld "id" am AS-/ES-Eintrag schreibt.
;; Die ID selbst legt csv:res-ids-schreiben als reservierte ID am Wrapper ab.
;; Rueckgabe: Anzahl der Eintraege mit ID.
(defun csv:asmark-ids-setzen (marker-liste / rec mark wrapper handle wrapper-id id
gesetzt ohne-id)
@@ -2334,14 +2352,72 @@
ib (atoi (cond ((cdr (assoc "ID" (ssg-attrib-read b)))) (""))))
(cond ((= ia 0) nil) ((= ib 0) t) (t (< ia ib)))))))
;; ===========================================================================
;; Stabile IDs der temporaeren Kettenobjekte (reservierte IDs am Wrapper)
;; ===========================================================================
;; AS-/ES-Marker, Separator-/Element-Kopien und Einheiten-Proxies entstehen
;; bei jedem Export neu und werden danach geloescht. Ihre ID bleibt trotzdem
;; gleich: sie wird als reservierte ID (XDATA SSG_ID_RES, ssg-id-res-* in
;; ssg_id.lsp) am VF_n/GF_n-Wrapper abgelegt und beim naechsten Export dem
;; neuen Objekt an derselben Stelle wiedergegeben. Schluessel:
;; "AS|n"/"ES|n" - AS-/ES-Marker, n = sepliste-lfdnr (csv:asmark-res-key)
;; "K|i" - Kopie des i-ten Bausteins der geordneten Kette
;; (0-basiert, Reihenfolge von csv:kette-ordnen)
;; "U|n" - n-te Einheit des Wrappers (Modus group_vf_gf)
;; Die Positionen sind deterministisch, solange der Wrapper unveraendert ist;
;; ein Edit baut einen NEUEN Wrapper (ohne diese XDATA) - dann entstehen neue
;; IDs, verschobene Zuordnungen aber nicht.
;;
;; Ablauf: die Erzeuger melden jedes Objekt mit csv:res-merken an, NACH
;; ssg-id-check-all schreibt csv:res-ids-schreiben je Wrapper den kompletten
;; Stand (ersetzt den alten - Eintraege fuer entfallene Objekte verschwinden).
;; Sammlung dieses Laufs: ((wrapper (key . ename) ...) ...)
(setq *csv-res-sammlung* nil)
(defun csv:res-key-kette (i) (strcat "K|" (itoa i)))
(defun csv:res-key-einheit (lfdnr) (strcat "U|" (itoa lfdnr)))
;; Objekt ename unter key fuer den Wrapper anmelden.
(defun csv:res-merken (wrapper key ename / eintrag)
(setq eintrag (assoc wrapper *csv-res-sammlung*))
(if eintrag
(setq *csv-res-sammlung*
(subst (append eintrag (list (cons key ename))) eintrag *csv-res-sammlung*))
(setq *csv-res-sammlung*
(cons (list wrapper (cons key ename)) *csv-res-sammlung*)))
ename
)
;; Nach der ID-Vergabe: je Wrapper die IDs aller angemeldeten Objekte als
;; reservierte IDs schreiben. Rueckgabe: Anzahl geschriebener IDs.
(defun csv:res-ids-schreiben ( / eintrag paare p id n)
(setq n 0)
(foreach eintrag *csv-res-sammlung*
(setq paare nil)
(foreach p (cdr eintrag)
(setq id (cdr (assoc "ID" (ssg-attrib-read (cdr p)))))
(if (and id (> (strlen id) 0))
(setq paare (cons (cons (car p) id) paare))))
(ssg-id-res-schreiben (car eintrag) (reverse paare))
(setq n (+ n (length paare)))
)
(setq *csv-res-sammlung* nil)
n
)
;; --- Einem Export-Objekt die naechste ID geben, falls es noch keine hat ---
;; naechste-id = zuletzt vergebene Nummer. Rueckgabe: neue letzte Nummer.
(defun csv:id-vergeben (ename naechste-id / id)
;; naechste-id = zuletzt vergebene Nummer, res-id = reservierte ID fuer dieses
;; Objekt (oder nil) - wird bevorzugt und verbraucht keine neue Nummer.
;; Rueckgabe: neue letzte Nummer.
(defun csv:id-vergeben (ename naechste-id res-id / id)
(setq id (cdr (assoc "ID" (ssg-attrib-read ename))))
(if (or (null id) (= id ""))
(progn
(setq naechste-id (1+ naechste-id))
(ssg-id-set-and-verify ename (ssg-id-format naechste-id) "Kettenfolge")))
(if (and res-id (> (strlen res-id) 0))
(ssg-id-set-and-verify ename res-id "reservierte ID")
(progn
(setq naechste-id (1+ naechste-id))
(ssg-id-set-and-verify ename (ssg-id-format naechste-id) "Kettenfolge"))))
naechste-id
)
@@ -2359,8 +2435,8 @@
;; Ohne diese Vergabe nummeriert erst ssg-id-check-all - in der Reihenfolge
;; von (ssget "X"), in BricsCAD also rueckwaerts (zuletzt erzeugt zuerst).
;; Die Export-CSV ist nach TeileId sortiert, damit stehen die Zeilen jeder
;; Kette jetzt von AS nach ES. Bereits vorhandene IDs (dauerhafte AS/ES-
;; Marker) bleiben unangetastet.
;; Kette jetzt von AS nach ES. Bereits vorhandene IDs (AS/ES-Marker mit
;; reservierter ID vom Wrapper) bleiben unangetastet.
;; sep-proxies/element-proxies/asmarks = die Stellvertreter-Listen dieses
;; Laufs (letztes Feld jedes Records = verpackter Baustein).
;; Rueckgabe: Einheiten-Proxy-Records (proxy-ename wrapper-ename typ lfdnr) -
@@ -2368,7 +2444,7 @@
(defun csv:ketten-verarbeiten (sep-proxies element-proxies asmarks
/ alt gruppiert blockname ms traeger r naechste-id
wrapper teile einheit lfdnr mark starts
i teil u tr ergebnis)
i teil u tr ergebnis res key)
(setq alt (csv:unitmark-bestand-loeschen))
(setq gruppiert (= *csv-export-modus* "group_vf_gf"))
(if gruppiert (setq blockname (csv:unitmark-blockdef-sicherstellen)))
@@ -2384,7 +2460,8 @@
(foreach wrapper (csv:wrapper-nach-id)
(setq teile (csv:kette-ordnen (csv:kette-teile wrapper)
(cdr (assoc 2 (entget wrapper)))))
;; Einheiten (nur gruppiert); starts = ((erster-index . proxy) ...)
(setq res (ssg-id-res-lesen wrapper))
;; Einheiten (nur gruppiert); starts = ((erster-index key . proxy) ...)
(setq starts nil lfdnr 0)
(if (and gruppiert blockname)
(foreach einheit (csv:kette-einheiten (mapcar 'car teile))
@@ -2394,14 +2471,26 @@
(if mark
(progn
(setq ergebnis (cons (list mark wrapper (car einheit) lfdnr) ergebnis))
(setq starts (cons (cons (car (cadr einheit)) mark) starts))))))
;; IDs entlang der Kette
(setq starts (cons (list (car (cadr einheit)) (csv:res-key-einheit lfdnr) mark)
starts))))))
;; IDs entlang der Kette - reservierte ID des Platzes zuerst (siehe
;; csv:res-merken); AS-/ES-Marker haben ihre ID schon und sind bereits
;; unter ihrem eigenen Schluessel angemeldet (csv:asmark-aktualisieren).
(setq i 0)
(foreach teil teile
(foreach u starts
(if (= (car u) i) (setq naechste-id (csv:id-vergeben (cdr u) naechste-id))))
(if (= (nth 0 u) i)
(progn
(setq naechste-id (csv:id-vergeben (nth 2 u) naechste-id
(cdr (assoc (nth 1 u) res))))
(csv:res-merken wrapper (nth 1 u) (nth 2 u)))))
(if (setq tr (cdr (assoc (list wrapper (nth 1 (nth 1 teil))) traeger)))
(setq naechste-id (csv:id-vergeben tr naechste-id)))
(if (member (car teil) '("AS" "ES"))
(setq naechste-id (csv:id-vergeben tr naechste-id nil))
(progn
(setq key (csv:res-key-kette i))
(setq naechste-id (csv:id-vergeben tr naechste-id (cdr (assoc key res))))
(csv:res-merken wrapper key tr))))
(setq i (1+ i)))
)
(if gruppiert
@@ -2551,21 +2640,22 @@
;; den Zeichnungszustand herrichten - Separator-Proxies einpacken, IDs
;; sicherstellen, Proxy-Zuordnung setzen, Omniflo-Attribute (HOEHE/DREHUNG)
;; aktualisieren, Separator-/Scanner-Zuordnung pruefen, global regenerieren und
;; die bbox-Fehlerdiagnose zuruecksetzen. Rueckgabe: die Liste ALLER erzeugten
;; Kopien - Separatoren UND AS/ES-Schleuselemente (der Aufrufer entfernt sie am
;; Ende wieder). label dient nur den Meldungen.
;; die bbox-Fehlerdiagnose zuruecksetzen. Rueckgabe: (sep-proxies
;; element-proxies unitmarks asmarks) - alle temporaer, der Aufrufer entfernt
;; sie am Ende wieder. label dient nur den Meldungen.
(defun csv:export-vorbereiten (label / sep-proxies asmarks element-proxies unitmarks)
;; Baustein-Geometrie der Stellvertreter (Separator-Kopie, AS-/ES-Marker)
;; wird beim Erzeugen neu gemerkt - Stand eines frueheren Laufs verwerfen.
(setq *csv-baustein-by-handle* nil)
;; Anmeldungen fuer die reservierten IDs (csv:res-merken) dieses Laufs.
(setq *csv-res-sammlung* nil)
;; Verpackte Separator_SP-Symbole (siehe csv:sep-proxies-erzeugen) VOR der
;; ID-Vergabe durch temporaere, echte Kopien ersetzen - sie werden am Ende
;; von csv:run-export wieder entfernt (csv:sep-proxies-loeschen).
(setq sep-proxies (csv:sep-proxies-erzeugen))
;; Die AS-/ES-Kettenenden stecken ebenfalls verpackt im Wrapper, bekommen
;; aber KEINE temporaere Kopie, sondern einen DAUERHAFTEN Marker
;; (ZZ_ASES_MARKER): er macht das Kettenende in der Zeichnung sichtbar und
;; traegt dessen ID ueber Exportlaeufe hinweg (siehe csv:asmark-*).
;; Die AS-/ES-Kettenenden stecken ebenfalls verpackt im Wrapper und
;; bekommen einen temporaeren Marker (ZZ_ASES_MARKER); ihre ID bleibt als
;; reservierte ID am Wrapper ueber Exportlaeufe hinweg (siehe csv:asmark-*).
(setq asmarks (csv:asmark-aktualisieren))
;; Die uebrigen Kettenbausteine (Boegen, gerade Foerderer-/Gefaellestrecken-
;; Segmente, Umlenk-/Motorstation) als temporaere Kopien - NUR im Modus
@@ -2602,6 +2692,9 @@
(csv:asmark-ids-setzen asmarks)
(csv:sepliste-ids-setzen sep-proxies)
(csv:unitmark-ids-setzen unitmarks)
;; IDs aller temporaeren Kettenobjekte als reservierte IDs am Wrapper
;; ablegen - der naechste Export gibt sie ihnen zurueck (csv:res-merken).
(csv:res-ids-schreiben)
;; Vor dem Export HOEHE/DREHUNG aller Omniflo-Elemente aktualisieren
(princ (ssg-textf "exp-update-hoehe-drehung" (list label)))
(omni:update-all-attribs)
@@ -2637,10 +2730,9 @@
;; bbox-Fehlerdiagnose fuer diesen Lauf zuruecksetzen (siehe csv:get-bbox).
(setq *csv-bbox-fail-count* 0)
(setq *csv-bbox-fail-first* nil)
;; Nur die TEMPORAEREN Hilfsmittel zurueckgeben (Separator-/Element-Kopien,
;; Einheiten-Proxies) - die AS/ES-Marker bleiben bewusst in der Zeichnung
;; stehen und duerfen nicht mitgeloescht werden.
(list sep-proxies element-proxies unitmarks))
;; Alle temporaeren Hilfsmittel zurueckgeben (Separator-/Element-Kopien,
;; Einheiten-Proxies, AS-/ES-Marker) - csv:run-export entfernt sie wieder.
(list sep-proxies element-proxies unitmarks asmarks))
;; --- Python-Export-Skript aufrufen und Ergebnis auswerten ---------------
;; Aus csv:run-export ausgelagert: das fertige raw-JSON (out-pfad) an das
@@ -2706,14 +2798,15 @@
;; (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
first-block count out-dir sep-proxies element-proxies
unitmarks vorbereitung-ergebnis)
unitmarks asmarks vorbereitung-ergebnis)
;; Zeichnungszustand fuer den Export herrichten (Proxies, IDs, Zuordnung,
;; Attribut-Update, Sep/Scan-Zaehlung, REGENALL, bbox-Reset) - ausgelagert.
;; Rueckgabe: (sep-proxies element-proxies unitmarks), alle unten wieder zu entfernen.
;; Rueckgabe: (sep-proxies element-proxies unitmarks asmarks), alle unten wieder zu entfernen.
(setq vorbereitung-ergebnis (csv:export-vorbereiten label))
(setq sep-proxies (nth 0 vorbereitung-ergebnis))
(setq element-proxies (nth 1 vorbereitung-ergebnis))
(setq unitmarks (nth 2 vorbereitung-ergebnis))
(setq asmarks (nth 3 vorbereitung-ergebnis))
(princ (ssg-textf "exp-collect-blocks" (list label)))
(setq ss (csv:collect-export-blocks))
@@ -2779,11 +2872,12 @@
)
)
)
;; Temporaere Separator-/Element-Kopien wieder entfernen - sie haben ihren
;; Zweck (ID-Vergabe + JSON-Zeile ueber die obigen, unveraenderten
;; Sammel-Funktionen) erfuellt. Die AS-/ES-Marker (ZZ_ASES_MARKER) bleiben
;; bewusst stehen (siehe csv:export-vorbereiten).
;; Temporaere Separator-/Element-Kopien und AS-/ES-Marker wieder entfernen -
;; sie haben ihren Zweck (ID-Vergabe + JSON-Zeile ueber die obigen,
;; unveraenderten Sammel-Funktionen) erfuellt. Die AS-/ES-IDs bleiben als
;; reservierte IDs am Wrapper (csv:asmark-ids-setzen).
(csv:sep-proxies-loeschen sep-proxies)
(csv:hilfskopien-loeschen asmarks "exp-art-ases")
(csv:hilfskopien-loeschen element-proxies "exp-art-element")
(csv:hilfskopien-loeschen unitmarks "exp-art-einheit")
(princ)
+58 -2
View File
@@ -69,8 +69,8 @@
;; ZZ_ASES_MARKER: die Marker der AS-/ES-Kettenenden (siehe
;; csv:asmark-aktualisieren, export.lsp). Sie brauchen eine ID -
;; sie vertreten das Kettenende im Export ("sepliste"-Feld "id"
;; und eigene JSON-Zeile) und behalten sie ueber Laeufe hinweg,
;; weil der Marker in der Zeichnung stehen bleibt.
;; und eigene JSON-Zeile). Der Marker selbst ist temporaer, seine
;; ID bleibt als reservierte ID am Wrapper (ssg-id-res-*).
(wcmatch bname "ZZ_ASES_MARKER*")
;; ZZ_UNIT_MARKER: die Foerdereinheit-/Gefaelleeinheit-Marker
;; (siehe csv:ketten-verarbeiten, export.lsp) - temporaere
@@ -93,9 +93,64 @@
)
;; ============================================================
;; Reservierte IDs (XDATA "SSG_ID_RES")
;; ============================================================
;; IDs von Objekten, die NICHT dauerhaft in der Zeichnung stehen, aber ueber
;; Laeufe hinweg dieselbe ID behalten sollen - z.B. die AS-/ES-Kettenenden
;; eines VF_n/GF_n-Wrappers: ihr Export-Stellvertreter (ZZ_ASES_MARKER) wird
;; nach jedem Export geloescht, die ID bleibt als XDATA am Wrapper stehen
;; (csv:asmark-*, export.lsp). Format: (("AS|1" . "0032") ("ES|4" . "0033")),
;; Schluessel frei waehlbar, aber ohne "=".
;;
;; ssg-id-max-in-ss rechnet reservierte IDs mit ein: sonst saehe die
;; Neuvergabe die ID eines gerade nicht existierenden Stellvertreters als frei
;; an und vergaebe sie an einen anderen Block.
(defun ssg-id-res-app () "SSG_ID_RES")
;; Rein (file-/zeichnungsfrei): Paare <-> 1000er-Strings "AS|1=0032".
(defun ssg-id-res->strings (paare)
(mapcar (function (lambda (p) (strcat (car p) "=" (cdr p)))) paare)
)
(defun ssg-id-res-parse (strings / s pos out)
(foreach s strings
(if (setq pos (vl-string-search "=" s))
(setq out (cons (cons (substr s 1 pos) (substr s (+ pos 2))) out))))
(reverse out)
)
;; Hoechste numerische ID der Paare (0, wenn keine).
(defun ssg-id-res-max (paare / m n)
(setq m 0)
(foreach p paare
(if (> (setq n (atoi (cdr p))) m) (setq m n)))
m
)
;; Liest die reservierten IDs eines Entities. Rueckgabe: Paare oder nil.
(defun ssg-id-res-lesen (ent / app-data)
(setq app-data (cdr (assoc -3 (entget ent (list (ssg-id-res-app))))))
(if app-data
(ssg-id-res-parse (mapcar 'cdr (cdr (car app-data))))
)
)
;; Schreibt die reservierten IDs eines Entities (ersetzt den bisherigen Stand
;; komplett). paare = nil entfernt die XDATA.
(defun ssg-id-res-schreiben (ent paare)
(regapp (ssg-id-res-app))
(entmod (append (entget ent)
(list (list -3 (cons (ssg-id-res-app)
(mapcar (function (lambda (s) (cons 1000 s)))
(ssg-id-res->strings paare)))))))
ent
)
;; --- Hoechste bereits vergebene ID in einem Auswahlsatz ermitteln ---
;; ss = Auswahlsatz (i.d.R. aus ssg-id-collect-blocks) oder nil.
;; Rueckgabe: Integer (hoechste ID) oder 0 wenn keine gefunden.
;; Beruecksichtigt auch die reservierten IDs (ssg-id-res-lesen) der Bloecke.
;;
;; Bewusst als eigene Funktion: ssg-id-check-all MUSS diesen Wert ueber den
;; GESAMTEN Auswahlsatz kennen, BEVOR es die erste neue ID vergibt (siehe
@@ -118,6 +173,7 @@
)
)
)
(setq max-id (max max-id (ssg-id-res-max (ssg-id-res-lesen ename))))
(setq i (1+ i))
)
)