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 ;; Symbole - als Sub-INSERTs in der Wrapper-Blockdefinition und sind damit
;; fuer (ssget "X" ...) unsichtbar. Dieses Muster findet sie in der ;; fuer (ssget "X" ...) unsichtbar. Dieses Muster findet sie in der
;; Blockdefinition (csv:nested-welt-records); gesetzt wird an ihrer Stelle ;; 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). ;; ZZ_ASES_MARKER (csv:asmark-aktualisieren).
(defun csv:pattern-nested-schleus () (defun csv:pattern-nested-schleus ()
(export:pattern "pattern_schleuselement" "AS_Element*,ES_Element*") (export:pattern "pattern_schleuselement" "AS_Element*,ES_Element*")
@@ -1147,8 +1147,8 @@
;; wird, entscheidet der Aufrufer: ;; wird, entscheidet der Aufrufer:
;; - csv:sep-proxies-erzeugen -> temporaere Kopie des Symbols selbst ;; - csv:sep-proxies-erzeugen -> temporaere Kopie des Symbols selbst
;; (wird nach dem Export wieder geloescht) ;; (wird nach dem Export wieder geloescht)
;; - csv:asmark-aktualisieren -> dauerhafter AS/ES-Marker (bleibt stehen ;; - csv:asmark-aktualisieren -> AS/ES-Marker (ebenfalls temporaer, seine
;; und traegt die ID ueber Laeufe hinweg) ;; ID bleibt als reservierte ID am Wrapper)
;; ;;
;; Die Kopie steht bewusst EXAKT auf der Weltposition/-drehung/-skalierung ;; Die Kopie steht bewusst EXAKT auf der Weltposition/-drehung/-skalierung
;; ihres verpackten Vorbilds (frueher: +500 mm Versatz in Blockrichtung, rein ;; 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 ;; Setzt csv:nested-welt-records + csv:block-einfuegen-welt zusammen: fuer
;; jeden Fund eine ECHTE Kopie DESSELBEN Blocks an derselben Weltlage. ;; jeden Fund eine ECHTE Kopie DESSELBEN Blocks an derselben Weltlage.
;; Die AS-/ES-Kettenenden laufen NICHT mehr hierueber - fuer sie setzt ;; 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 ;; proxy-liste-Eintrag: (proxy-ename wrapper-ename typ (x y z) strecke-typ
;; trennsteg-ent) - trennsteg-ent = der verpackte Trennsteg (Kettenbaustein, ;; trennsteg-ent) - trennsteg-ent = der verpackte Trennsteg (Kettenbaustein,
@@ -1485,7 +1485,7 @@
(setq *csv-sepliste-id-by-handle* nil) (setq *csv-sepliste-id-by-handle* nil)
;; --- Einen sepliste-Eintrag mit der ID seines Bauteils vermerken --- ;; --- 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:asmark-ids-setzen) und die temporaeren Separator-Kopien
;; (csv:sepliste-ids-setzen). Beide muessen sich den Eintrag EINES Wrappers ;; (csv:sepliste-ids-setzen). Beide muessen sich den Eintrag EINES Wrappers
;; teilen: ein zweites Paar (handle . alist) waere fuer assoc unsichtbar, die ;; teilen: ein zweites Paar (handle . alist) waere fuer assoc unsichtbar, die
@@ -1863,22 +1863,22 @@
;; AS-/ES-Marker (ZZ_ASES_MARKER) ;; AS-/ES-Marker (ZZ_ASES_MARKER)
;; =========================================================================== ;; ===========================================================================
;; Ein kleines Rechteck, das der Export an JEDES AS-/ES-Ende einer VF_n/GF_n- ;; 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- ;; Die ID ist trotzdem stabil: csv:asmark-ids-setzen legt sie als reservierte
;; Blockdefinition (AS_Element_*/ES_Element_*) und sind in der Zeichnung ;; ID (XDATA SSG_ID_RES, Schluessel "AS|1", siehe ssg-id-res-* in ssg_id.lsp)
;; sonst weder anklickbar noch als eigenes Objekt erkennbar. ;; am Wrapper ab, der naechste Export gibt sie dem neuen Marker wieder. Weil
;; ID-Traeger - das (unsichtbare) ID-Attribut des Markers fuellt ;; ssg-id-max-in-ss die reservierten IDs mitzaehlt, vergibt ssg-id-check-all
;; ssg-id-check-all, und der naechste Export VERWENDET DENSELBEN MARKER ;; sie in der Zwischenzeit an niemand anderen.
;; 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.
;; ;;
;; Der Marker ist abgeleitete Geometrie: csv:asmark-aktualisieren baut bei ;; Aeltere Zeichnungen (und ein Lauf mit csv_leave_proxies) haben noch Marker
;; JEDEM Export alle Marker neu auf (Lage folgt damit automatisch einer ;; in der Zeichnung stehen: deren ID wird uebernommen, falls der Wrapper noch
;; umgebauten Kette) und uebernimmt dabei nur die ID des bisherigen Markers. ;; keine reservierte ID fuehrt (csv:asmark-finden), danach werden sie
;; Nicht wiederverwendete Marker werden geloescht - ein Marker ohne Kette ;; geloescht.
;; bleibt also nicht als Karteileiche stehen.
(defun csv:asmark-blockname () "ZZ_ASES_MARKER") (defun csv:asmark-blockname () "ZZ_ASES_MARKER")
@@ -1994,18 +1994,25 @@
treffer 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 --- ;; --- Alle AS-/ES-Marker der Zeichnung neu aufbauen ---
;; Laeuft VOR ssg-id-check-all (csv:export-vorbereiten): neue Marker haben dann ;; 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 ;; noch kein ID-Attribut und werden dort nummeriert, uebernommene tragen die
;; ihres Vorgaengers und behalten sie. ;; reservierte ID des Wrappers (bzw. die ihres noch stehenden Vorgaengers).
;; ;;
;; Ablauf je VF_n/GF_n-Wrapper mit sepliste: ;; Ablauf je VF_n/GF_n-Wrapper mit sepliste:
;; 1. Weltlage aller verpackten AS-/ES-Elemente holen (csv:nested-welt-records) ;; 1. Weltlage aller verpackten AS-/ES-Elemente holen (csv:nested-welt-records)
;; 2. sie den AS-/ES-Eintraegen der sepliste zuordnen (csv:sepliste-paare - ;; 2. sie den AS-/ES-Eintraegen der sepliste zuordnen (csv:sepliste-paare -
;; dieselbe exklusive Zuordnung wie bei den Separator-Kopien; SEP-Eintraege ;; dieselbe exklusive Zuordnung wie bei den Separator-Kopien; SEP-Eintraege
;; finden hier keinen Partner und bleiben unberuehrt) ;; finden hier keinen Partner und bleiben unberuehrt)
;; 3. je Paar den bisherigen Marker suchen, seine ID merken, ihn loeschen und ;; 3. je Paar die bisherige ID holen (reservierte ID am Wrapper, sonst ein
;; an der AKTUELLEN Lage neu setzen ;; 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 ;; Was danach im Bestand uebrig ist, gehoert zu keiner Kette mehr und wird
;; geloescht. ;; geloescht.
;; ;;
@@ -2014,7 +2021,8 @@
(defun csv:asmark-aktualisieren ( / recs bestand blockname ms wrapper-enames rec (defun csv:asmark-aktualisieren ( / recs bestand blockname ms wrapper-enames rec
wrapper ed bname wrapper-id app sepliste eigene wrapper ed bname wrapper-id app sepliste eigene
proxies paare paar elem lfdnr typ alt alt-id 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 neu 0 uebernommen 0 verwaist 0)
(setq recs (csv:nested-welt-records (csv:pattern-nested-schleus))) (setq recs (csv:nested-welt-records (csv:pattern-nested-schleus)))
(setq bestand (csv:asmark-sammeln)) (setq bestand (csv:asmark-sammeln))
@@ -2049,19 +2057,25 @@
(list (csv:proxy-typ (nth 2 r)) (car (nth 3 r)) (cadr (nth 3 r))))) (list (csv:proxy-typ (nth 2 r)) (car (nth 3 r)) (cadr (nth 3 r)))))
eigene)) eigene))
(setq paare (csv:sepliste-paare sepliste proxies)) (setq paare (csv:sepliste-paare sepliste proxies))
(setq reserviert (ssg-id-res-lesen wrapper))
(foreach paar paare (foreach paar paare
(setq lfdnr (nth 0 paar)) (setq lfdnr (nth 0 paar))
(setq elem (nth (nth 1 paar) eigene)) (setq elem (nth (nth 1 paar) eigene))
(setq typ (csv:proxy-typ (nth 2 elem))) (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 (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 (if alt
(progn (progn
(setq alt-id (nth 4 alt))
(entdel (nth 0 alt)) (entdel (nth 0 alt))
(setq bestand (vl-remove alt bestand)) (setq bestand (vl-remove alt bestand))
(setq uebernommen (1+ uebernommen))
) )
)
(if (> (strlen alt-id) 0)
(setq uebernommen (1+ uebernommen))
(setq neu (1+ neu)) (setq neu (1+ neu))
) )
;; Marker mit Skalierung 1.0 einfuegen - die Skalierung des ;; Marker mit Skalierung 1.0 einfuegen - die Skalierung des
@@ -2098,6 +2112,9 @@
;; 5. Feld: das verpackte Element (Schluessel fuer die ID- ;; 5. Feld: das verpackte Element (Schluessel fuer die ID-
;; Vergabe in Kettenfolge, csv:ketten-ids-vergeben). ;; Vergabe in Kettenfolge, csv:ketten-ids-vergeben).
(setq ergebnis (cons (list mark wrapper typ lfdnr (nth 1 elem)) ergebnis)) (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. ;; erneut an; die TeileId waere dann doch nicht stabil.
;; 2. die ID des Markers unter *csv-sepliste-id-by-handle* eintragen, damit ;; 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. ;; 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. ;; Rueckgabe: Anzahl der Eintraege mit ID.
(defun csv:asmark-ids-setzen (marker-liste / rec mark wrapper handle wrapper-id id (defun csv:asmark-ids-setzen (marker-liste / rec mark wrapper handle wrapper-id id
gesetzt ohne-id) gesetzt ohne-id)
@@ -2334,14 +2352,72 @@
ib (atoi (cond ((cdr (assoc "ID" (ssg-attrib-read b)))) ("")))) ib (atoi (cond ((cdr (assoc "ID" (ssg-attrib-read b)))) (""))))
(cond ((= ia 0) nil) ((= ib 0) t) (t (< ia ib))))))) (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 --- ;; --- Einem Export-Objekt die naechste ID geben, falls es noch keine hat ---
;; naechste-id = zuletzt vergebene Nummer. Rueckgabe: neue letzte Nummer. ;; naechste-id = zuletzt vergebene Nummer, res-id = reservierte ID fuer dieses
(defun csv:id-vergeben (ename naechste-id / id) ;; 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)))) (setq id (cdr (assoc "ID" (ssg-attrib-read ename))))
(if (or (null id) (= id "")) (if (or (null id) (= id ""))
(progn (if (and res-id (> (strlen res-id) 0))
(setq naechste-id (1+ naechste-id)) (ssg-id-set-and-verify ename res-id "reservierte ID")
(ssg-id-set-and-verify ename (ssg-id-format naechste-id) "Kettenfolge"))) (progn
(setq naechste-id (1+ naechste-id))
(ssg-id-set-and-verify ename (ssg-id-format naechste-id) "Kettenfolge"))))
naechste-id naechste-id
) )
@@ -2359,8 +2435,8 @@
;; Ohne diese Vergabe nummeriert erst ssg-id-check-all - in der Reihenfolge ;; Ohne diese Vergabe nummeriert erst ssg-id-check-all - in der Reihenfolge
;; von (ssget "X"), in BricsCAD also rueckwaerts (zuletzt erzeugt zuerst). ;; von (ssget "X"), in BricsCAD also rueckwaerts (zuletzt erzeugt zuerst).
;; Die Export-CSV ist nach TeileId sortiert, damit stehen die Zeilen jeder ;; Die Export-CSV ist nach TeileId sortiert, damit stehen die Zeilen jeder
;; Kette jetzt von AS nach ES. Bereits vorhandene IDs (dauerhafte AS/ES- ;; Kette jetzt von AS nach ES. Bereits vorhandene IDs (AS/ES-Marker mit
;; Marker) bleiben unangetastet. ;; reservierter ID vom Wrapper) bleiben unangetastet.
;; sep-proxies/element-proxies/asmarks = die Stellvertreter-Listen dieses ;; sep-proxies/element-proxies/asmarks = die Stellvertreter-Listen dieses
;; Laufs (letztes Feld jedes Records = verpackter Baustein). ;; Laufs (letztes Feld jedes Records = verpackter Baustein).
;; Rueckgabe: Einheiten-Proxy-Records (proxy-ename wrapper-ename typ lfdnr) - ;; Rueckgabe: Einheiten-Proxy-Records (proxy-ename wrapper-ename typ lfdnr) -
@@ -2368,7 +2444,7 @@
(defun csv:ketten-verarbeiten (sep-proxies element-proxies asmarks (defun csv:ketten-verarbeiten (sep-proxies element-proxies asmarks
/ alt gruppiert blockname ms traeger r naechste-id / alt gruppiert blockname ms traeger r naechste-id
wrapper teile einheit lfdnr mark starts 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 alt (csv:unitmark-bestand-loeschen))
(setq gruppiert (= *csv-export-modus* "group_vf_gf")) (setq gruppiert (= *csv-export-modus* "group_vf_gf"))
(if gruppiert (setq blockname (csv:unitmark-blockdef-sicherstellen))) (if gruppiert (setq blockname (csv:unitmark-blockdef-sicherstellen)))
@@ -2384,7 +2460,8 @@
(foreach wrapper (csv:wrapper-nach-id) (foreach wrapper (csv:wrapper-nach-id)
(setq teile (csv:kette-ordnen (csv:kette-teile wrapper) (setq teile (csv:kette-ordnen (csv:kette-teile wrapper)
(cdr (assoc 2 (entget 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) (setq starts nil lfdnr 0)
(if (and gruppiert blockname) (if (and gruppiert blockname)
(foreach einheit (csv:kette-einheiten (mapcar 'car teile)) (foreach einheit (csv:kette-einheiten (mapcar 'car teile))
@@ -2394,14 +2471,26 @@
(if mark (if mark
(progn (progn
(setq ergebnis (cons (list mark wrapper (car einheit) lfdnr) ergebnis)) (setq ergebnis (cons (list mark wrapper (car einheit) lfdnr) ergebnis))
(setq starts (cons (cons (car (cadr einheit)) mark) starts)))))) (setq starts (cons (list (car (cadr einheit)) (csv:res-key-einheit lfdnr) mark)
;; IDs entlang der Kette 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) (setq i 0)
(foreach teil teile (foreach teil teile
(foreach u starts (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))) (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))) (setq i (1+ i)))
) )
(if gruppiert (if gruppiert
@@ -2551,21 +2640,22 @@
;; den Zeichnungszustand herrichten - Separator-Proxies einpacken, IDs ;; den Zeichnungszustand herrichten - Separator-Proxies einpacken, IDs
;; sicherstellen, Proxy-Zuordnung setzen, Omniflo-Attribute (HOEHE/DREHUNG) ;; sicherstellen, Proxy-Zuordnung setzen, Omniflo-Attribute (HOEHE/DREHUNG)
;; aktualisieren, Separator-/Scanner-Zuordnung pruefen, global regenerieren und ;; aktualisieren, Separator-/Scanner-Zuordnung pruefen, global regenerieren und
;; die bbox-Fehlerdiagnose zuruecksetzen. Rueckgabe: die Liste ALLER erzeugten ;; die bbox-Fehlerdiagnose zuruecksetzen. Rueckgabe: (sep-proxies
;; Kopien - Separatoren UND AS/ES-Schleuselemente (der Aufrufer entfernt sie am ;; element-proxies unitmarks asmarks) - alle temporaer, der Aufrufer entfernt
;; Ende wieder). label dient nur den Meldungen. ;; sie am Ende wieder. label dient nur den Meldungen.
(defun csv:export-vorbereiten (label / sep-proxies asmarks element-proxies unitmarks) (defun csv:export-vorbereiten (label / sep-proxies asmarks element-proxies unitmarks)
;; Baustein-Geometrie der Stellvertreter (Separator-Kopie, AS-/ES-Marker) ;; Baustein-Geometrie der Stellvertreter (Separator-Kopie, AS-/ES-Marker)
;; wird beim Erzeugen neu gemerkt - Stand eines frueheren Laufs verwerfen. ;; wird beim Erzeugen neu gemerkt - Stand eines frueheren Laufs verwerfen.
(setq *csv-baustein-by-handle* nil) (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 ;; Verpackte Separator_SP-Symbole (siehe csv:sep-proxies-erzeugen) VOR der
;; ID-Vergabe durch temporaere, echte Kopien ersetzen - sie werden am Ende ;; ID-Vergabe durch temporaere, echte Kopien ersetzen - sie werden am Ende
;; von csv:run-export wieder entfernt (csv:sep-proxies-loeschen). ;; von csv:run-export wieder entfernt (csv:sep-proxies-loeschen).
(setq sep-proxies (csv:sep-proxies-erzeugen)) (setq sep-proxies (csv:sep-proxies-erzeugen))
;; Die AS-/ES-Kettenenden stecken ebenfalls verpackt im Wrapper, bekommen ;; Die AS-/ES-Kettenenden stecken ebenfalls verpackt im Wrapper und
;; aber KEINE temporaere Kopie, sondern einen DAUERHAFTEN Marker ;; bekommen einen temporaeren Marker (ZZ_ASES_MARKER); ihre ID bleibt als
;; (ZZ_ASES_MARKER): er macht das Kettenende in der Zeichnung sichtbar und ;; reservierte ID am Wrapper ueber Exportlaeufe hinweg (siehe csv:asmark-*).
;; traegt dessen ID ueber Exportlaeufe hinweg (siehe csv:asmark-*).
(setq asmarks (csv:asmark-aktualisieren)) (setq asmarks (csv:asmark-aktualisieren))
;; Die uebrigen Kettenbausteine (Boegen, gerade Foerderer-/Gefaellestrecken- ;; Die uebrigen Kettenbausteine (Boegen, gerade Foerderer-/Gefaellestrecken-
;; Segmente, Umlenk-/Motorstation) als temporaere Kopien - NUR im Modus ;; Segmente, Umlenk-/Motorstation) als temporaere Kopien - NUR im Modus
@@ -2602,6 +2692,9 @@
(csv:asmark-ids-setzen asmarks) (csv:asmark-ids-setzen asmarks)
(csv:sepliste-ids-setzen sep-proxies) (csv:sepliste-ids-setzen sep-proxies)
(csv:unitmark-ids-setzen unitmarks) (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 ;; Vor dem Export HOEHE/DREHUNG aller Omniflo-Elemente aktualisieren
(princ (ssg-textf "exp-update-hoehe-drehung" (list label))) (princ (ssg-textf "exp-update-hoehe-drehung" (list label)))
(omni:update-all-attribs) (omni:update-all-attribs)
@@ -2637,10 +2730,9 @@
;; bbox-Fehlerdiagnose fuer diesen Lauf zuruecksetzen (siehe csv:get-bbox). ;; bbox-Fehlerdiagnose fuer diesen Lauf zuruecksetzen (siehe csv:get-bbox).
(setq *csv-bbox-fail-count* 0) (setq *csv-bbox-fail-count* 0)
(setq *csv-bbox-fail-first* nil) (setq *csv-bbox-fail-first* nil)
;; Nur die TEMPORAEREN Hilfsmittel zurueckgeben (Separator-/Element-Kopien, ;; Alle temporaeren Hilfsmittel zurueckgeben (Separator-/Element-Kopien,
;; Einheiten-Proxies) - die AS/ES-Marker bleiben bewusst in der Zeichnung ;; Einheiten-Proxies, AS-/ES-Marker) - csv:run-export entfernt sie wieder.
;; stehen und duerfen nicht mitgeloescht werden. (list sep-proxies element-proxies unitmarks asmarks))
(list sep-proxies element-proxies unitmarks))
;; --- Python-Export-Skript aufrufen und Ergebnis auswerten --------------- ;; --- Python-Export-Skript aufrufen und Ergebnis auswerten ---------------
;; Aus csv:run-export ausgelagert: das fertige raw-JSON (out-pfad) an das ;; 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. ;; (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 (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 first-block count out-dir sep-proxies element-proxies
unitmarks vorbereitung-ergebnis) unitmarks asmarks vorbereitung-ergebnis)
;; Zeichnungszustand fuer den Export herrichten (Proxies, IDs, Zuordnung, ;; Zeichnungszustand fuer den Export herrichten (Proxies, IDs, Zuordnung,
;; Attribut-Update, Sep/Scan-Zaehlung, REGENALL, bbox-Reset) - ausgelagert. ;; 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 vorbereitung-ergebnis (csv:export-vorbereiten label))
(setq sep-proxies (nth 0 vorbereitung-ergebnis)) (setq sep-proxies (nth 0 vorbereitung-ergebnis))
(setq element-proxies (nth 1 vorbereitung-ergebnis)) (setq element-proxies (nth 1 vorbereitung-ergebnis))
(setq unitmarks (nth 2 vorbereitung-ergebnis)) (setq unitmarks (nth 2 vorbereitung-ergebnis))
(setq asmarks (nth 3 vorbereitung-ergebnis))
(princ (ssg-textf "exp-collect-blocks" (list label))) (princ (ssg-textf "exp-collect-blocks" (list label)))
(setq ss (csv:collect-export-blocks)) (setq ss (csv:collect-export-blocks))
@@ -2779,11 +2872,12 @@
) )
) )
) )
;; Temporaere Separator-/Element-Kopien wieder entfernen - sie haben ihren ;; Temporaere Separator-/Element-Kopien und AS-/ES-Marker wieder entfernen -
;; Zweck (ID-Vergabe + JSON-Zeile ueber die obigen, unveraenderten ;; sie haben ihren Zweck (ID-Vergabe + JSON-Zeile ueber die obigen,
;; Sammel-Funktionen) erfuellt. Die AS-/ES-Marker (ZZ_ASES_MARKER) bleiben ;; unveraenderten Sammel-Funktionen) erfuellt. Die AS-/ES-IDs bleiben als
;; bewusst stehen (siehe csv:export-vorbereiten). ;; reservierte IDs am Wrapper (csv:asmark-ids-setzen).
(csv:sep-proxies-loeschen sep-proxies) (csv:sep-proxies-loeschen sep-proxies)
(csv:hilfskopien-loeschen asmarks "exp-art-ases")
(csv:hilfskopien-loeschen element-proxies "exp-art-element") (csv:hilfskopien-loeschen element-proxies "exp-art-element")
(csv:hilfskopien-loeschen unitmarks "exp-art-einheit") (csv:hilfskopien-loeschen unitmarks "exp-art-einheit")
(princ) (princ)
+58 -2
View File
@@ -69,8 +69,8 @@
;; ZZ_ASES_MARKER: die Marker der AS-/ES-Kettenenden (siehe ;; ZZ_ASES_MARKER: die Marker der AS-/ES-Kettenenden (siehe
;; csv:asmark-aktualisieren, export.lsp). Sie brauchen eine ID - ;; csv:asmark-aktualisieren, export.lsp). Sie brauchen eine ID -
;; sie vertreten das Kettenende im Export ("sepliste"-Feld "id" ;; sie vertreten das Kettenende im Export ("sepliste"-Feld "id"
;; und eigene JSON-Zeile) und behalten sie ueber Laeufe hinweg, ;; und eigene JSON-Zeile). Der Marker selbst ist temporaer, seine
;; weil der Marker in der Zeichnung stehen bleibt. ;; ID bleibt als reservierte ID am Wrapper (ssg-id-res-*).
(wcmatch bname "ZZ_ASES_MARKER*") (wcmatch bname "ZZ_ASES_MARKER*")
;; ZZ_UNIT_MARKER: die Foerdereinheit-/Gefaelleeinheit-Marker ;; ZZ_UNIT_MARKER: die Foerdereinheit-/Gefaelleeinheit-Marker
;; (siehe csv:ketten-verarbeiten, export.lsp) - temporaere ;; (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 --- ;; --- Hoechste bereits vergebene ID in einem Auswahlsatz ermitteln ---
;; ss = Auswahlsatz (i.d.R. aus ssg-id-collect-blocks) oder nil. ;; ss = Auswahlsatz (i.d.R. aus ssg-id-collect-blocks) oder nil.
;; Rueckgabe: Integer (hoechste ID) oder 0 wenn keine gefunden. ;; 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 ;; Bewusst als eigene Funktion: ssg-id-check-all MUSS diesen Wert ueber den
;; GESAMTEN Auswahlsatz kennen, BEVOR es die erste neue ID vergibt (siehe ;; 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)) (setq i (1+ i))
) )
) )
+41 -17
View File
@@ -55,7 +55,7 @@ Bounding-Boxen braucht).
`(proxy-ename wrapper-ename typ (x y z))`. `(proxy-ename wrapper-ename typ (x y z))`.
1b. **`csv:asmark-aktualisieren`** — die AS-/ES-Enden derselben Kette 1b. **`csv:asmark-aktualisieren`** — die AS-/ES-Enden derselben Kette
(`AS_Element*`/`ES_Element*`, Muster `pattern_schleuselement`) bekommen (`AS_Element*`/`ES_Element*`, Muster `pattern_schleuselement`) bekommen
KEINE temporaere Kopie, sondern einen DAUERHAFTEN Marker — siehe eigener KEINE Kopie des Elements, sondern einen eigenen (ebenfalls temporaeren) Marker — siehe eigener
Abschnitt "Der AS/ES-Marker" unten. Beide Wege teilen sich die Abschnitt "Der AS/ES-Marker" unten. Beide Wege teilen sich die
Platzierungsrechnung (`csv:nested-welt-records` liefert die Weltlage jedes Platzierungsrechnung (`csv:nested-welt-records` liefert die Weltlage jedes
verpackten Fundes, `csv:block-einfuegen-welt` setzt ein Objekt dorthin). verpackten Fundes, `csv:block-einfuegen-welt` setzt ein Objekt dorthin).
@@ -140,6 +140,26 @@ AS/ES-Marker, Einheiten-Proxies) werden vor `ssg-id-check-all` entlang der
Kette von AS nach ES aufsteigend vergeben (`csv:ketten-verarbeiten`) - die Kette von AS nach ES aufsteigend vergeben (`csv:ketten-verarbeiten`) - die
CSV ist nach TeileId sortiert, die Zeilen stehen damit in Kettenfolge. CSV ist nach TeileId sortiert, die Zeilen stehen damit in Kettenfolge.
**Stabile IDs ueber Exportlaeufe.** Alle diese Objekte sind temporaer und
werden nach dem Export geloescht (ausser mit `csv_leave_proxies`). Ihre ID
bleibt trotzdem gleich: nach `ssg-id-check-all` schreibt
`csv:res-ids-schreiben` sie als **reservierte IDs** an den VF_n/GF_n-Wrapper
(XDATA `SSG_ID_RES`, Helfer `ssg-id-res-*` in `Lisp/ssg_id.lsp`), der naechste
Export gibt sie dem neuen Objekt an derselben Stelle zurueck. Schluessel:
| Schluessel | Objekt |
|---|---|
| `AS\|n` / `ES\|n` | AS-/ES-Marker, n = sepliste-`lfdnr` |
| `K\|i` | Separator-/Element-Kopie des i-ten Bausteins der geordneten Kette (0-basiert, `csv:kette-ordnen`) |
| `U\|n` | n-te Foerder-/Gefaelleeinheit des Wrappers (`group_vf_gf`) |
`ssg-id-max-in-ss` zaehlt die reservierten IDs mit, damit sie in der
Zwischenzeit an keinen anderen Block vergeben werden. Nur Objekte OHNE
reservierte ID (erster Export einer Kette, Modus neu gewaehlt) bekommen eine
neue Nummer - oberhalb aller vorhandenen, also nicht mehr zwingend in
Kettenfolge neben den uebrigen Zeilen der Kette. Ein Edit baut einen neuen
Wrapper ohne diese XDATA; dessen Kettenobjekte werden dann neu nummeriert.
Umgesetzt ueber `csv:baustein-merken`: beim Erzeugen des Stellvertreters Umgesetzt ueber `csv:baustein-merken`: beim Erzeugen des Stellvertreters
werden K-Punkte (`csv:ks-welt-punkte`) und bbox (kurzlebige Kopie des werden K-Punkte (`csv:ks-welt-punkte`) und bbox (kurzlebige Kopie des
Bausteins, `csv:baustein-bbox`) unter seinem Handle gemerkt Bausteins, `csv:baustein-bbox`) unter seinem Handle gemerkt
@@ -211,7 +231,7 @@ realen Bauteils, das ihn in der Zeichnung vertritt:
``` ```
Das ist dieselbe ID, die die zugehoerige temporaere Kopie (SEP) bzw. der Das ist dieselbe ID, die die zugehoerige temporaere Kopie (SEP) bzw. der
dauerhafte `ZZ_ASES_MARKER` (AS/ES) in ihrer eigenen JSON-Zeile traegt — die temporaere `ZZ_ASES_MARKER` (AS/ES) in ihrer eigenen JSON-Zeile traegt — die
Verbindung "Kettenglied <-> reales Teil" steht damit schon im Export und muss Verbindung "Kettenglied <-> reales Teil" steht damit schon im Export und muss
in Python nicht mehr ueber Koordinaten-Naehe geraten werden. `map_sepliste_ in Python nicht mehr ueber Koordinaten-Naehe geraten werden. `map_sepliste_
kette_items` (siehe Abschnitt 5 unten) loest genau darueber jeden sepliste- kette_items` (siehe Abschnitt 5 unten) loest genau darueber jeden sepliste-
@@ -226,7 +246,9 @@ Die beiden Kettenenden stecken als `AS_Element_*`/`ES_Element_*` verpackt in
der Wrapper-Blockdefinition: in der Zeichnung sind sie weder anklickbar noch der Wrapper-Blockdefinition: in der Zeichnung sind sie weder anklickbar noch
einzeln erkennbar, und `(ssget "X" ...)` findet sie nicht. `csv:asmark-*` einzeln erkennbar, und `(ssget "X" ...)` findet sie nicht. `csv:asmark-*`
(`Lisp/export.lsp`) setzt darum an jedes Ende ein kleines Rechteck, das nach (`Lisp/export.lsp`) setzt darum an jedes Ende ein kleines Rechteck, das nach
dem Export in der Zeichnung STEHEN BLEIBT: nach dem Export wie alle Hilfskopien wieder GELOESCHT wird (nur der
Debug-Schalter `csv_leave_proxies` bzw. der Haken im Dialog
`CSV_EXPORT_KONFIG` laesst ihn zur Ansicht stehen):
- **Sichtbarmachung** — Kantenlaenge aus `cfg/export.cfg` `[Marker]` - **Sichtbarmachung** — Kantenlaenge aus `cfg/export.cfg` `[Marker]`
`ases_groesse_mm` (Default 200 mm), mittig auf dem Einfuegepunkt des `ases_groesse_mm` (Default 200 mm), mittig auf dem Einfuegepunkt des
@@ -238,20 +260,22 @@ dem Export in der Zeichnung STEHEN BLEIBT:
- **ID-Traeger** — die Attribute (alle unsichtbar) sind - **ID-Traeger** — die Attribute (alle unsichtbar) sind
`ID`, `ZUORDNUNG` (Wrapper-ID), `TYP` (`AS`/`ES`), `LFDNR` (sepliste-Eintrag), `ID`, `ZUORDNUNG` (Wrapper-ID), `TYP` (`AS`/`ES`), `LFDNR` (sepliste-Eintrag),
`ELEMENT` (Blockname des echten Elements, haelt die Variante 30/90, `ELEMENT` (Blockname des echten Elements, haelt die Variante 30/90,
links/rechts, 2D/3D fest) und `ARTINR`. `ssg-id-check-all` fuellt die `ID`, links/rechts, 2D/3D fest) und `ARTINR`. `ssg-id-check-all` fuellt die `ID`.
und weil der Marker liegen bleibt, **behaelt ein AS/ES seine TeileId ueber Danach legt `csv:res-ids-schreiben` die ID als **reservierte ID** am
Exportlaeufe hinweg** — im Unterschied zu den Separator-Kopien, die jeder VF_n/GF_n-Wrapper ab (Eintrag `AS|1=0032`, siehe "Stabile IDs ueber
Lauf neu erzeugt und neu nummeriert. Exportlaeufe" oben). Der naechste Export gibt sie dem neu gesetzten Marker
zurueck, **ein AS/ES behaelt seine TeileId also ueber Exportlaeufe
hinweg**, obwohl der Marker dazwischen nicht existiert.
Der Marker ist abgeleitete Geometrie: jeder Export baut ihn neu auf (die Lage Der Marker ist abgeleitete Geometrie: jeder Export baut ihn neu auf (die Lage
folgt damit automatisch einer umgebauten Kette) und uebernimmt vom bisherigen folgt damit automatisch einer umgebauten Kette) und uebernimmt die ID ueber
Marker nur dessen `ID`. Wiedergefunden wird er ueber (`ZUORDNUNG`, `TYP`, den Schluessel (`TYP`, `LFDNR`) aus der reservierten ID des Wrappers — bewusst
`LFDNR`) — bewusst nicht ueber die Position, damit eine verschobene Kette ihre nicht ueber die Position, damit eine verschobene Kette ihre TeileIds behaelt.
TeileIds behaelt. Was am Ende keinem Kettenende mehr entspricht (Kette Steht noch ein Marker in der Zeichnung (aeltere Zeichnung, in der die Marker
geloescht, Eintrag entfallen), wird geloescht; Karteileichen entstehen nicht. frueher dauerhaft blieben, oder ein Lauf mit `csv_leave_proxies`), wird seine
Ein frisch gebauter Wrapper hat beim Setzen der Marker noch keine ID — seine ID ueber (`ZUORDNUNG`, `TYP`, `LFDNR`) uebernommen, falls der Wrapper noch
Marker bekommen die `ZUORDNUNG` nach der ID-Vergabe nachgetragen und sind ab keine reservierte ID fuehrt; der alte Marker wird dabei geloescht, ebenso
dem naechsten Export wiederfindbar. jeder, der keinem Kettenende mehr entspricht.
Im Export ist der Marker eine eigene Zeile (`pattern_ases_marker` in Im Export ist der Marker eine eigene Zeile (`pattern_ases_marker` in
`cfg/export.cfg`) und liefert die `id` des AS-/ES-Eintrags in der `sepliste`. `cfg/export.cfg`) und liefert die `id` des AS-/ES-Eintrags in der `sepliste`.
@@ -411,7 +435,7 @@ Zu beachten:
in Baureihenfolge, unabhaengig vom Kreisel-Umlauf. in Baureihenfolge, unabhaengig vom Kreisel-Umlauf.
- Die AS/ES-Enden (`0021`=AS, `0024`=ES) sind eigene Zeilen (Zeilentyp - Die AS/ES-Enden (`0021`=AS, `0024`=ES) sind eigene Zeilen (Zeilentyp
"ILS Ausschleuselement"/"ILS Einschleuselement"), direkt aus dem "ILS Ausschleuselement"/"ILS Einschleuselement"), direkt aus dem
dauerhaften `ZZ_ASES_MARKER` klassifiziert — in diesem gekuerzten Beispiel `ZZ_ASES_MARKER` klassifiziert — in diesem gekuerzten Beispiel
nicht einzeln aufgefuehrt, aber ihre TeileIds tauchen in `TrackIds` beider nicht einzeln aufgefuehrt, aber ihre TeileIds tauchen in `TrackIds` beider
Seiten auf. Seiten auf.
- Die Separatoren 3 und 5 (`0012`/`0022`) unterscheiden sich nur durch ihre - Die Separatoren 3 und 5 (`0012`/`0022`) unterscheiden sich nur durch ihre
@@ -499,7 +523,7 @@ Geometrie bereits klassifizierter Items abgeleitet:
AS/ES-Kettenenden werden NICHT mehr synthetisiert (fruehere Version: AS/ES-Kettenenden werden NICHT mehr synthetisiert (fruehere Version:
`compute_strecke_kreisel_schleus`/`build_strecke_schleus_items` suchten den `compute_strecke_kreisel_schleus`/`build_strecke_schleus_items` suchten den
anschliessenden Kreisel per Kollisionstest und erfanden dabei eine eigene, anschliessenden Kreisel per Kollisionstest und erfanden dabei eine eigene,
bei jedem Export neue TeileId). Der dauerhafte `ZZ_ASES_MARKER` bei jedem Export neue TeileId). Der `ZZ_ASES_MARKER`
(Lisp/export.lsp, siehe oben) ist ein echter Block mit echter Geometrie - (Lisp/export.lsp, siehe oben) ist ein echter Block mit echter Geometrie -
`"ILS Ausschleuselement"`/`"ILS Einschleuselement"` sind darum eine ganz `"ILS Ausschleuselement"`/`"ILS Einschleuselement"` sind darum eine ganz
normale Zeile aus Schritt 1 (Klassifikation), TeileId/Position/Boundingbox normale Zeile aus Schritt 1 (Klassifikation), TeileId/Position/Boundingbox
+1
View File
@@ -720,6 +720,7 @@
"exp-art-separator": "Separator-Kopie(n)", "exp-art-separator": "Separator-Kopie(n)",
"exp-art-element": "Element-Kopie(n)", "exp-art-element": "Element-Kopie(n)",
"exp-art-einheit": "Einheiten-Proxy(s)", "exp-art-einheit": "Einheiten-Proxy(s)",
"exp-art-ases": "AS-/ES-Marker",
"exp-update-hoehe-drehung": "\n[%1] Aktualisiere Hoehe/Drehung...", "exp-update-hoehe-drehung": "\n[%1] Aktualisiere Hoehe/Drehung...",
"exp-collect-blocks": "\n[%1] Sammle relevante Bloecke...", "exp-collect-blocks": "\n[%1] Sammle relevante Bloecke...",
"exp-no-blocks-found": "\n[%1] Keine relevanten Bloecke gefunden.", "exp-no-blocks-found": "\n[%1] Keine relevanten Bloecke gefunden.",
+1
View File
@@ -720,6 +720,7 @@
"exp-art-separator": "separator copy(ies)", "exp-art-separator": "separator copy(ies)",
"exp-art-element": "element copy(ies)", "exp-art-element": "element copy(ies)",
"exp-art-einheit": "unit proxy(ies)", "exp-art-einheit": "unit proxy(ies)",
"exp-art-ases": "AS/ES marker(s)",
"exp-update-hoehe-drehung": "\n[%1] Updating height/rotation...", "exp-update-hoehe-drehung": "\n[%1] Updating height/rotation...",
"exp-collect-blocks": "\n[%1] Collecting relevant blocks...", "exp-collect-blocks": "\n[%1] Collecting relevant blocks...",
"exp-no-blocks-found": "\n[%1] No relevant blocks found.", "exp-no-blocks-found": "\n[%1] No relevant blocks found.",
+2 -2
View File
@@ -592,7 +592,7 @@ def map_sepliste_kette_items(items, sep_kette, dbg=None):
besitzenden Strecke (siehe write_separatorliste_merkmale). besitzenden Strecke (siehe write_separatorliste_merkmale).
ERZEUGT KEINE neuen Zeilen: AS/ES liegen bereits als eigene Items vor ERZEUGT KEINE neuen Zeilen: AS/ES liegen bereits als eigene Items vor
(direkt aus dem dauerhaften ZZ_ASES_MARKER klassifiziert, siehe (direkt aus dem ZZ_ASES_MARKER klassifiziert, siehe
process_blocks), SEP als die beim Export ausgepackte temporaere process_blocks), SEP als die beim Export ausgepackte temporaere
Separator_SP-Kopie (csv:sep-proxies-erzeugen, export.lsp). Beide Wege Separator_SP-Kopie (csv:sep-proxies-erzeugen, export.lsp). Beide Wege
wuerden sonst dieselben physischen Bauteile DOPPELT zaehlen. wuerden sonst dieselben physischen Bauteile DOPPELT zaehlen.
@@ -805,7 +805,7 @@ def write_separatorliste_merkmale(items, sep_kette_by_key, dbg=None):
dict-Reihenfolge ist nicht garantiert, die sepliste-Liste dagegen schon. dict-Reihenfolge ist nicht garantiert, die sepliste-Liste dagegen schon.
AS/ES zaehlen HIER mit (anders als beim "Separatorlist"-Merkmal frueher) - AS/ES zaehlen HIER mit (anders als beim "Separatorlist"-Merkmal frueher) -
sie sind eigene Items ("ILS Ausschleuselement"/"ILS Einschleuselement", sie sind eigene Items ("ILS Ausschleuselement"/"ILS Einschleuselement",
direkt aus dem dauerhaften ZZ_ASES_MARKER klassifiziert, siehe direkt aus dem ZZ_ASES_MARKER klassifiziert, siehe
process_blocks), analog zu den AS/ES-Enden, die beim Kreisel bereits ueber process_blocks), analog zu den AS/ES-Enden, die beim Kreisel bereits ueber
compute_kreisel_umlauf in dessen TrackIds auftauchen - ohne sie fehlten compute_kreisel_umlauf in dessen TrackIds auftauchen - ohne sie fehlten
hier die Kettenenden, obwohl sie beim Kreisel schon drin sind. hier die Kettenenden, obwohl sie beim Kreisel schon drin sind.
+4 -4
View File
@@ -89,7 +89,7 @@ SENSOR_TEILEARTEN = {"ILS 2.0 Separator", "ILS 2.0 Scanner"}
# Umlauf-Punkte gefuehrt - so tauchen sie, wenn sie auf einer Kreiselbahn # Umlauf-Punkte gefuehrt - so tauchen sie, wenn sie auf einer Kreiselbahn
# liegen, in dessen "TrackIds"-Spalte auf (Nutzeranforderung: wie # liegen, in dessen "TrackIds"-Spalte auf (Nutzeranforderung: wie
# Separator/AS/ES behandeln). AUSSCHLEUS_TEILEART/EINSCHLEUS_TEILEART (AS/ES- # Separator/AS/ES behandeln). AUSSCHLEUS_TEILEART/EINSCHLEUS_TEILEART (AS/ES-
# Kettenenden, siehe unten): seit sie als dauerhafter ZZ_ASES_MARKER real in # Kettenenden, siehe unten): seit sie als ZZ_ASES_MARKER real in
# der Zeichnung stehen (statt wie frueher nur ueber eine Kreisel<->Strecke- # der Zeichnung stehen (statt wie frueher nur ueber eine Kreisel<->Strecke-
# Kollisionsberechnung synthetisiert zu werden, siehe git-Historie # Kollisionsberechnung synthetisiert zu werden, siehe git-Historie
# compute_strecke_kreisel_schleus), reicht ihre EIGENE Bounding-Box fuer die # compute_strecke_kreisel_schleus), reicht ihre EIGENE Bounding-Box fuer die
@@ -114,7 +114,7 @@ WEICHE_TEILEART = "ILS Weiche"
# TeileArten der Ein-/Ausschleuselemente an den Strecken-Enden (AS/ES) einer # TeileArten der Ein-/Ausschleuselemente an den Strecken-Enden (AS/ES) einer
# Gefaellestrecke/eines Foerderers - siehe process_blocks (export_csv.py): # Gefaellestrecke/eines Foerderers - siehe process_blocks (export_csv.py):
# direkt aus dem dauerhaften ZZ_ASES_MARKER klassifiziert (dessen Attribut # direkt aus dem ZZ_ASES_MARKER klassifiziert (dessen Attribut
# TYP="AS"/"ES" waehlt die TeileArt), keine gesonderte Erzeugung mehr hier. # TYP="AS"/"ES" waehlt die TeileArt), keine gesonderte Erzeugung mehr hier.
AUSSCHLEUS_TEILEART = "ILS Ausschleuselement" AUSSCHLEUS_TEILEART = "ILS Ausschleuselement"
EINSCHLEUS_TEILEART = "ILS Einschleuselement" EINSCHLEUS_TEILEART = "ILS Einschleuselement"
@@ -1173,7 +1173,7 @@ def compute_sep_kette(items, dbg=None):
"nachfolger"}} - vorgaenger/nachfolger sind wieder solche keys, oder None "nachfolger"}} - vorgaenger/nachfolger sind wieder solche keys, oder None
am jeweiligen Kettenende (Verkettung mit dem Kreisel-Umlauf uebernimmt am jeweiligen Kettenende (Verkettung mit dem Kreisel-Umlauf uebernimmt
compute_kreisel_umlauf). "id" ist die TeileId des Bauteils, das diesen compute_kreisel_umlauf). "id" ist die TeileId des Bauteils, das diesen
Eintrag in der Zeichnung vertritt (AS/ES ueber den dauerhaften Eintrag in der Zeichnung vertritt (AS/ES ueber den
ZZ_ASES_MARKER, SEP ueber die beim Export ausgepackte temporaere ZZ_ASES_MARKER, SEP ueber die beim Export ausgepackte temporaere
Separator_SP-Kopie - siehe csv:sepliste-ids-setzen, Lisp/export.lsp) - Separator_SP-Kopie - siehe csv:sepliste-ids-setzen, Lisp/export.lsp) -
leerer String, wenn (noch) keine ID zugewiesen wurde (Altbestand). leerer String, wenn (noch) keine ID zugewiesen wurde (Altbestand).
@@ -1215,7 +1215,7 @@ def compute_kreisel_umlauf(items, tolerance_mm, durchmesser_mm=800.0,
UND die AS/ES-Enden aller andockenden VF_n/GF_n-Ketten (alle zusammen UND die AS/ES-Enden aller andockenden VF_n/GF_n-Ketten (alle zusammen
KREISEL_UMLAUF_TEILEARTEN, einheitlich per BBox-Ueberschneidung einer KREISEL_UMLAUF_TEILEARTEN, einheitlich per BBox-Ueberschneidung einer
Kreiselhaelfte/eines Kreisels zugeordnet - wie compute_sensor_zuordnung; Kreiselhaelfte/eines Kreisels zugeordnet - wie compute_sensor_zuordnung;
ein AS/ES bringt seine eigene Bounding-Box vom dauerhaften ZZ_ASES_MARKER ein AS/ES bringt seine eigene Bounding-Box vom ZZ_ASES_MARKER
mit, seit es als reales Item existiert - keine gesonderte Naeherungslogik mit, seit es als reales Item existiert - keine gesonderte Naeherungslogik
mehr noetig) UND die Kreisel-Kreisel-Weichen (touch_switches, siehe mehr noetig) UND die Kreisel-Kreisel-Weichen (touch_switches, siehe
compute_kreisel_touch_switches) - in eine geschlossene Umlauf-Reihenfolge compute_kreisel_touch_switches) - in eine geschlossene Umlauf-Reihenfolge
+1 -1
View File
@@ -206,7 +206,7 @@ class TestSeplisteNachbarnAufgeloest:
Architektur: SEP-Eintraege liegen bereits als echte (Proxy-)Separator_SP- Architektur: SEP-Eintraege liegen bereits als echte (Proxy-)Separator_SP-
Items vor (der LISP-Export fuegt je verpacktem Symbol eine temporaere Items vor (der LISP-Export fuegt je verpacktem Symbol eine temporaere
Kopie ein), AS-/ES-Eintraege als eigene Items, direkt aus dem dauerhaften Kopie ein), AS-/ES-Eintraege als eigene Items, direkt aus dem
ZZ_ASES_MARKER klassifiziert (siehe export_csv.py process_blocks) - beide ZZ_ASES_MARKER klassifiziert (siehe export_csv.py process_blocks) - beide
tragen bereits ihre TeileId als sepliste-Feld "id". map_sepliste_kette_ tragen bereits ihre TeileId als sepliste-Feld "id". map_sepliste_kette_
items erzeugt daher KEINE neuen Zeilen, sondern ordnet jedem sepliste- items erzeugt daher KEINE neuen Zeilen, sondern ordnet jedem sepliste-
+1 -1
View File
@@ -7,7 +7,7 @@ Laeuft komplett ohne BricsCAD (reine Python-Logik, siehe lib/export_csv.py).
Eine Strecke (VF_n/GF_n) traegt in ihrer "sepliste"-XDATA je AS-/SEP-/ES- Eine Strecke (VF_n/GF_n) traegt in ihrer "sepliste"-XDATA je AS-/SEP-/ES-
Eintrag x/y sowie (seit csv:asmark-ids-setzen/csv:sepliste-ids-setzen, Eintrag x/y sowie (seit csv:asmark-ids-setzen/csv:sepliste-ids-setzen,
Lisp/export.lsp) ein Feld "id" - die TeileId des Bauteils, das diesen Lisp/export.lsp) ein Feld "id" - die TeileId des Bauteils, das diesen
Eintrag in der Zeichnung vertritt (AS/ES ueber den dauerhaften Eintrag in der Zeichnung vertritt (AS/ES ueber den
ZZ_ASES_MARKER, SEP ueber die beim Export ausgepackte temporaere ZZ_ASES_MARKER, SEP ueber die beim Export ausgepackte temporaere
Separator_SP-Kopie). write_separatorliste_merkmale() soll daraus, ueber die Separator_SP-Kopie). write_separatorliste_merkmale() soll daraus, ueber die
bereits von map_sepliste_kette_items per exaktem ID-Abgleich aufgeloesten bereits von map_sepliste_kette_items per exaktem ID-Abgleich aufgeloesten
+30
View File
@@ -247,6 +247,16 @@
(tu-eq "ssg-id-format/42" "0042" (ssg-id-format 42)) (tu-eq "ssg-id-format/42" "0042" (ssg-id-format 42))
(tu-eq "ssg-id-format/1000" "1000" (ssg-id-format 1000)) (tu-eq "ssg-id-format/1000" "1000" (ssg-id-format 1000))
(tu-eq "ssg-id-format/12345" "12345" (ssg-id-format 12345)) (tu-eq "ssg-id-format/12345" "12345" (ssg-id-format 12345))
;; Reservierte IDs (XDATA SSG_ID_RES): Serialisierung + Maximum.
(setq _rp '(("AS|1" . "0032") ("ES|4" . "0107")))
(tu-eq "ssg-id-res->strings" '("AS|1=0032" "ES|4=0107") (ssg-id-res->strings _rp))
(tu-eq "ssg-id-res-parse/rundlauf" _rp (ssg-id-res-parse (ssg-id-res->strings _rp)))
(tu-eq "ssg-id-res-parse/ohne-gleich-ignoriert" '(("AS|1" . "0032"))
(ssg-id-res-parse '("kaputt" "AS|1=0032")))
(tu-eq "ssg-id-res-parse/leerer-wert" '(("AS|1" . "")) (ssg-id-res-parse '("AS|1=")))
(tu-eq "ssg-id-res-max" 107 (ssg-id-res-max _rp))
(tu-eq "ssg-id-res-max/leer" 0 (ssg-id-res-max nil))
) )
@@ -385,6 +395,26 @@
(tu-nil "csv:asmark-finden/ohne-wrapper-id" (csv:asmark-finden _mk "" "AS" "1")) (tu-nil "csv:asmark-finden/ohne-wrapper-id" (csv:asmark-finden _mk "" "AS" "1"))
(tu-nil "csv:asmark-finden/leerer-bestand" (csv:asmark-finden nil "0021" "AS" "1")) (tu-nil "csv:asmark-finden/leerer-bestand" (csv:asmark-finden nil "0021" "AS" "1"))
;; csv:asmark-res-key: Schluessel der reservierten ID am Wrapper - lfdnr als
;; Integer (csv:asmark-aktualisieren) und String muss denselben liefern.
(tu-eq "csv:asmark-res-key/int" "AS|1" (csv:asmark-res-key "AS" 1))
(tu-eq "csv:asmark-res-key/str" "ES|4" (csv:asmark-res-key "ES" "4"))
(tu-eq "csv:res-key-kette" "K|7" (csv:res-key-kette 7))
(tu-eq "csv:res-key-einheit" "U|2" (csv:res-key-einheit 2))
;; csv:res-merken: Anmeldungen je Wrapper zusammenfuehren (ein Eintrag je
;; Wrapper, Reihenfolge der Anmeldung). Symbole statt enames - rein
;; listenbasiert. Globale Sammlung sichern und wiederherstellen.
(setq _rs *csv-res-sammlung* *csv-res-sammlung* nil)
(csv:res-merken 'W1 "AS|1" 'M1)
(csv:res-merken 'W2 "K|0" 'M2)
(csv:res-merken 'W1 "K|3" 'M3)
(tu-eq "csv:res-merken/je-wrapper"
'((W1 ("AS|1" . M1) ("K|3" . M3)) (W2 ("K|0" . M2)))
(vl-sort *csv-res-sammlung* (function (lambda (a b) (< (vl-symbol-name (car a))
(vl-symbol-name (car b)))))))
(setq *csv-res-sammlung* _rs)
;; csv:proxy-typ: Typmarker aus dem Blocknamen (Grundlage der Zuordnung). ;; csv:proxy-typ: Typmarker aus dem Blocknamen (Grundlage der Zuordnung).
(tu-eq "csv:proxy-typ/as" "AS" (csv:proxy-typ "AS_Element_90_links_3D")) (tu-eq "csv:proxy-typ/as" "AS" (csv:proxy-typ "AS_Element_90_links_3D"))
(tu-eq "csv:proxy-typ/es" "ES" (csv:proxy-typ "ES_Element_30_rechts_2D")) (tu-eq "csv:proxy-typ/es" "ES" (csv:proxy-typ "ES_Element_30_rechts_2D"))