export_csv: VF_n/GF_n-Einzelelemente zu Foerdereinheit/Gefaelleeinheit gruppieren
Die Einzelteil-Proxy-Zeilen (Boegen, Streckenelemente, Umlenk-/Motorstation) aus der letzten Session sind fuer den Normalfall zu granular. Standardmaessig (*csv-export-alle-elemente* = nil) fasst csv:unitmark-aktualisieren sie jetzt zu je einer "Foerdereinheit"/"Gefaelleeinheit"-Zeile pro zusammenhaengendem VF-/GF-Abschnitt einer Kette zusammen, mit einem persistenten Rechteck-Marker (ZZ_UNIT_MARKER, analog ZZ_ASES_MARKER) auf der Bounding-Box-Vereinigung aller enthaltenen Elemente. Der bisherige Rohdaten-Export bleibt ueber (csv:export-alle-elemente-an) weiterhin verfuegbar. Einheiten-Grenzen kommen rein export-seitig aus der sepliste (SEP/AS/ES in echter Bau-Reihenfolge) plus dem bereits vorhandenen SSG_SEP_TYP je Separator - eine bauzeitige Markierung in vf_linienzug.lsp/vf_standard.lsp/ vf_etage.lsp waere deutlich invasiver gewesen (3 unabhaengige Baupfade ohne gemeinsamen Einstiegspunkt). csv:sepliste-partition (Lauflaengen-Kodierung ueber die typisierte sepliste) und csv:element-unit-zuordnung (Zuordnung der gesammelten Elemente per Kettenrichtungs-Projektion statt der nachweislich unzuverlaessigen csv:nested-welt-records-Listenreihenfolge) sind reine, dateifrei getestete Funktionen. Korrigiert nebenbei eine falsche Annahme: L_VF_m/L_GF_m zaehlen pro Segment, nicht pro Einheit - die tatsaechliche Einheiten-Anzahl kommt nur aus der sepliste-Typfolge. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
f751a90076
commit
e7643bf181
+768
-36
@@ -50,6 +50,21 @@
|
||||
;; ueberlebt damit jeden Neustart.
|
||||
(setq *export-test-override* nil)
|
||||
|
||||
;; --- Schalter: rohe Einzelteil-Zeilen statt gruppierter Foerdereinheit/
|
||||
;; Gefaelleeinheit-Zeilen exportieren ---
|
||||
;; Default nil = gruppierter Modus (csv:unitmark-aktualisieren fasst Boegen/
|
||||
;; Streckenelemente/Umlenk-/Motorstation zu je einer Zeile pro
|
||||
;; Foerdereinheit/Gefaelleeinheit zusammen, die vier pattern_nested_*-
|
||||
;; Einzelteil-Zeilen bleiben aus dem Export ausgeschlossen). Auf T gesetzt:
|
||||
;; Verhalten wie vor der Gruppierung - jedes Einzelteil bekommt seine eigene
|
||||
;; Export-Zeile (csv:collect-export-blocks laesst die pattern_nested_*-
|
||||
;; Klauseln dann durch). Nur per Lisp-Variable/den beiden Helfern
|
||||
;; umschaltbar, kein Menuepunkt vorgesehen.
|
||||
(if (not (boundp '*csv-export-alle-elemente*)) (setq *csv-export-alle-elemente* nil))
|
||||
(defun csv:export-alle-elemente-p () *csv-export-alle-elemente*)
|
||||
(defun csv:export-alle-elemente-an () (setq *csv-export-alle-elemente* T) (princ))
|
||||
(defun csv:export-alle-elemente-aus () (setq *csv-export-alle-elemente* nil) (princ))
|
||||
|
||||
|
||||
;; --- Feste Datei-/Skriptnamen dieses Moduls (keine Config, direkt im Code) ---
|
||||
(setq *export-filenames*
|
||||
@@ -655,6 +670,20 @@
|
||||
)
|
||||
|
||||
|
||||
;; --- K1/K2 eines ZZ_UNIT_MARKER lesen ---
|
||||
;; Fallback fuer csv:block-to-json (siehe dort): die Werte stehen bereits
|
||||
;; fertig kodiert in den ATTDEFs K1/K2 (siehe csv:unitmark-aktualisieren),
|
||||
;; hier nur noch als K-Liste im Format von csv:get-k-kos-strings verpackt.
|
||||
(defun csv:unitmark-k-kos-strings (ename / attribs k1 k2 result)
|
||||
(setq attribs (ssg-attrib-read ename))
|
||||
(setq k1 (cdr (assoc "K1" attribs)))
|
||||
(setq k2 (cdr (assoc "K2" attribs)))
|
||||
(setq result nil)
|
||||
(if (and k1 (> (strlen k1) 0)) (setq result (cons (cons "K1" k1) result)))
|
||||
(if (and k2 (> (strlen k2) 0)) (setq result (cons (cons "K2" k2) result)))
|
||||
result
|
||||
)
|
||||
|
||||
;; --- Einen INSERT-Block als JSON-Objekt schreiben ---
|
||||
;; include-bbox = T -> zusaetzlich Bounding-Box (Mitte + Ausdehnung) ermitteln
|
||||
;; und als "bbox"-Objekt anhaengen (nur fuer EXPORTCSV, nicht fuer EXPORTSIVAS).
|
||||
@@ -718,6 +747,14 @@
|
||||
(wcmatch (strcase blk-name) "VF_*,GF_*"))
|
||||
(setq k-list (csv:vfgf-k-kos-strings ename pt rotation))
|
||||
)
|
||||
;; ZZ_UNIT_MARKER (Foerdereinheit/Gefaelleeinheit): K1/K2 stehen bereits
|
||||
;; fertig kodiert als eigene ATTDEFs am Marker (csv:unitmark-aktualisieren
|
||||
;; berechnet sie einmal bei der Marker-Erzeugung aus dem ersten/letzten
|
||||
;; zugeordneten Element) - keine erneute KS-Suche noetig.
|
||||
(if (and (null k-list)
|
||||
(wcmatch (strcase blk-name) "ZZ_UNIT_MARKER*"))
|
||||
(setq k-list (csv:unitmark-k-kos-strings ename))
|
||||
)
|
||||
(setq bbox-json "")
|
||||
(if include-bbox
|
||||
(progn
|
||||
@@ -1475,6 +1512,325 @@
|
||||
gesetzt
|
||||
)
|
||||
|
||||
;; ===========================================================================
|
||||
;; Foerdereinheit/Gefaelleeinheit-Gruppierung (ZZ_UNIT_MARKER)
|
||||
;; ===========================================================================
|
||||
;; Fasst die Einzelbausteine einer VF_n/GF_n-Kette (Boegen, Strecken, Umlenk-/
|
||||
;; Motorstation, siehe csv:element-proxies-erzeugen) wieder zu Einheiten
|
||||
;; zusammen: abwechselnd Foerdereinheit (VF) / Gefaelleeinheit (GF), je EINE
|
||||
;; Zeile mit K1 vom ersten, K2 vom letzten enthaltenen Element. Laeuft rein
|
||||
;; export-seitig (kein Bau-Code-Eingriff) - Einheiten-Grenzen kommen aus der
|
||||
;; sepliste (SEP/AS/ES in echter Bau-Reihenfolge, XDATA-lfdnr) plus dem
|
||||
;; bereits vorhandenen SSG_SEP_TYP je Separator (VF/GF), NICHT aus der
|
||||
;; unzuverlaessigen csv:nested-welt-records-Listenreihenfolge (siehe
|
||||
;; Kommentar dort - fuer einen einzelnen Wrapper doppelt umgekehrt) und NICHT
|
||||
;; aus L_VF_m/L_GF_m (die zaehlen pro Segment, nicht pro Einheit - ein VF-
|
||||
;; Einheit kann mehrere L_VF_m-Eintraege haben, GF1/GF2-Rampen einer VF-
|
||||
;; Einheit landen im selben L_GF_m wie eigenstaendige GF-Stuecke, siehe
|
||||
;; vfl-block-erstellen-Kommentar in vf_linienzug.lsp).
|
||||
|
||||
;; --- Sepliste-Eintraege um strecke-typ und verlaessliche Weltposition
|
||||
;; anreichern ---
|
||||
;; sepliste = ((typ lfdnr x y) ...) wie ssg-sepliste-xdata-lesen liefert
|
||||
;; (XDATA-Ebene - deren x/y sind der ROHE Gruppencode-10-Punkt
|
||||
;; des Bau-Primitivs und koennen gespiegelt/verschoben sein,
|
||||
;; siehe die sepliste-x/y-Bereinigung im JSON-Export; hier NICHT
|
||||
;; als Positionsquelle verwendet, nur zur Paarung mit dem echten
|
||||
;; Proxy per csv:sepliste-paare, wie an anderer Stelle bereits
|
||||
;; etabliert).
|
||||
;; sep-proxies-eigene = NUR die sep-proxies-Records (siehe
|
||||
;; csv:sep-proxies-erzeugen) DIESES Wrappers, in
|
||||
;; Erzeugungsreihenfolge.
|
||||
;; asmarks-eigene = NUR die asmark-Records (marker-ename wrapper-ename
|
||||
;; typ lfdnr) DIESES Wrappers, aus csv:asmark-aktualisieren.
|
||||
;; Rueckgabe: ((typ lfdnr strecke-typ welt-pt) ...) in lfdnr-Reihenfolge.
|
||||
;; strecke-typ = nil fuer AS/ES (wird von csv:sepliste-partition vom
|
||||
;; Nachbarn geerbt) bzw. fuer einen SEP-Eintrag ohne gefundenen Partner.
|
||||
;; welt-pt = (x y z) der ECHTEN, verlaesslichen Proxy-/Marker-Position (SEP
|
||||
;; ueber sep-proxies-eigene, AS/ES ueber den asmark-Entity-Einfuegepunkt),
|
||||
;; oder nil, falls kein Partner gefunden wurde.
|
||||
(defun csv:sepliste-mit-strecke-typ (sepliste sep-proxies-eigene asmarks-eigene
|
||||
/ proxies paare paar-by-lfdnr paar erg e
|
||||
strecke-typ welt-pt m)
|
||||
(setq proxies
|
||||
(mapcar (function (lambda (r) (list (nth 2 r) (car (nth 3 r)) (cadr (nth 3 r)))))
|
||||
sep-proxies-eigene))
|
||||
(setq paare (csv:sepliste-paare sepliste proxies))
|
||||
(setq paar-by-lfdnr nil)
|
||||
(foreach paar paare
|
||||
(setq paar-by-lfdnr (cons (cons (nth 0 paar) (nth 1 paar)) paar-by-lfdnr)))
|
||||
(setq erg nil)
|
||||
(foreach e sepliste
|
||||
(setq strecke-typ nil welt-pt nil)
|
||||
(cond
|
||||
((= (nth 0 e) "SEP")
|
||||
(setq paar (assoc (nth 1 e) paar-by-lfdnr))
|
||||
(if paar
|
||||
(progn
|
||||
(setq strecke-typ (nth 4 (nth (cdr paar) sep-proxies-eigene)))
|
||||
(setq welt-pt (nth 3 (nth (cdr paar) sep-proxies-eigene)))
|
||||
)
|
||||
)
|
||||
)
|
||||
((member (nth 0 e) (list "AS" "ES"))
|
||||
(setq m nil)
|
||||
(foreach kand asmarks-eigene
|
||||
(if (and (null m) (= (nth 2 kand) (nth 0 e))
|
||||
(= (nth 3 kand) (itoa (nth 1 e))))
|
||||
(setq m kand)))
|
||||
(if m (setq welt-pt (cdr (assoc 10 (entget (nth 0 m))))))
|
||||
)
|
||||
)
|
||||
(setq erg (cons (list (nth 0 e) (nth 1 e) strecke-typ welt-pt) erg))
|
||||
)
|
||||
(reverse erg)
|
||||
)
|
||||
|
||||
;; --- Ersten SEP-typ in der Liste finden (Vorschau fuer AS) ---
|
||||
;; Eine Kette beginnt immer mit einer Foerdereinheit (AS haengt am ersten
|
||||
;; SEP-Eintrag, falls vorhanden) - Default "VF", falls die Kette gar keinen
|
||||
;; Separator hat (reine Foerdereinheit ohne jeden Zwischenhalt).
|
||||
(defun csv:sepliste-erster-sep-typ (sepliste-typisiert / e)
|
||||
(setq e (car sepliste-typisiert))
|
||||
(cond
|
||||
((null e) "VF")
|
||||
((and (= (nth 0 e) "SEP") (nth 2 e)) (nth 2 e))
|
||||
(t (csv:sepliste-erster-sep-typ (cdr sepliste-typisiert)))
|
||||
)
|
||||
)
|
||||
|
||||
;; --- Sepliste (mit strecke-typ) in Einheiten-Spannen partitionieren ---
|
||||
;; sepliste-typisiert = ((typ lfdnr strecke-typ welt-pt) ...) in lfdnr-
|
||||
;; Reihenfolge (Rueckgabe von csv:sepliste-mit-strecke-typ).
|
||||
;;
|
||||
;; Lauflaengen-Kodierung ueber den EFFEKTIVEN Typ jedes Eintrags, EIN
|
||||
;; Vorwaerts-Durchlauf mit einer einzigen mitgefuehrten Zustandsvariable
|
||||
;; "aktueller-typ" (das strecke-typ des zuletzt gesehenen SEP-Eintrags):
|
||||
;; - AS: effektiver Typ = das strecke-typ des ERSTEN SEP-Eintrags der
|
||||
;; ganzen Kette (Vorschau, csv:sepliste-erster-sep-typ) - eine Kette
|
||||
;; beginnt immer mit einer Foerdereinheit.
|
||||
;; - SEP: effektiver Typ = sein eigenes strecke-typ (faellt es aus - alter
|
||||
;; Bestand ohne Marker -, bleibt der zuletzt bekannte Typ stehen).
|
||||
;; "aktueller-typ" wird auf diesen Wert aktualisiert.
|
||||
;; - ES: effektiver Typ = "aktueller-typ" (der zuletzt gesehene SEP,
|
||||
;; also die Einheit, die gerade offen ist).
|
||||
;; Eine neue Einheit beginnt, sobald sich der effektive Typ gegenueber dem
|
||||
;; Vorgaenger aendert; gleich bleibender Typ (inkl. zwei aufeinanderfolgender
|
||||
;; SEP-Eintraege desselben Typs, die GEMEINSAM eine einzige Einheit
|
||||
;; bracketieren - HundM05-Beispiel: SEP3=GF,SEP4=GF sind EINE Gefaelleeinheit)
|
||||
;; haengt an die offene Einheit an. Kein Sonderfall-Code fuer "erster/zweiter
|
||||
;; SEP dieses Typs" noetig - die Lauflaengen-Regel deckt beides ab.
|
||||
;;
|
||||
;; Rueckgabe: ((einheit-typ (lfdnr ...)) ...) in Kettenreihenfolge.
|
||||
;; Reine Rechenfunktion (keine Zeichnung, keine Datei) - getestet in
|
||||
;; tests/test_unit.lsp.
|
||||
(defun csv:sepliste-partition (sepliste-typisiert / erg e eff aktueller-typ
|
||||
offen-typ offen-lfdnrs)
|
||||
(setq aktueller-typ (csv:sepliste-erster-sep-typ sepliste-typisiert))
|
||||
(setq erg nil offen-typ nil offen-lfdnrs nil)
|
||||
(foreach e sepliste-typisiert
|
||||
(cond
|
||||
((= (nth 0 e) "SEP")
|
||||
(setq aktueller-typ (cond ((nth 2 e)) (aktueller-typ)))
|
||||
(setq eff aktueller-typ))
|
||||
(t (setq eff aktueller-typ))
|
||||
)
|
||||
(if (and offen-typ (/= eff offen-typ))
|
||||
(progn
|
||||
(setq erg (cons (list offen-typ (reverse offen-lfdnrs)) erg))
|
||||
(setq offen-typ nil offen-lfdnrs nil)
|
||||
)
|
||||
)
|
||||
(setq offen-typ eff)
|
||||
(setq offen-lfdnrs (cons (nth 1 e) offen-lfdnrs))
|
||||
)
|
||||
(if offen-typ
|
||||
(setq erg (cons (list offen-typ (reverse offen-lfdnrs)) erg)))
|
||||
(reverse erg)
|
||||
)
|
||||
|
||||
;; --- Weltposition eines sepliste-lfdnr aus der typisierten Liste holen ---
|
||||
(defun csv:sepliste-typisiert-pos (lfdnr sepliste-typisiert / treffer)
|
||||
(setq treffer nil)
|
||||
(foreach e sepliste-typisiert
|
||||
(if (and (null treffer) (= (nth 1 e) lfdnr)) (setq treffer e)))
|
||||
(if treffer (nth 3 treffer))
|
||||
)
|
||||
|
||||
;; --- 2D-Skalarprodukt zweier Vektoren (x y) ---
|
||||
(defun csv:dot2 (a b) (+ (* (car a) (car b)) (* (cadr a) (cadr b))))
|
||||
|
||||
;; --- Elemente den Einheiten-Spannen zuordnen ---
|
||||
;; unit-spans = Rueckgabe von csv:sepliste-partition:
|
||||
;; ((einheit-typ (lfdnr ...)) ...).
|
||||
;; sepliste-typisiert = Rueckgabe von csv:sepliste-mit-strecke-typ (liefert
|
||||
;; die Weltposition jedes Rand-lfdnr).
|
||||
;; element-proxies-eigene = NUR die element-proxies-Records (siehe
|
||||
;; csv:element-proxies-erzeugen) DIESES Wrappers,
|
||||
;; (proxy-ename wrapper-ename teileart-key (x y z)).
|
||||
;;
|
||||
;; Vorgehen: fuer jede Spanne den ERSTEN und LETZTEN Rand-lfdnr in eine
|
||||
;; Weltposition aufloesen (Start-/Endpunkt der Spanne entlang der Kette).
|
||||
;; Kettenrichtung = Einheitsvektor vom allerersten zum allerletzten
|
||||
;; Rand-lfdnr der GESAMTEN sepliste (AS->ES). Jedes Element wird per
|
||||
;; Skalarprodukt auf diese Richtung projiziert (t-Wert) und der Spanne
|
||||
;; zugeordnet, deren [t-start,t-ende]-Intervall am naechsten liegt (bei
|
||||
;; eindeutiger Enthaltung: diese Spanne; sonst die mit dem kleinsten
|
||||
;; Abstand zum naeheren Rand - kein Element bleibt unzugeordnet).
|
||||
;;
|
||||
;; Rueckgabe: Liste parallel zu unit-spans, je Spanne eine Liste
|
||||
;; zugeordneter element-proxies-Records.
|
||||
(defun csv:element-unit-zuordnung (unit-spans sepliste-typisiert
|
||||
element-proxies-eigene / grenzen span
|
||||
lfdnrs start-pos ende-pos richtung
|
||||
erste-pos letzte-pos laenge t-werte
|
||||
erg elem t-elem beste-i beste-abstand i
|
||||
t-start t-ende abstand)
|
||||
;; Kettenrichtung ueber den allerersten/allerletzten Rand-lfdnr der
|
||||
;; gesamten sepliste bestimmen (nicht nur der ersten/letzten Spanne - bei
|
||||
;; einer Kette mit nur einer Spanne sind das dieselben Werte).
|
||||
(setq erste-pos nil letzte-pos nil)
|
||||
(foreach e sepliste-typisiert
|
||||
(if (and (null erste-pos) (nth 3 e)) (setq erste-pos (nth 3 e))))
|
||||
(foreach e (reverse sepliste-typisiert)
|
||||
(if (and (null letzte-pos) (nth 3 e)) (setq letzte-pos (nth 3 e))))
|
||||
(if (or (null erste-pos) (null letzte-pos)
|
||||
(< (distance erste-pos letzte-pos) 1e-6))
|
||||
;; Entartete Kette (kein Rand-Punkt aufloesbar, oder AS=ES-Position) -
|
||||
;; keine sinnvolle Projektion moeglich, jede Spanne bekommt keine
|
||||
;; Elemente zugeordnet (Aufrufer behandelt das wie "keine Elemente").
|
||||
(setq richtung '(1.0 0.0))
|
||||
(progn
|
||||
(setq richtung (list (- (car letzte-pos) (car erste-pos))
|
||||
(- (cadr letzte-pos) (cadr erste-pos))))
|
||||
(setq laenge (sqrt (csv:dot2 richtung richtung)))
|
||||
(if (> laenge 1e-6)
|
||||
(setq richtung (list (/ (car richtung) laenge) (/ (cadr richtung) laenge)))
|
||||
(setq richtung '(1.0 0.0))
|
||||
)
|
||||
)
|
||||
)
|
||||
;; Je Spanne: [t-start, t-ende] aus dem ersten/letzten Rand-lfdnr.
|
||||
(setq grenzen nil)
|
||||
(foreach span unit-spans
|
||||
(setq lfdnrs (cadr span))
|
||||
(setq start-pos (csv:sepliste-typisiert-pos (car lfdnrs) sepliste-typisiert))
|
||||
(setq ende-pos (csv:sepliste-typisiert-pos (last lfdnrs) sepliste-typisiert))
|
||||
(setq t-start
|
||||
(if start-pos
|
||||
(csv:dot2 (list (- (car start-pos) (car erste-pos))
|
||||
(- (cadr start-pos) (cadr erste-pos))) richtung)
|
||||
0.0))
|
||||
(setq t-ende
|
||||
(if ende-pos
|
||||
(csv:dot2 (list (- (car ende-pos) (car erste-pos))
|
||||
(- (cadr ende-pos) (cadr erste-pos))) richtung)
|
||||
0.0))
|
||||
(setq grenzen (cons (list (min t-start t-ende) (max t-start t-ende)) grenzen))
|
||||
)
|
||||
(setq grenzen (reverse grenzen))
|
||||
;; Je Element: t-Wert projizieren, naechstliegende Spanne waehlen. Jeder
|
||||
;; Eintrag wird zunaechst als (t-elem . elem) gefuehrt, damit die Spanne
|
||||
;; am Ende NACH t SORTIERT werden kann - das liefert "erstes"/"letztes"
|
||||
;; Element einer Spanne entlang der Kettenrichtung (fuer K1/K2 der
|
||||
;; Einheiten-Zeile, siehe csv:unitmark-aktualisieren), ohne auf die
|
||||
;; unzuverlaessige csv:nested-welt-records-Reihenfolge angewiesen zu sein.
|
||||
(setq erg nil)
|
||||
(foreach span unit-spans (setq erg (cons nil erg)))
|
||||
(setq erg (reverse erg))
|
||||
(foreach elem element-proxies-eigene
|
||||
(setq t-elem
|
||||
(csv:dot2 (list (- (car (nth 3 elem)) (car erste-pos))
|
||||
(- (cadr (nth 3 elem)) (cadr erste-pos))) richtung))
|
||||
(setq beste-i 0 beste-abstand nil i 0)
|
||||
(foreach g grenzen
|
||||
(setq abstand
|
||||
(cond
|
||||
((and (>= t-elem (car g)) (<= t-elem (cadr g))) 0.0)
|
||||
((< t-elem (car g)) (- (car g) t-elem))
|
||||
(t (- t-elem (cadr g)))
|
||||
))
|
||||
(if (or (null beste-abstand) (< abstand beste-abstand))
|
||||
(progn (setq beste-abstand abstand) (setq beste-i i)))
|
||||
(setq i (1+ i))
|
||||
)
|
||||
(setq erg (csv:liste-setzen erg beste-i (cons (cons t-elem elem) (nth beste-i erg))))
|
||||
)
|
||||
;; Je Spanne nach t sortieren, dann den t-Wert wieder abstreifen.
|
||||
(mapcar
|
||||
(function (lambda (paare)
|
||||
(mapcar 'cdr (vl-sort paare (function (lambda (a b) (< (car a) (car b))))))))
|
||||
erg)
|
||||
)
|
||||
|
||||
;; --- Element einer Liste an Index i ersetzen (0-basiert) ---
|
||||
;; Kleiner Hilfsbaustein, da AutoLISP kein eingebautes "setf (nth i lst)" hat.
|
||||
(defun csv:liste-setzen (lst i wert / j out)
|
||||
(setq out nil j 0)
|
||||
(foreach e lst
|
||||
(setq out (cons (if (= j i) wert e) out))
|
||||
(setq j (1+ j))
|
||||
)
|
||||
(reverse out)
|
||||
)
|
||||
|
||||
;; --- Bounding-Box-Vereinigung mehrerer Entities ---
|
||||
;; Verallgemeinert csv:get-bbox (siehe dort) von einer Entity auf eine Liste:
|
||||
;; min/max ueber alle vla-getboundingbox-Ergebnisse, gleiche Fehler-
|
||||
;; behandlung/Diagnose-Zaehler (*csv-bbox-fail-count*), gleiche Rueckgabeform
|
||||
;; (cx cy cz dx dy dz). Entities, deren Box nicht ermittelt werden kann,
|
||||
;; werden uebersprungen (nicht die ganze Vereinigung verworfen) - eine
|
||||
;; teilweise Union ist besser als gar keine.
|
||||
(defun csv:get-bbox-union (enames / obj res ename minpt maxpt gmin gmax dz min-hoehe)
|
||||
(setq gmin nil gmax nil)
|
||||
(foreach ename enames
|
||||
(setq obj (vlax-ename->vla-object ename))
|
||||
(vl-catch-all-apply 'vla-update (list obj))
|
||||
(setq res
|
||||
(vl-catch-all-apply
|
||||
'(lambda ( / ll ur)
|
||||
(vla-getboundingbox obj 'll 'ur)
|
||||
(list (csv:pt->list ll) (csv:pt->list ur)))))
|
||||
(if (vl-catch-all-error-p res)
|
||||
(progn
|
||||
(setq *csv-bbox-fail-count* (1+ (cond (*csv-bbox-fail-count*) (0))))
|
||||
(if (null *csv-bbox-fail-first*)
|
||||
(setq *csv-bbox-fail-first*
|
||||
(strcat "(" (cond ((cdr (assoc 2 (entget ename)))) ("?")) ") "
|
||||
(vl-catch-all-error-message res))))
|
||||
)
|
||||
(progn
|
||||
(setq minpt (car res))
|
||||
(setq maxpt (cadr res))
|
||||
(setq gmin
|
||||
(if gmin
|
||||
(mapcar 'min gmin minpt)
|
||||
minpt))
|
||||
(setq gmax
|
||||
(if gmax
|
||||
(mapcar 'max gmax maxpt)
|
||||
maxpt))
|
||||
)
|
||||
)
|
||||
)
|
||||
(if (and gmin gmax)
|
||||
(progn
|
||||
(setq dz (- (caddr gmax) (caddr gmin)))
|
||||
(setq min-hoehe (csv:bb-minimum-height-mm))
|
||||
(if (< dz min-hoehe) (setq dz min-hoehe))
|
||||
(list
|
||||
(/ (+ (car gmin) (car gmax)) 2.0)
|
||||
(/ (+ (cadr gmin) (cadr gmax)) 2.0)
|
||||
(/ (+ (caddr gmin) (caddr gmax)) 2.0)
|
||||
(- (car gmax) (car gmin))
|
||||
(- (cadr gmax) (cadr gmin))
|
||||
dz
|
||||
)
|
||||
)
|
||||
nil
|
||||
)
|
||||
)
|
||||
|
||||
;; ===========================================================================
|
||||
;; AS-/ES-Marker (ZZ_ASES_MARKER)
|
||||
;; ===========================================================================
|
||||
@@ -1790,6 +2146,376 @@
|
||||
(princ)
|
||||
)
|
||||
|
||||
;; ===========================================================================
|
||||
;; Foerdereinheit-/Gefaelleeinheit-Marker (ZZ_UNIT_MARKER)
|
||||
;; ===========================================================================
|
||||
;; Ein Rechteck, das der Export je Einheiten-Spanne (siehe
|
||||
;; csv:sepliste-partition/csv:element-unit-zuordnung weiter oben) setzt und
|
||||
;; dort DAUERHAFT stehen bleibt - analog zu ZZ_ASES_MARKER, aber auf die
|
||||
;; Bounding-Box-Vereinigung der enthaltenen Elemente skaliert statt fest
|
||||
;; quadratisch. Persistiert wie ZZ_ASES_MARKER ueber Exportlaeufe hinweg
|
||||
;; (Wiederfinden ueber ZUORDNUNG+TYP+LFDNR), damit die TeileId stabil bleibt.
|
||||
;;
|
||||
;; Nur aktiv, wenn *csv-export-alle-elemente* NICHT gesetzt ist (siehe
|
||||
;; Schalter weiter unten) - im Rohdaten-Modus werden keine neuen Marker
|
||||
;; angelegt, ein Aufraeum-Durchlauf entfernt aber IMMER verwaiste Marker
|
||||
;; (auch im Rohdaten-Modus - sonst blieben bei einem Wechsel gruppiert->roh
|
||||
;; alte Marker als Karteileichen stehen).
|
||||
|
||||
(defun csv:unitmark-blockname () "ZZ_UNIT_MARKER")
|
||||
|
||||
;; Attribut-Schema. Alle ATTDEFs unsichtbar (wie *csv-asmark-attrib-defs*).
|
||||
;; ID - fuellt ssg-id-check-all, ueber Exportlaeufe stabil
|
||||
;; ZUORDNUNG - ID des VF_n/GF_n-Wrappers (Schluessel zum Wiederfinden)
|
||||
;; TYP - "VF" (Foerdereinheit) oder "GF" (Gefaelleeinheit)
|
||||
;; LFDNR - 1-basierte Einheiten-Nummer INNERHALB des Wrappers (NICHT
|
||||
;; der sepliste-lfdnr - eine frische Zaehlung je Einheit)
|
||||
;; LAENGE_m - Summe der LAENGE/A-Attribute aller enthaltenen
|
||||
;; Streckenelement-Mitglieder (Meter, als String)
|
||||
;; ANZAHL_BOEGEN - Anzahl der enthaltenen Mitglieder mit TeileArt "BOGEN"
|
||||
;; K1/K2 - KS_EIN des ERSTEN bzw. KS_AUS des LETZTEN Mitglieds der
|
||||
;; Spanne, bereits als csv:trans-encode-String (wie K1-K4
|
||||
;; ueberall sonst im Export) - NICHT als rtos-Text: rtos
|
||||
;; haengt an DIMZIN/LUPREC/LUNITS und ist fuer persistente
|
||||
;; ATTDEF-Werte ungeeignet (siehe rtos-Hinweis in anderen
|
||||
;; sepliste-Serialisierungen, ssg_ks_insert.lsp). Der
|
||||
;; fertig kodierte String wird unveraendert zurueckgelesen,
|
||||
;; kein Decode/Re-encode-Rundlauf noetig.
|
||||
(setq *csv-unitmark-attrib-defs*
|
||||
'(("ID" "") ("ZUORDNUNG" "") ("TYP" "") ("LFDNR" "")
|
||||
("LAENGE_m" "") ("ANZAHL_BOEGEN" "") ("K1" "") ("K2" ""))
|
||||
)
|
||||
|
||||
;; --- Blockdefinition des Markers bei Bedarf anlegen ---
|
||||
;; 1x1-Einheitsquadrat auf Layer "0" (wie csv:asmark-blockdef-sicherstellen) -
|
||||
;; wird beim Einfuegen ueber sx/sy auf die tatsaechliche Bounding-Box-
|
||||
;; Ausdehnung der Einheit skaliert (csv:block-einfuegen-welt), anders als der
|
||||
;; feste ZZ_ASES_MARKER. Keine eigene DWG (reine Hilfsgeometrie).
|
||||
;; Rueckgabe: Blockname oder nil.
|
||||
(defun csv:unitmark-blockdef-sicherstellen ( / name lastEnt ss e typ)
|
||||
(setq name (csv:unitmark-blockname))
|
||||
(if (tblsearch "BLOCK" name)
|
||||
name
|
||||
(progn
|
||||
(setq lastEnt (entlast))
|
||||
(entmake (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") '(8 . "0")
|
||||
'(100 . "AcDbPolyline") '(90 . 4) '(70 . 1)
|
||||
(cons 10 (list -0.5 -0.5))
|
||||
(cons 10 (list 0.5 -0.5))
|
||||
(cons 10 (list 0.5 0.5))
|
||||
(cons 10 (list -0.5 0.5))))
|
||||
(ssg-attrib-make-defs *csv-unitmark-attrib-defs* 0.05)
|
||||
(setq ss (ssadd))
|
||||
(setq e (if lastEnt (entnext lastEnt) (entnext)))
|
||||
(while e
|
||||
(setq typ (cdr (assoc 0 (entget e))))
|
||||
(if (member typ '("LWPOLYLINE" "ATTDEF")) (ssadd e ss))
|
||||
(setq e (entnext e))
|
||||
)
|
||||
(command "_.-BLOCK" name (list 0.0 0.0 0.0) ss "")
|
||||
(if (tblsearch "BLOCK" name)
|
||||
(progn (princ (ssg-textf "exp-unitmark-blockdef" (list name))) name)
|
||||
(progn (princ (ssg-textf "exp-unitmark-blockdef-fehler" (list name))) nil)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; --- Vorhandene Marker der Zeichnung einsammeln ---
|
||||
;; Rueckgabe: Liste von (ename zuordnung typ lfdnr id), analog
|
||||
;; csv:asmark-sammeln.
|
||||
(defun csv:unitmark-sammeln ( / ss i ename attribs out)
|
||||
(setq ss (ssget "X" (list (cons 0 "INSERT") (cons 2 (csv:unitmark-blockname)))))
|
||||
(if ss
|
||||
(progn
|
||||
(setq i 0)
|
||||
(while (setq ename (ssname ss i))
|
||||
(setq attribs (ssg-attrib-read ename))
|
||||
(setq out
|
||||
(cons (list ename
|
||||
(cond ((cdr (assoc "ZUORDNUNG" attribs))) (""))
|
||||
(cond ((cdr (assoc "TYP" attribs))) (""))
|
||||
(cond ((cdr (assoc "LFDNR" attribs))) (""))
|
||||
(cond ((cdr (assoc "ID" attribs))) ("")))
|
||||
out))
|
||||
(setq i (1+ i))
|
||||
)
|
||||
)
|
||||
)
|
||||
out
|
||||
)
|
||||
|
||||
;; --- Bestehenden Marker ueber (ZUORDNUNG, TYP, LFDNR) wiederfinden ---
|
||||
(defun csv:unitmark-finden (bestand zuordnung typ lfdnr / m treffer)
|
||||
(foreach m bestand
|
||||
(if (and (null treffer)
|
||||
(= (nth 1 m) zuordnung)
|
||||
(= (nth 2 m) typ)
|
||||
(= (nth 3 m) lfdnr))
|
||||
(setq treffer m)
|
||||
)
|
||||
)
|
||||
treffer
|
||||
)
|
||||
|
||||
;; --- Laenge (m) eines Streckenelement-Mitglieds aus seinem LAENGE/A-
|
||||
;; Attribut lesen; 0.0 falls keins vorhanden ---
|
||||
(defun csv:unitmark-elem-laenge-mm (proxy-ename / attribs wert)
|
||||
(setq attribs (ssg-attrib-read proxy-ename))
|
||||
(setq wert (cond ((cdr (assoc "LAENGE" attribs))) ((cdr (assoc "A" attribs))) (nil)))
|
||||
(if wert (atof wert) 0.0)
|
||||
)
|
||||
|
||||
;; --- K1/K2 eines Mitglieds lesen, bereits als csv:trans-encode-String ---
|
||||
;; Dieselbe KS_EIN/KS_AUS-Suche wie csv:get-k-kos-strings (nur EINE Ebene
|
||||
;; tief in der Proxy-Blockdefinition, echte K1-K4 haben Vorrang). ks-ziel =
|
||||
;; "K1" oder "K2" (Ziel-Slot wie dort).
|
||||
;; Rueckgabe: 12-Zeichen Base64-String oder nil, falls das Mitglied kein
|
||||
;; passendes KS traegt (z.B. das nie verwendete Vario_Kurve_*).
|
||||
(defun csv:unitmark-elem-ks (proxy-ename ks-ziel / ed pt rotation extrusion
|
||||
R-world psx psy psz blk-tbl sub-ent sub-ed
|
||||
sub-bname sub-pt sub-extrusion sub-pt-real
|
||||
is-real target treffer)
|
||||
(setq ed (entget proxy-ename))
|
||||
(setq pt (cdr (assoc 10 ed)))
|
||||
(if (null (caddr pt)) (setq pt (list (car pt) (cadr pt) 0.0)))
|
||||
(setq rotation (cond ((cdr (assoc 50 ed))) (0.0)))
|
||||
(setq extrusion (cond ((cdr (assoc 210 ed))) ('(0.0 0.0 1.0))))
|
||||
(setq pt (mat3-mul-vec3 (mat3-ocs-matrix extrusion) pt))
|
||||
(setq R-world (mat3-from-normal-rotation extrusion rotation))
|
||||
(setq psx (cond ((cdr (assoc 41 ed))) (1.0)))
|
||||
(setq psy (cond ((cdr (assoc 42 ed))) (1.0)))
|
||||
(setq psz (cond ((cdr (assoc 43 ed))) (1.0)))
|
||||
(setq blk-tbl (tblsearch "BLOCK" (cdr (assoc 2 ed))))
|
||||
(setq treffer nil)
|
||||
(if blk-tbl
|
||||
(progn
|
||||
(setq sub-ent (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 (strcase (cdr (assoc 2 sub-ed))))
|
||||
(setq is-real (wcmatch sub-bname "K1,K2,K3,K4"))
|
||||
(setq target
|
||||
(cond
|
||||
(is-real sub-bname)
|
||||
((or (= sub-bname "KS_EIN") (= sub-bname "KSYS_EIN")) "K1")
|
||||
((or (= sub-bname "KS_AUS") (= sub-bname "KSYS_AUS")) "K2")
|
||||
(t nil)))
|
||||
(if (and target (= target ks-ziel) (or is-real (null treffer)))
|
||||
(progn
|
||||
(setq sub-pt (cdr (assoc 10 sub-ed)))
|
||||
(if (null (caddr sub-pt))
|
||||
(setq sub-pt (list (car sub-pt) (cadr sub-pt) 0.0)))
|
||||
(setq sub-extrusion (cond ((cdr (assoc 210 sub-ed))) ('(0.0 0.0 1.0))))
|
||||
(setq sub-pt-real (mat3-mul-vec3 (mat3-ocs-matrix sub-extrusion) sub-pt))
|
||||
(setq sub-pt-real (list (* psx (car sub-pt-real))
|
||||
(* psy (cadr sub-pt-real))
|
||||
(* psz (caddr sub-pt-real))))
|
||||
(setq sub-pt-real (csv:local-to-world pt R-world sub-pt-real))
|
||||
(setq treffer
|
||||
(csv:trans-encode (car sub-pt-real) (cadr sub-pt-real) (caddr sub-pt-real)))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(setq sub-ent (entnext sub-ent))
|
||||
)
|
||||
)
|
||||
)
|
||||
treffer
|
||||
)
|
||||
|
||||
;; --- Alle Foerdereinheit-/Gefaelleeinheit-Marker der Zeichnung neu
|
||||
;; aufbauen ---
|
||||
;; Laeuft VOR ssg-id-check-all (csv:export-vorbereiten), analog
|
||||
;; csv:asmark-aktualisieren. sep-proxies/element-proxies/asmarks = die drei
|
||||
;; bereits erzeugten Proxy-/Marker-Listen dieses Exportlaufs.
|
||||
;;
|
||||
;; Ist *csv-export-alle-elemente* gesetzt (Rohdaten-Modus): KEINE neuen
|
||||
;; Marker anlegen, nur den kompletten vorhandenen Bestand aufraeumen (sonst
|
||||
;; blieben bei einem Wechsel gruppiert->roh alte Marker als Karteileichen
|
||||
;; stehen).
|
||||
;;
|
||||
;; Rueckgabe: Liste von Records (marker-ename wrapper-ename typ lfdnr) fuer
|
||||
;; csv:unitmark-ids-setzen.
|
||||
(defun csv:unitmark-aktualisieren (sep-proxies element-proxies asmarks
|
||||
/ blockname bestand ms wrapper-enames
|
||||
rec wrapper ed bname wrapper-id app
|
||||
sepliste sepliste-typisiert sep-eigene
|
||||
elem-eigene asmarks-eigene unit-spans
|
||||
zuordnungen span span-i typ lfdnrs
|
||||
zugeordnet alt alt-id mark bbox-enames
|
||||
bbox laenge-mm anzahl-boegen elem
|
||||
lfdnr-erstes lfdnr-letztes k1 k2
|
||||
ergebnis neu uebernommen verwaist)
|
||||
(setq neu 0 uebernommen 0 verwaist 0)
|
||||
(setq bestand (csv:unitmark-sammeln))
|
||||
(if (not (csv:export-alle-elemente-p))
|
||||
(progn
|
||||
(setq blockname (csv:unitmark-blockdef-sicherstellen))
|
||||
(if blockname
|
||||
(progn
|
||||
(setq ms (vla-get-ModelSpace (vla-get-ActiveDocument (vlax-get-acad-object))))
|
||||
;; Wrapper einsammeln (jeder nur einmal) - Vereinigung ueber alle
|
||||
;; drei Proxy-Listen, damit auch ein Wrapper OHNE Boegen/Strecken
|
||||
;; (nur AS-Separator-ES, reine Einzel-Foerdereinheit) erfasst wird.
|
||||
(setq wrapper-enames nil)
|
||||
(foreach rec sep-proxies
|
||||
(if (not (member (nth 1 rec) wrapper-enames))
|
||||
(setq wrapper-enames (cons (nth 1 rec) wrapper-enames))))
|
||||
(foreach rec element-proxies
|
||||
(if (not (member (nth 1 rec) wrapper-enames))
|
||||
(setq wrapper-enames (cons (nth 1 rec) wrapper-enames))))
|
||||
(foreach rec asmarks
|
||||
(if (not (member (nth 1 rec) wrapper-enames))
|
||||
(setq wrapper-enames (cons (nth 1 rec) wrapper-enames))))
|
||||
(foreach wrapper (reverse wrapper-enames)
|
||||
(setq ed (entget wrapper))
|
||||
(setq bname (cdr (assoc 2 ed)))
|
||||
(setq wrapper-id (cond ((cdr (assoc "ID" (ssg-attrib-read wrapper)))) ("")))
|
||||
(setq app
|
||||
(cond
|
||||
((wcmatch (strcase bname) "VF_*") "SSG_VF_SEP")
|
||||
((wcmatch (strcase bname) "GF_*") "SSG_GF_SEP")
|
||||
(t nil)))
|
||||
(setq sepliste
|
||||
(if (and app (car (atoms-family 1 '("SSG-SEPLISTE-XDATA-LESEN"))))
|
||||
(ssg-sepliste-xdata-lesen wrapper app)))
|
||||
(if sepliste
|
||||
(progn
|
||||
(setq sep-eigene nil)
|
||||
(foreach rec sep-proxies
|
||||
(if (eq (nth 1 rec) wrapper) (setq sep-eigene (cons rec sep-eigene))))
|
||||
(setq sep-eigene (reverse sep-eigene))
|
||||
(setq elem-eigene nil)
|
||||
(foreach rec element-proxies
|
||||
(if (eq (nth 1 rec) wrapper) (setq elem-eigene (cons rec elem-eigene))))
|
||||
(setq elem-eigene (reverse elem-eigene))
|
||||
(setq asmarks-eigene nil)
|
||||
(foreach rec asmarks
|
||||
(if (eq (nth 1 rec) wrapper) (setq asmarks-eigene (cons rec asmarks-eigene))))
|
||||
(setq asmarks-eigene (reverse asmarks-eigene))
|
||||
|
||||
(setq sepliste-typisiert
|
||||
(csv:sepliste-mit-strecke-typ sepliste sep-eigene asmarks-eigene))
|
||||
(setq unit-spans (csv:sepliste-partition sepliste-typisiert))
|
||||
(setq zuordnungen
|
||||
(csv:element-unit-zuordnung unit-spans sepliste-typisiert elem-eigene))
|
||||
|
||||
(setq span-i 0)
|
||||
(foreach span unit-spans
|
||||
(setq typ (car span))
|
||||
(setq lfdnrs (cadr span))
|
||||
;; zugeordnet ist bereits NACH KETTENRICHTUNG SORTIERT
|
||||
;; (csv:element-unit-zuordnung) - das erste Element liefert
|
||||
;; K1, das letzte K2.
|
||||
(setq zugeordnet (nth span-i zuordnungen))
|
||||
|
||||
;; Bounding-Box-Vereinigung ueber alle zugeordneten
|
||||
;; Element-Proxies. Ist eine Spanne leer (z.B. eine ganz
|
||||
;; kurze Gefaelleeinheit ohne eigenes Bogen-/Strecken-
|
||||
;; Element zwischen zwei direkt benachbarten Separatoren),
|
||||
;; entsteht fuer sie kein Marker - eine Einheit ohne jedes
|
||||
;; zugeordnete Bauteil hat keine sinnvolle Geometrie.
|
||||
(setq bbox-enames nil)
|
||||
(foreach elem zugeordnet (setq bbox-enames (cons (nth 0 elem) bbox-enames)))
|
||||
(setq bbox (if bbox-enames (csv:get-bbox-union bbox-enames)))
|
||||
|
||||
(if bbox
|
||||
(progn
|
||||
;; Laenge/Anzahl Boegen aus den zugeordneten Elementen.
|
||||
(setq laenge-mm 0.0 anzahl-boegen 0)
|
||||
(foreach elem zugeordnet
|
||||
(if (= (nth 2 elem) "STRECKENELEMENT")
|
||||
(setq laenge-mm (+ laenge-mm (csv:unitmark-elem-laenge-mm (nth 0 elem)))))
|
||||
(if (= (nth 2 elem) "BOGEN")
|
||||
(setq anzahl-boegen (1+ anzahl-boegen)))
|
||||
)
|
||||
;; K1/K2: eigenes KS_EIN des ERSTEN, KS_AUS des
|
||||
;; LETZTEN zugeordneten Elements (Kettenrichtungs-
|
||||
;; Sortierung, siehe oben) - fehlt bei einem Element
|
||||
;; das passende KS (z.B. das nie verwendete
|
||||
;; Vario_Kurve_*), bleibt K1/K2 leer, kein Abbruch.
|
||||
(setq k1 (csv:unitmark-elem-ks (nth 0 (car zugeordnet)) "K1"))
|
||||
(setq k2 (csv:unitmark-elem-ks (nth 0 (last zugeordnet)) "K2"))
|
||||
|
||||
(setq mark
|
||||
(csv:block-einfuegen-welt ms blockname
|
||||
(list (nth 0 bbox) (nth 1 bbox) (nth 2 bbox))
|
||||
(mat3-rz 0.0)
|
||||
(max (nth 3 bbox) 1.0) (max (nth 4 bbox) 1.0) 1.0
|
||||
bname))
|
||||
(if mark
|
||||
(progn
|
||||
(setq alt (csv:unitmark-finden bestand wrapper-id typ (itoa (1+ span-i))))
|
||||
(setq alt-id "")
|
||||
(if alt
|
||||
(progn
|
||||
(setq alt-id (nth 4 alt))
|
||||
(entdel (nth 0 alt))
|
||||
(setq bestand (vl-remove alt bestand))
|
||||
(setq uebernommen (1+ uebernommen))
|
||||
)
|
||||
(setq neu (1+ neu))
|
||||
)
|
||||
(ssg-attrib-set-on mark
|
||||
(list (cons "ID" alt-id)
|
||||
(cons "ZUORDNUNG" wrapper-id)
|
||||
(cons "TYP" typ)
|
||||
(cons "LFDNR" (itoa (1+ span-i)))
|
||||
(cons "LAENGE_m" (rtos (/ laenge-mm 1000.0) 2 3))
|
||||
(cons "ANZAHL_BOEGEN" (itoa anzahl-boegen))
|
||||
(cons "K1" (cond (k1) ("")))
|
||||
(cons "K2" (cond (k2) ("")))
|
||||
))
|
||||
(ssg-layer-setzen mark "ases_marker")
|
||||
(setq ergebnis (cons (list mark wrapper typ (1+ span-i)) ergebnis))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(setq span-i (1+ span-i))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
;; Rest des Bestands (auch im Rohdaten-Modus, wo bestand nie durch obige
|
||||
;; Schleife verkleinert wurde): keine Kette/Einheit mehr dahinter.
|
||||
(foreach m bestand
|
||||
(entdel (nth 0 m))
|
||||
(setq verwaist (1+ verwaist))
|
||||
)
|
||||
(if (or (> neu 0) (> uebernommen 0) (> verwaist 0))
|
||||
(princ (ssg-textf "exp-unitmark-bilanz"
|
||||
(list (itoa neu) (itoa uebernommen) (itoa verwaist)))))
|
||||
(reverse ergebnis)
|
||||
)
|
||||
|
||||
;; --- Nach der ID-Vergabe: ZUORDNUNG bereits gesetzt (anders als bei
|
||||
;; ZZ_ASES_MARKER, siehe csv:unitmark-aktualisieren) - hier bleibt nur die
|
||||
;; Bilanz-Meldung uebrig. Kein sepliste-Bezug (Einheiten sind nicht Teil der
|
||||
;; sepliste selbst). ---
|
||||
(defun csv:unitmark-ids-setzen (marker-liste / rec mark id gesetzt ohne-id)
|
||||
(setq gesetzt 0 ohne-id 0)
|
||||
(foreach rec marker-liste
|
||||
(setq mark (nth 0 rec))
|
||||
(setq id (cdr (assoc "ID" (ssg-attrib-read mark))))
|
||||
(if (and id (> (strlen id) 0))
|
||||
(setq gesetzt (1+ gesetzt))
|
||||
(setq ohne-id (1+ ohne-id))
|
||||
)
|
||||
)
|
||||
(if (> gesetzt 0)
|
||||
(princ (ssg-textf "exp-unitmark-ids" (list (itoa gesetzt)))))
|
||||
gesetzt
|
||||
)
|
||||
|
||||
|
||||
;; --- Relevante Bloecke sammeln ---
|
||||
;; Filtert INSERT-Entities auf exportierbare Bloecke:
|
||||
@@ -1828,7 +2554,7 @@
|
||||
;; Element mitgezaehlt - export_csv.py UND export_sivas.py fuehren sie
|
||||
;; beide als eigene TeileArt-Zeilen.
|
||||
;; Gibt Auswahlsatz zurueck oder nil.
|
||||
(defun csv:collect-export-blocks ( / ss-all ss-out i ename ed bname)
|
||||
(defun csv:collect-export-blocks ( / ss-all ss-out i ename ed bname ist-nested-element)
|
||||
(setq ss-all (ssget "X" (list (cons 0 "INSERT"))))
|
||||
(if (null ss-all) (setq ss-out nil)
|
||||
(progn
|
||||
@@ -1837,40 +2563,40 @@
|
||||
(while (setq ename (ssname ss-all i))
|
||||
(setq ed (entget ename))
|
||||
(setq bname (cdr (assoc 2 ed)))
|
||||
(if (or
|
||||
(wcmatch bname (export:pattern "pattern_kreisel" "KR_*,KREISEL_*,ECKRAD_*"))
|
||||
(wcmatch (strcase bname) (export:pattern "pattern_gerade" "AP110*,AP_110*"))
|
||||
(wcmatch bname (export:pattern "pattern_strecke"
|
||||
"Vario*,Staustrecke*,AUS_Element*,EIN_Element*,VF_*,GF_*"))
|
||||
(wcmatch bname (export:pattern "pattern_ases_marker" "ZZ_ASES_MARKER*"))
|
||||
(wcmatch bname (export:pattern "pattern_separator" "Separator_SP*,S-LP*"))
|
||||
(wcmatch bname (export:pattern "pattern_scanner" "Scanner*"))
|
||||
(wcmatch bname (export:pattern "pattern_btmt_beladung" "BTMT-Beladung*"))
|
||||
(wcmatch bname (export:pattern "pattern_btmt_entladung" "SC_Entladung*"))
|
||||
(wcmatch bname (export:pattern "pattern_eingang" "Eingang*"))
|
||||
(wcmatch bname (export:pattern "pattern_ausgang" "Ausgang*"))
|
||||
(wcmatch bname (export:pattern "pattern_geruest" "GR_*"))
|
||||
;; Uebrige verpackte VF_n/GF_n-Bausteine (Boegen, gerade
|
||||
;; Foerderer-/Gefaellestrecken-Segmente, Umlenk-/Motorstation) -
|
||||
;; siehe csv:element-proxies-erzeugen. pattern_strecke oben
|
||||
;; wuerde die meisten davon schon per Praefix (Vario*/
|
||||
;; Staustrecke*) miterfassen, NUR Gefaellebogen_* nicht - die
|
||||
;; vier expliziten Klauseln schliessen diese Luecke und machen
|
||||
;; die Zugehoerigkeit klar. Kein Duplikate-Risiko: eine ssadd-
|
||||
;; Selektion kann dieselbe Entity nicht zweimal enthalten, egal
|
||||
;; wie viele Klauseln hier matchen.
|
||||
(wcmatch bname (export:pattern "pattern_nested_bogen"
|
||||
"Gefaellebogen_*,Vario_Bogen_*,Vario_Kurve_*"))
|
||||
(wcmatch bname (export:pattern "pattern_nested_streckenelement"
|
||||
"Staustrecke_SP_1000_mm*"))
|
||||
(wcmatch bname (export:pattern "pattern_nested_umlenkstation" "Vario_Umlenkstation_*"))
|
||||
(wcmatch bname (export:pattern "pattern_nested_motorstation" "Vario_Motorstation_*"))
|
||||
;; Rein numerische Namen = Omniflo SivasNr (Boegen/Weichen)
|
||||
;; Rein LISP-intern (Python klassifiziert Omniflo stattdessen
|
||||
;; ueber exakten Katalog-Match), daher fest im Code statt in
|
||||
;; cfg/export.cfg.
|
||||
(wcmatch bname "#*")
|
||||
)
|
||||
;; Uebrige verpackte VF_n/GF_n-Bausteine (Boegen, gerade Foerderer-/
|
||||
;; Gefaellestrecken-Segmente, Umlenk-/Motorstation, siehe
|
||||
;; csv:pattern-nested-element/csv:element-proxies-erzeugen): NUR im
|
||||
;; Rohdaten-Modus (*csv-export-alle-elemente* = T) als eigene Export-
|
||||
;; Zeile gesammelt. Im Default (gruppierter Modus, nil) fasst
|
||||
;; csv:unitmark-aktualisieren sie zu Foerdereinheit-/Gefaelleeinheit-
|
||||
;; Zeilen zusammen (pattern_unit_marker unten) - die Proxy-Kopien
|
||||
;; selbst werden dann trotz Treffer auf pattern_strecke (Vario*/
|
||||
;; Staustrecke* per Praefix) explizit AUSGESCHLOSSEN, damit sie nicht
|
||||
;; doppelt (einzeln UND als Teil der Einheiten-Zeile) erscheinen.
|
||||
(setq ist-nested-element
|
||||
(and (not (csv:export-alle-elemente-p))
|
||||
(wcmatch bname (csv:pattern-nested-element))))
|
||||
(if (and (not ist-nested-element)
|
||||
(or
|
||||
(wcmatch bname (export:pattern "pattern_kreisel" "KR_*,KREISEL_*,ECKRAD_*"))
|
||||
(wcmatch (strcase bname) (export:pattern "pattern_gerade" "AP110*,AP_110*"))
|
||||
(wcmatch bname (export:pattern "pattern_strecke"
|
||||
"Vario*,Staustrecke*,AUS_Element*,EIN_Element*,VF_*,GF_*"))
|
||||
(wcmatch bname (export:pattern "pattern_ases_marker" "ZZ_ASES_MARKER*"))
|
||||
(wcmatch bname (export:pattern "pattern_separator" "Separator_SP*,S-LP*"))
|
||||
(wcmatch bname (export:pattern "pattern_scanner" "Scanner*"))
|
||||
(wcmatch bname (export:pattern "pattern_btmt_beladung" "BTMT-Beladung*"))
|
||||
(wcmatch bname (export:pattern "pattern_btmt_entladung" "SC_Entladung*"))
|
||||
(wcmatch bname (export:pattern "pattern_eingang" "Eingang*"))
|
||||
(wcmatch bname (export:pattern "pattern_ausgang" "Ausgang*"))
|
||||
(wcmatch bname (export:pattern "pattern_geruest" "GR_*"))
|
||||
(wcmatch bname (export:pattern "pattern_unit_marker" "ZZ_UNIT_MARKER*"))
|
||||
;; Rein numerische Namen = Omniflo SivasNr (Boegen/Weichen)
|
||||
;; Rein LISP-intern (Python klassifiziert Omniflo stattdessen
|
||||
;; ueber exakten Katalog-Match), daher fest im Code statt in
|
||||
;; cfg/export.cfg.
|
||||
(wcmatch bname "#*")
|
||||
))
|
||||
(ssadd ename ss-out)
|
||||
)
|
||||
(setq i (1+ i))
|
||||
@@ -1918,7 +2644,7 @@
|
||||
;; 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.
|
||||
(defun csv:export-vorbereiten (label / sep-proxies asmarks element-proxies)
|
||||
(defun csv:export-vorbereiten (label / sep-proxies asmarks element-proxies unitmarks)
|
||||
;; 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).
|
||||
@@ -1935,6 +2661,11 @@
|
||||
;; dessen Lauf mit nummeriert werden (siehe ssg-id-collect-blocks,
|
||||
;; ssg_id.lsp).
|
||||
(setq element-proxies (csv:element-proxies-erzeugen))
|
||||
;; Foerdereinheit-/Gefaelleeinheit-Marker (ZZ_UNIT_MARKER) aus den drei
|
||||
;; obigen Proxy-/Marker-Listen bauen - MUSS nach ihnen (braucht ihre
|
||||
;; Weltpositionen) und VOR ssg-id-check-all stehen (frische Marker werden
|
||||
;; dort mit nummeriert), siehe csv:unitmark-aktualisieren.
|
||||
(setq unitmarks (csv:unitmark-aktualisieren sep-proxies element-proxies asmarks))
|
||||
;; Vor dem Export: IDs aller Bloecke sicherstellen und Duplikate korrigieren.
|
||||
;; Erst hier - also erst nachdem ALLE Kopien aus allen Wrapper-Bloecken
|
||||
;; stehen - wird ueberhaupt eine ID vergeben. ssg-id-check-all ermittelt
|
||||
@@ -1956,6 +2687,7 @@
|
||||
(setq *csv-sepliste-id-by-handle* nil)
|
||||
(csv:asmark-ids-setzen asmarks)
|
||||
(csv:sepliste-ids-setzen sep-proxies)
|
||||
(csv:unitmark-ids-setzen unitmarks)
|
||||
;; Vor dem Export HOEHE/DREHUNG aller Omniflo-Elemente aktualisieren
|
||||
(princ (ssg-textf "exp-update-hoehe-drehung" (list label)))
|
||||
(omni:update-all-attribs)
|
||||
|
||||
@@ -72,6 +72,10 @@
|
||||
;; und eigene JSON-Zeile) und behalten sie ueber Laeufe hinweg,
|
||||
;; weil der Marker in der Zeichnung stehen bleibt.
|
||||
(wcmatch bname "ZZ_ASES_MARKER*")
|
||||
;; ZZ_UNIT_MARKER: die Foerdereinheit-/Gefaelleeinheit-Marker
|
||||
;; (siehe csv:unitmark-aktualisieren, export.lsp) - aus
|
||||
;; demselben Grund wie ZZ_ASES_MARKER.
|
||||
(wcmatch bname "ZZ_UNIT_MARKER*")
|
||||
(wcmatch bname "Separator_SP*,S-LP*,Scanner*")
|
||||
(wcmatch bname "BTMT-Beladung*,SC_Entladung*")
|
||||
(wcmatch bname "Eingang*,Ausgang*")
|
||||
|
||||
+26
-5
@@ -76,16 +76,36 @@
|
||||
# Gefaellestrecken-Segmente, Umlenk-/Motorstation). Wie pattern_schleuselement
|
||||
# liegen sie NICHT als eigener top-level INSERT vor, sondern verpackt in der
|
||||
# Wrapper-Blockdefinition - die Muster dienen der SUCHE dort
|
||||
# (csv:nested-welt-records). Exportiert wird eine TEMPORAERE Kopie des
|
||||
# jeweiligen Original-Blocks (csv:element-proxies-erzeugen, wie bei
|
||||
# Separator/pattern_separator), die nach dem Export wieder geloescht wird.
|
||||
# Vario_Kurve_* ist laut Code-Kommentar (vf_linienzug.lsp) aktuell nirgends
|
||||
# im Projekt tatsaechlich eingefuegt - nur zur Vollstaendigkeit gelistet.
|
||||
# (csv:nested-welt-records). Eine TEMPORAERE Kopie des jeweiligen Original-
|
||||
# Blocks wird IMMER erzeugt (csv:element-proxies-erzeugen, wie bei Separator/
|
||||
# pattern_separator - liefert die Positionsdaten fuer die Gruppierung unten)
|
||||
# und nach dem Export IMMER wieder geloescht; als EIGENE Export-Zeile
|
||||
# erscheinen sie aber NUR, wenn *csv-export-alle-elemente* (export.lsp) auf T
|
||||
# gesetzt ist. Im Default (nil, gruppierter Modus) fasst
|
||||
# csv:unitmark-aktualisieren sie stattdessen zu Foerdereinheit-/
|
||||
# Gefaelleeinheit-Zeilen zusammen (siehe pattern_unit_marker). Vario_Kurve_*
|
||||
# ist laut Code-Kommentar (vf_linienzug.lsp) als "nirgends im Projekt
|
||||
# tatsaechlich eingefuegt" dokumentiert - in der Praxis kommt es doch vor
|
||||
# (siehe reale HundM05-Exporte), das Muster bleibt darum wirksam.
|
||||
# Staustrecke_SP_1000_mm wird beim Bau per Laenge NICHT-UNIFORM skaliert
|
||||
# (insert-inclined-scaled-block) - csv:get-k-kos-strings beruecksichtigt das
|
||||
# beim Lesen von K1/K2 (sx/sy/sz-Parameter). export_sivas.py schliesst diese
|
||||
# vier Muster wie Separator/Scanner aus (Stueckzahl steckt schon in den
|
||||
# GF_Bogen_*/VF_Bogen_*/ANZAHL_VF/ANZAHL_GF-Attributen des Wrappers).
|
||||
#
|
||||
# pattern_unit_marker: der Marker, den der Export je zusammenhaengendem
|
||||
# Foerderer-Abschnitt ("Foerdereinheit") bzw. Gefaelle-Abschnitt
|
||||
# ("Gefaelleeinheit") einer VF_n/GF_n-Kette setzt (ZZ_UNIT_MARKER, ein
|
||||
# Rechteck auf der Bounding-Box-Vereinigung aller enthaltenen Boegen/
|
||||
# Streckenelemente/Umlenk-/Motorstation-Mitglieder, csv:unitmark-
|
||||
# aktualisieren in Lisp/export.lsp). Bleibt wie ZZ_ASES_MARKER dauerhaft in
|
||||
# der Zeichnung stehen und behaelt seine ID ueber Exportlaeufe hinweg
|
||||
# (Attribute ID/ZUORDNUNG/TYP/LFDNR/LAENGE_m/ANZAHL_BOEGEN/K1/K2, alle
|
||||
# unsichtbar). Nur aktiv im gruppierten Modus (*csv-export-alle-elemente* =
|
||||
# nil) - im Rohdaten-Modus werden keine neuen Marker angelegt, verwaiste
|
||||
# Marker (z.B. nach einem Wechsel gruppiert->roh) werden aber immer
|
||||
# aufgeraeumt. export_sivas.py schliesst dieses Muster wie die vier
|
||||
# pattern_nested_*-Muster aus (Stueckzahl steckt in ANZAHL_VF/ANZAHL_GF).
|
||||
# ============================================================
|
||||
|
||||
[blockpattern]
|
||||
@@ -109,6 +129,7 @@ pattern_nested_bogen= Gefaellebogen_*, Vario_Bogen_*, Vario_Kurve_*
|
||||
pattern_nested_streckenelement= Staustrecke_SP_1000_mm*
|
||||
pattern_nested_umlenkstation= Vario_Umlenkstation_*
|
||||
pattern_nested_motorstation= Vario_Motorstation_*
|
||||
pattern_unit_marker= ZZ_UNIT_MARKER*
|
||||
pattern_ks_subblocks= KS_EIN, KS_AUS, K1, K2, K3, K4
|
||||
|
||||
[python]
|
||||
|
||||
@@ -272,6 +272,24 @@ def build_element_merkmale(block):
|
||||
}
|
||||
|
||||
|
||||
def build_einheit_merkmale(block):
|
||||
"""Merkmale-Dict fuer eine Foerdereinheit-/Gefaelleeinheit-Zeile (ZZ_UNIT_
|
||||
MARKER, siehe csv:unitmark-aktualisieren in export.lsp und
|
||||
pattern_unit_marker in cfg/export.cfg).
|
||||
|
||||
LAENGE_m/ANZAHL_BOEGEN kommen direkt aus den ATTDEFs des Markers - dort
|
||||
von Lisp bereits vorberechnet (Summe der LAENGE/A-Attribute aller
|
||||
zugeordneten Streckenelement-Mitglieder bzw. Anzahl der Bogen-Mitglieder).
|
||||
Python hat im gruppierten Modus KEINEN Zugriff auf die Einzelteile selbst
|
||||
(die werden dort gar nicht erst exportiert), daher keine eigene
|
||||
Neuberechnung hier."""
|
||||
attribs = block.get("attribs", {})
|
||||
return {
|
||||
"Laenge_m": attribs.get("LAENGE_m", ""),
|
||||
"Anzahl_Boegen": attribs.get("ANZAHL_BOEGEN", ""),
|
||||
}
|
||||
|
||||
|
||||
def build_btmt_merkmale(block):
|
||||
"""Merkmale-Dict fuer eine eigenstaendige BTMT-Beladung/SC_Entladung-Station
|
||||
(siehe pattern_btmt_beladung/pattern_btmt_entladung in cfg/export.cfg).
|
||||
@@ -948,6 +966,8 @@ def process_blocks(blocks, lookup, dbg=None):
|
||||
geruest_count = 0
|
||||
ausschleus_count = 0
|
||||
einschleus_count = 0
|
||||
foerdereinheit_count = 0
|
||||
gefaelleeinheit_count = 0
|
||||
|
||||
# Zaehlung fuer die Omniflo-Sum-Zeile (nur Bogen/Weiche/Gerade)
|
||||
cnt_wk = cnt_einzel = cnt_delta = cnt_doppel = cnt_stern = 0
|
||||
@@ -1013,6 +1033,40 @@ def process_blocks(blocks, lookup, dbg=None):
|
||||
})
|
||||
continue
|
||||
|
||||
# ZZ_UNIT_MARKER (siehe cfg/export.cfg pattern_unit_marker sowie
|
||||
# csv:unitmark-aktualisieren in Lisp/export.lsp): der persistente
|
||||
# Marker, den Lisp je zusammenhaengendem Foerderer-/Gefaelle-Abschnitt
|
||||
# einer VF_n/GF_n-Kette setzt (gruppierter Modus, Default). TYP
|
||||
# entscheidet VF->Foerdereinheit / GF->Gefaelleeinheit, analog zur
|
||||
# AS/ES-Klassifikation oben. K1/K2 brauchen keine Sonderbehandlung -
|
||||
# bbox_columns() liest sie generisch aus dem JSON-Row (csv:unitmark-
|
||||
# k-kos-strings, export.lsp).
|
||||
if matches_any(bname, BLOCKPATTERNS.get("pattern_unit_marker", [])):
|
||||
attribs = block.get("attribs", {})
|
||||
typ = attribs.get("TYP", "")
|
||||
teileart = {"VF": "ILS 2.0 Foerdereinheit", "GF": "ILS 2.0 Gefaelleeinheit"}.get(typ)
|
||||
if teileart is None:
|
||||
print(f"[export_csv] WARNUNG: {bname} ohne gueltiges TYP-Attribut "
|
||||
f"(TYP={typ!r}) - uebersprungen")
|
||||
continue
|
||||
elem_nr += 1
|
||||
if typ == "VF":
|
||||
foerdereinheit_count += 1
|
||||
zaehler_n = foerdereinheit_count
|
||||
else:
|
||||
gefaelleeinheit_count += 1
|
||||
zaehler_n = gefaelleeinheit_count
|
||||
items.append({
|
||||
"nr": elem_nr,
|
||||
"teileart": teileart,
|
||||
"teileid": attribs.get("ID") or format_sensor_id("EINH", elem_nr),
|
||||
"bezeichnung": f"{teileart} :{zaehler_n}",
|
||||
"planquadrat": planquadrat_column(block, planquadrat_cfg),
|
||||
"merkmale": build_einheit_merkmale(block),
|
||||
**bbox_columns(block),
|
||||
})
|
||||
continue
|
||||
|
||||
# Omniflo Bogen oder Weiche
|
||||
if bname in lookup:
|
||||
typ, eintrag = lookup[bname]
|
||||
|
||||
+10
-6
@@ -413,18 +413,22 @@ SKIP_BLOCKS = set(BLOCKPATTERNS.get("pattern_ks_subblocks", ["K1", "K2", "K3", "
|
||||
#
|
||||
# Dieselbe Ueberlegung gilt fuer die ausgepackten VF_n/GF_n-Sub-Komponenten
|
||||
# (Boegen, gerade Foerderer-/Gefaellestrecken-Segmente, Umlenk-/Motorstation -
|
||||
# siehe csv:element-proxies-erzeugen, export.lsp): ihre Stueckzahl steckt
|
||||
# bereits in den GF_Bogen_*/VF_Bogen_*/ANZAHL_VF/ANZAHL_GF-Attributen des
|
||||
# Wrappers (*strecke-attr-gruppe*, ssg_core.lsp) - ein eigener Sivas-Eintrag
|
||||
# wuerde ebenso doppelt zaehlen. Muss VOR der pattern_strecke_module-Pruefung
|
||||
# unten greifen, sonst faengt deren generisches "ILS 2.0 Strecke"-Sammeln
|
||||
# diese Kopien zuerst ab.
|
||||
# siehe csv:element-proxies-erzeugen, export.lsp; nur im Rohdaten-Modus
|
||||
# *csv-export-alle-elemente*=T ueberhaupt in export_raw.json vorhanden) sowie
|
||||
# fuer die gruppierten Foerdereinheit-/Gefaelleeinheit-Marker (ZZ_UNIT_MARKER,
|
||||
# csv:unitmark-aktualisieren, Default-Modus): ihre Stueckzahl steckt bereits
|
||||
# in den GF_Bogen_*/VF_Bogen_*/ANZAHL_VF/ANZAHL_GF-Attributen des Wrappers
|
||||
# (*strecke-attr-gruppe*, ssg_core.lsp) - ein eigener Sivas-Eintrag wuerde
|
||||
# ebenso doppelt zaehlen. Muss VOR der pattern_strecke_module-Pruefung unten
|
||||
# greifen, sonst faengt deren generisches "ILS 2.0 Strecke"-Sammeln diese
|
||||
# Kopien zuerst ab.
|
||||
SEP_SCANNER_PATTERNS = (
|
||||
BLOCKPATTERNS.get("pattern_separator", []) + BLOCKPATTERNS.get("pattern_scanner", [])
|
||||
+ BLOCKPATTERNS.get("pattern_nested_bogen", [])
|
||||
+ BLOCKPATTERNS.get("pattern_nested_streckenelement", [])
|
||||
+ BLOCKPATTERNS.get("pattern_nested_umlenkstation", [])
|
||||
+ BLOCKPATTERNS.get("pattern_nested_motorstation", [])
|
||||
+ BLOCKPATTERNS.get("pattern_unit_marker", [])
|
||||
)
|
||||
|
||||
# Sivas-Nummern und Bezeichnungen je ILS-Elementtyp
|
||||
|
||||
@@ -410,6 +410,87 @@
|
||||
(csv:element-teileart "Vario_Motorstation_500mm_rechts"))
|
||||
(tu-eq "csv:element-teileart/unbekannt" nil
|
||||
(csv:element-teileart "AS_Element_90_links"))
|
||||
|
||||
;; --- csv:sepliste-partition: sepliste in Foerdereinheit-/Gefaelleeinheit-
|
||||
;; Spannen aufteilen (Lauflaengen-Kodierung ueber den effektiven Typ) -----
|
||||
;; Reine Rechenfunktion auf (typ lfdnr strecke-typ welt-pt)-Tupeln, hier
|
||||
;; ohne Zeichnung testbar (welt-pt wird von der Partitionierung selbst
|
||||
;; nicht gebraucht, darum ueberall nil).
|
||||
|
||||
;; HundM05 VF_1-Beispiel (echt verifiziert): AS, SEP2=VF, SEP3=GF, SEP4=GF,
|
||||
;; SEP5=VF, ES -> 3 Einheiten VF,GF,VF. SEP3+SEP4 bracketen GEMEINSAM eine
|
||||
;; einzige Gefaelleeinheit (nicht zwei separate).
|
||||
(setq _sep-hundm05
|
||||
'(("AS" 1 nil nil) ("SEP" 2 "VF" nil) ("SEP" 3 "GF" nil)
|
||||
("SEP" 4 "GF" nil) ("SEP" 5 "VF" nil) ("ES" 6 nil nil)))
|
||||
(tu-eq "csv:sepliste-partition/hundm05"
|
||||
'(("VF" (1 2)) ("GF" (3 4)) ("VF" (5 6)))
|
||||
(csv:sepliste-partition _sep-hundm05))
|
||||
|
||||
;; Minimalfall: nur AS-SEP(VF)-ES, kein Typwechsel -> 1 Foerdereinheit ueber
|
||||
;; die ganze Kette.
|
||||
(setq _sep-minimal '(("AS" 1 nil nil) ("SEP" 2 "VF" nil) ("ES" 3 nil nil)))
|
||||
(tu-eq "csv:sepliste-partition/minimal"
|
||||
'(("VF" (1 2 3)))
|
||||
(csv:sepliste-partition _sep-minimal))
|
||||
|
||||
;; Einzel-GF-Fall: die Gefaelleeinheit wird nur von EINEM SEP (nicht zwei)
|
||||
;; UND dem nachfolgenden ES bracketiert.
|
||||
(setq _sep-einzel-gf
|
||||
'(("AS" 1 nil nil) ("SEP" 2 "VF" nil) ("SEP" 3 "GF" nil) ("ES" 4 nil nil)))
|
||||
(tu-eq "csv:sepliste-partition/einzel-gf"
|
||||
'(("VF" (1 2)) ("GF" (3 4)))
|
||||
(csv:sepliste-partition _sep-einzel-gf))
|
||||
|
||||
;; 3+ gleichtypige SEP-Eintraege hintereinander muessen weiterhin EINE
|
||||
;; Einheit ergeben (nicht mehrere) - Lauflaengen-Regel, kein Sonderfall.
|
||||
(setq _sep-dreifach-gf
|
||||
'(("AS" 1 nil nil) ("SEP" 2 "VF" nil) ("SEP" 3 "GF" nil)
|
||||
("SEP" 4 "GF" nil) ("SEP" 5 "GF" nil) ("SEP" 6 "VF" nil) ("ES" 7 nil nil)))
|
||||
(tu-eq "csv:sepliste-partition/dreifach-gf"
|
||||
'(("VF" (1 2)) ("GF" (3 4 5)) ("VF" (6 7)))
|
||||
(csv:sepliste-partition _sep-dreifach-gf))
|
||||
|
||||
;; Kette beginnend mit GF (AS erbt den Typ des ersten SEP-Eintrags, hier GF
|
||||
;; statt des sonstigen Default "VF").
|
||||
(setq _sep-startet-gf
|
||||
'(("AS" 1 nil nil) ("SEP" 2 "GF" nil) ("ES" 3 nil nil)))
|
||||
(tu-eq "csv:sepliste-partition/startet-gf"
|
||||
'(("GF" (1 2 3)))
|
||||
(csv:sepliste-partition _sep-startet-gf))
|
||||
|
||||
;; --- csv:dot2: 2D-Skalarprodukt ---
|
||||
(tu-eqf "csv:dot2/achsen" 0.0 (csv:dot2 '(1.0 0.0) '(0.0 1.0)))
|
||||
(tu-eqf "csv:dot2/parallel" 6.0 (csv:dot2 '(2.0 0.0) '(3.0 0.0)))
|
||||
|
||||
;; --- csv:element-unit-zuordnung: Elemente per Kettenrichtungs-Projektion
|
||||
;; den Einheiten-Spannen zuordnen und INNERHALB jeder Spanne nach der
|
||||
;; Projektion sortieren -----------------------------------------------
|
||||
;; Gerade Kette AS(0,0) -SEP2(VF, 10,0)- SEP3(GF, 20,0) -ES(30,0)- entlang
|
||||
;; der X-Achse. unit-spans: VF=[1,2], GF=[2,3] (SEP2 gehoert zu beiden
|
||||
;; Spannen als Grenzmarker, siehe csv:sepliste-partition).
|
||||
(setq _sep-proj
|
||||
'(("AS" 1 nil (0.0 0.0 0.0)) ("SEP" 2 "VF" (10.0 0.0 0.0))
|
||||
("SEP" 3 "GF" (20.0 0.0 0.0)) ("ES" 4 nil (30.0 0.0 0.0))))
|
||||
(setq _spans-proj (csv:sepliste-partition _sep-proj))
|
||||
(tu-eq "csv:sepliste-partition/proj-spans" '(("VF" (1 2)) ("GF" (3 4))) _spans-proj)
|
||||
;; Zwei Elemente: eines bei x=5 (klar in der VF-Spanne [0,10]), eines bei
|
||||
;; x=17 (in der Luecke zwischen den Spannen-Grenzpunkten [10,20], aber
|
||||
;; naeher an der GF-Grenze 20 als an der VF-Grenze 10 - eindeutig GF, kein
|
||||
;; Gleichstand wie bei x=15 in der Luecken-Mitte).
|
||||
(setq _elem-vf (list 'PROXY1 'WRAPPER "STRECKENELEMENT" '(5.0 0.0 0.0)))
|
||||
(setq _elem-gf (list 'PROXY2 'WRAPPER "STRECKENELEMENT" '(17.0 0.0 0.0)))
|
||||
(setq _zuord (csv:element-unit-zuordnung _spans-proj _sep-proj (list _elem-vf _elem-gf)))
|
||||
(tu-eq "csv:element-unit-zuordnung/vf-treffer" (list _elem-vf) (nth 0 _zuord))
|
||||
(tu-eq "csv:element-unit-zuordnung/gf-treffer" (list _elem-gf) (nth 1 _zuord))
|
||||
|
||||
;; Sortierung innerhalb einer Spanne: zwei Elemente in der VF-Spanne,
|
||||
;; absichtlich in "falscher" Reihenfolge uebergeben - das Ergebnis muss
|
||||
;; nach x sortiert sein (frueheres x zuerst).
|
||||
(setq _elem-a (list 'PROXY_A 'WRAPPER "BOGEN" '(8.0 0.0 0.0)))
|
||||
(setq _elem-b (list 'PROXY_B 'WRAPPER "BOGEN" '(2.0 0.0 0.0)))
|
||||
(setq _zuord2 (csv:element-unit-zuordnung _spans-proj _sep-proj (list _elem-a _elem-b)))
|
||||
(tu-eq "csv:element-unit-zuordnung/sortiert" (list _elem-b _elem-a) (nth 0 _zuord2))
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user