export: Kettenbausteine ueber KS verketten, Einheiten neu gruppieren

K1/K2 und Boundingbox je Export-Zeile folgen jetzt dem echten
Kettenbaustein statt seinem Stellvertreter:
- Separator (all_elements): KS + bbox des 300-mm-Trennstegs statt des
  Sensor-Symbols; separator_track/group_vf_gf behalten das Symbol
- AS/ES (all_elements, group_vf_gf): KS + bbox des AS-/ES-Elements statt
  des 200x200-Markers ohne K
- gemeinsamer Kern csv:ks-welt-punkte; VF/GF-Wrapper-K1/K2 = K1 des AS
  bzw. K2 des ES

Gruppierter Export neu (sepliste-/XDATA-Algorithmus entfernt):
- Bausteine je Wrapper als Vektorkette K2 -> K1 ordnen (Start am AS)
- Foerdereinheit = Separator vor der Umlenkstation bis Motorstation,
  alles dazwischen Gefaelleeinheit (csv:kette-einheiten, Unit-Tests)
- je Einheit ein temporaerer Proxy mit 3D-Boundingbox, K1/K2, Laenge und
  Anzahl Boegen; wird nach dem Export geloescht (ausser csv_leave_proxies)
- IDs neuer Export-Objekte entlang der Kette AS -> ES aufsteigend

Weiteres:
- ssg-make-layer ohne _LAYER-Befehl fuer bestehende Layer (Konsole)
- einheitliche, zweisprachige Meldungen fuer behaltene Hilfskopien
- bin/show_exportcsv.bat: Export-CSV als Boundingbox-SVG (sps_skel)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Michael Stangl
2026-09-25 20:25:29 +02:00
co-authored by Claude Opus 5.5
parent bc481de901
commit 394d476d56
13 changed files with 1017 additions and 1037 deletions
+52 -3
View File
@@ -104,8 +104,8 @@ Pro INSERT wird ein JSON-Objekt geschrieben:
| `x`, `y`, `z`, `rotation` | `(assoc 10)` / `(assoc 50)` | roher Einfuegepunkt/-winkel, KEIN `vla-getboundingbox` |
| `attribs` | alle ATTRIB-Werte | |
| `insertpoint` | `csv:kos-encode` | Position+Rotation als 24-Zeichen-Base64 (Quaternion) |
| `k1`..`k4` | `csv:get-k-kos-strings` bzw. Fallbacks | Anschluss-Koordinatensysteme, siehe unten |
| `bbox` | `csv:get-bbox` (`vla-getboundingbox`) | NUR wenn `include-bbox=T` und der Aufruf gelingt; fehlt sonst komplett im JSON |
| `k1`..`k4` | `csv:k-liste` (Kern `csv:ks-welt-punkte`) bzw. Fallbacks | Anschluss-Koordinatensysteme, siehe unten |
| `bbox` | `csv:get-bbox` (`vla-getboundingbox`), im Modus `all_elements` fuer Separator/AS/ES die des Bausteins (`csv:baustein-merken`) | NUR wenn `include-bbox=T` und der Aufruf gelingt; fehlt sonst komplett im JSON |
| `warnung` | `*cs-scanner-warnung-by-handle*` | strittige Scanner-Zuordnung aus `cs-zuordnung-lauf` |
| `zuordnung_fix` | `*cs-sep-fix-by-handle*` | nur bei Proxy-Kopien: die feststehende Wrapper-ID |
| `sepliste` | `ssg-sepliste-xdata-lesen` + `*csv-sepliste-id-by-handle*` | nur bei VF_n/GF_n, siehe eigener Abschnitt |
@@ -116,7 +116,56 @@ Laenge+Rotation synthetisiert (`csv:gerade-k-kos-strings`). VF_n/GF_n leiten
K1 (Eingang) und K2 (Ausgang) aus den eingebetteten AS_Element/ES_Element ab
(`csv:vfgf-k-kos-strings`), damit die Kreisel<->Strecke-Kollisionspruefung in
Python mit einer kleinen festen Box an der AS/ES-Position arbeiten kann statt
mit der ganzen (oft sehr langen) Wrapper-Box.
mit der ganzen (oft sehr langen) Wrapper-Box. K1 des Wrappers ist dabei K1
des AS, K2 der K2 des ES (`csv:vfgf-element-punkte`, dieselbe Rechnung wie
deren eigene Zeilen).
**Kettenteile: Stellvertreter vs. Baustein.** Innerhalb einer VF_n/GF_n-Kette
gilt fuer jedes Teil K1 = KS_EIN, K2 = KS_AUS des Bausteins - K2 eines Teils
ist exakt K1 des naechsten. Bogen/Streckenelement/Motor-/Umlenkstation werden
als 1:1-Kopie exportiert und erfuellen das von selbst. Separator und AS/ES
exportieren dagegen einen **Stellvertreter**: die Kopie des Sensor-Symbols
`Separator_SP` (sitzt 235 mm weit im 300-mm-Trennsteg
`Staustrecke_Separator_SP_300_mm`, hat nur EIN eigenes KS) bzw. den
`ZZ_ASES_MARKER` (200x200, ohne KS). Was die Zeile fuehrt, haengt am Modus:
| Modus | Separator | AS/ES |
|---|---|---|
| `all_elements` | K1/K2 + bbox des Trennstegs | K1/K2 + bbox des AS-/ES-Elements (AS: K1 Kreisel, K2 Kettenanfang; ES: K1 Kettenende, K2 Kreisel) |
| `group_vf_gf` | KS + bbox des Symbols | wie `all_elements` (schliesst an die Einheiten an) |
| `separator_track` | KS + bbox des Symbols | bbox des Markers, keine K |
IDs der neuen Export-Objekte jeder Kette (Separator-/Element-Kopien, neue
AS/ES-Marker, Einheiten-Proxies) werden vor `ssg-id-check-all` entlang der
Kette von AS nach ES aufsteigend vergeben (`csv:ketten-verarbeiten`) - die
CSV ist nach TeileId sortiert, die Zeilen stehen damit in Kettenfolge.
Umgesetzt ueber `csv:baustein-merken`: beim Erzeugen des Stellvertreters
werden K-Punkte (`csv:ks-welt-punkte`) und bbox (kurzlebige Kopie des
Bausteins, `csv:baustein-bbox`) unter seinem Handle gemerkt
(`*csv-baustein-by-handle*`, je Lauf neu); `csv:k-liste` und
`csv:block-to-json` bevorzugen diese Werte. Der Trennsteg eines Symbols wird
ueber die Lage des Symbols IM Trennsteg gefunden (`csv:trennsteg-zu-symbol`),
nicht ueber den naechsten Ursprung.
**Gruppierter Modus (`group_vf_gf`): Foerder-/Gefaelleeinheiten.** Eine
VF_n/GF_n-Kette wechselt zwischen Gefaelle- und Foerderabschnitten (GF, VF,
GF, ...). `csv:ketten-verarbeiten` holt je Wrapper alle Bausteine samt
Welt-KS (`csv:kette-teile`: AS, Trennstege, Boegen, Streckenelemente,
Umlenk-/Motorstation, ES), ordnet sie als **Vektorkette** - auf K2 eines
Bausteins liegt K1 des naechsten, Start am AS (`csv:kette-ordnen`, Toleranz
2 mm) - und schneidet die Typfolge in Einheiten (`csv:kette-einheiten`):
eine **Foerdereinheit** beginnt am Separator vor der Umlenkstation und endet
mit der Motorstation, alles dazwischen ist eine **Gefaelleeinheit**; AS/ES
bleiben eigene Zeilen. Kurven sind dabei kein Problem, weil nur die
KS-Nachbarschaft zaehlt. Je Einheit entsteht ein Proxy `ZZ_UNIT_MARKER` auf
der vereinigten Boundingbox (gemessen an kurzlebigen Kopien der Bausteine),
mit K1 vom ersten und K2 vom letzten Baustein, `LAENGE_m` = Summe der
Streckenelement-Laengen K1->K2, `ANZAHL_BOEGEN`. Alle Proxies werden nach
dem Export geloescht, ausser der Debug-Schalter `csv_leave_proxies` ist
gesetzt. Reisst die KS-Kette ab, meldet der Export das (`exp-kette-luecke`)
und fuehrt den Rest als eigene Teilkette weiter. Die fruehere Gruppierung
ueber die sepliste-XDATA und den Separator-Typ (`SSG_SEP_TYP`) ist entfallen.
**Die `bbox` ist das einzige Feld, das `vla-getboundingbox` braucht** — alle
anderen Felder kommen aus rohen DXF-Gruppencodes oder XDATA. Ein Ausfall von