Files
dxfmakros/cfg/export.cfg
T
Michael StanglandClaude Opus 5.5 394d476d56 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>
2026-09-25 20:25:29 +02:00

318 lines
17 KiB
INI

# ============================================================
# export.cfg - Konfiguration fuer Lisp/export.lsp UND lib/export_csv.py,
# lib/export_sivas.py (gemeinsame Blockname-Muster, siehe
# lib/export_blockpatterns.py)
#
# Format: INI-Style
# [ABSCHNITT]
# Key = Wert (einzelner Wert)
# Key = Wert1, Wert2, Wert3 (Musterliste fuer wcmatch/fnmatch, kommagetrennt)
#
# Zeilen mit # sind Kommentare. Leerzeilen werden ignoriert.
#
# pattern_kreisel/pattern_strecke sind fuer Lisp's Block-SAMMLUNG grob
# gehalten (nur "gehoert das ueberhaupt zum Export"). Die uebrigen
# pattern_eckrad/pattern_variofoerderer/pattern_gefaellestrecke/
# pattern_strecke_module-Keys sind Teilmengen davon fuer die feinere
# TeileArt-KLASSIFIKATION in Python (eigene Zeile je Teileart) -
# Aenderungen an Blocknamen bitte in beiden Stellen nachziehen.
#
# pattern_separator/pattern_scanner: eigenstaendige Sensor-Bloecke
# (Separator_SP/S-LP, Scanner - siehe ils-insert-sensor/mubea:build-separator-one).
# Werden von Lisp's Block-SAMMLUNG mitgesammelt (siehe export.lsp) und von
# export_csv.py als eigene TeileArt-Zeilen mit einer beim Export erzeugten
# laufenden ID ausgegeben (die Bloecke selbst haben KEIN ID-Attribut - anders
# als Kreisel/GF/VF -, daher keine ssg-id-generate-Persistenz). export_sivas.py
# schliesst dieselben Bloecke bewusst aus (siehe SEP_SCANNER_PATTERNS dort):
# ihre Stueckzahl wird im Sivas-Export bereits ueber die ANZAHL_SEPARATOR/
# ANZAHL_SCANNER-Attribute der zugehoerigen Kreisel/Gefaellestrecke/
# VarioFoerderer-Bloecke gezaehlt - ein zusaetzlicher eigener Eintrag wuerde
# doppelt zaehlen.
#
# pattern_btmt_beladung/pattern_btmt_entladung: eigenstaendige BTMT Be-/
# Entladestationen (siehe ils-insert-station in SSG_LIB_Commands.lsp). Anders
# als Separator/Scanner werden sie NICHT von einem anderen Element mitgezaehlt
# (kein ANZAHL_*-Attribut an einem Carrier) - export_csv.py UND export_sivas.py
# fuehren sie daher beide als eigene TeileArt-Zeilen (export_sivas.py zusaetzlich
# in den Summierungszaehlern "Anzahl aller BTBeladung"/"Anzahl aller
# Abwurfstationen" der ILS-Automation-Zeile).
#
# pattern_eingang/pattern_ausgang: Eingangs-/Ausgangssymbole des Material-
# flusses (siehe ils-insert-station in SSG_LIB_Commands.lsp, Bloecke
# Eingang_<DIM>/Ausgang_<DIM>). NUR fuer den CSV-Export: export_csv.py fuehrt
# sie als eigene TeileArt-Zeilen ("Eingang"/"Ausgang", Merkmale wie BTMT) UND
# als frei platzierte Umlauf-Punkte auf einem Kreisel (KREISEL_UMLAUF_TEILEARTEN
# in lib/export_neighbors.py), damit sie - wie Separator/AS/ES - in die
# "TrackIds"-Spalte gelangen. export_sivas.py schliesst sie bewusst aus (kein
# Sivas-Eintrag). Voraussetzung fuer eine stabile TeileId ist ein ID-ATTDEF in
# den DWGs (ssg-id-check-all fuellt es vor jedem Export, siehe
# ssg-id-collect-blocks in ssg_id.lsp).
#
# pattern_schleuselement: die AS-/ES-Schleuselemente an den Enden einer
# VF_n/GF_n-Kette. Sie liegen in der gespeicherten Zeichnung NICHT als eigener
# top-level INSERT vor, sondern verpackt in der Wrapper-Blockdefinition. Dieses
# Muster dient nur der SUCHE in der Blockdefinition (csv:nested-welt-records in
# Lisp/export.lsp) - exportiert wird nicht das Element selbst, sondern sein
# Marker (siehe pattern_ases_marker).
#
# pattern_ases_marker: der Marker, den der Export an jedes AS-/ES-Kettenende
# setzt (ZZ_ASES_MARKER, ein kleines Rechteck, csv:asmark-aktualisieren in
# Lisp/export.lsp). Er bleibt nach dem Export in der Zeichnung stehen, macht
# das sonst unsichtbare Kettenende anklickbar und traegt dessen ID ueber
# Exportlaeufe hinweg (Attribute ID/ZUORDNUNG/TYP/LFDNR/ELEMENT/ARTINR, alle
# unsichtbar). Die ID landet im "sepliste"-Array des Wrappers (Feld "id" je
# Eintrag) UND als eigene Zeile in export_raw.json. Von Lisp's Block-SAMMLUNG
# genutzt; die Python-Klassifikation kennt das Muster noch nicht (der Block
# faellt dort durch alle Muster und wird uebersprungen) - sobald sie es kennt,
# ersetzt sie damit die bisher in Python synthetisierten Ein-/Ausschleus-
# element-Zeilen (build_strecke_schleus_items).
#
# pattern_geruest: Geruest-Baugruppen (GeruestInsert.lsp, GR_<id>_<timestamp>).
# Eigenstaendig wie BTMT, kein ANZAHL_*-Attribut an einem Carrier - export_csv.py
# UND export_sivas.py fuehren sie als eigene TeileArt-Zeilen.
#
# pattern_nested_bogen/_streckenelement/_umlenkstation/_motorstation: die
# uebrigen Bausteine einer VF_n/GF_n-Kette (Boegen, gerade Foerderer-/
# 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). Im Modus all_elements wird je Baustein eine
# TEMPORAERE Kopie erzeugt (csv:element-proxies-erzeugen) und als eigene
# Export-Zeile ausgegeben, danach wieder geloescht. Im gruppierten Modus
# (group_vf_gf, Default) fasst csv:ketten-verarbeiten die Bausteine
# 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 Proxy, den der Export im gruppierten Modus je
# Foerderer-Abschnitt ("Foerdereinheit") bzw. Gefaelle-Abschnitt
# ("Gefaelleeinheit") einer VF_n/GF_n-Kette setzt (ZZ_UNIT_MARKER, ein
# Rechteck auf der Bounding-Box-Vereinigung der enthaltenen Bausteine,
# csv:ketten-verarbeiten in Lisp/export.lsp). Die Kette wird dafuer als
# Vektorkette K2 -> K1 geordnet; eine Foerdereinheit reicht vom Separator vor
# der Umlenkstation bis zur Motorstation, alles dazwischen ist Gefaelle.
# Der Proxy ist ein reines Export-Hilfsmittel: er wird bei jedem Export neu
# erzeugt und danach geloescht, ausser der Debug-Schalter csv_leave_proxies
# ist gesetzt (Attribute ID/ZUORDNUNG/TYP/LFDNR/LAENGE_m/ANZAHL_BOEGEN/K1/K2,
# alle unsichtbar). export_sivas.py schliesst dieses Muster wie die vier
# pattern_nested_*-Muster aus (Stueckzahl steckt in ANZAHL_VF/ANZAHL_GF).
# ============================================================
[blockpattern]
pattern_kreisel= KR_*, KREISEL_*, ECKRAD_*
pattern_eckrad= ECKRAD_*
pattern_gerade= AP110*, AP_110*
pattern_strecke= Vario*, Staustrecke*, AUS_Element*, EIN_Element*, VF_*, GF_*
pattern_variofoerderer= VF_*
pattern_gefaellestrecke= GF_*
pattern_strecke_module= Vario*, Staustrecke*, AUS_Element*, EIN_Element*
pattern_schleuselement= AS_Element*, ES_Element*
pattern_ases_marker= ZZ_ASES_MARKER*
pattern_separator= Separator_SP*, S-LP*
pattern_scanner= Scanner*
pattern_btmt_beladung= BTMT-Beladung*
pattern_btmt_entladung= SC_Entladung*
pattern_eingang= Eingang*
pattern_ausgang= Ausgang*
pattern_geruest= GR_*
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]
# Interpreter fuer die Export-Skripte (lib/export_csv.py, lib/export_sivas.py).
# Leer lassen = automatisch: DXFM_PYTHON (aus bin/setenv.bat) -> Projekt-venv
# <DXFMAKRO>/.venv/Scripts/python.exe -> py.exe -> python (PATH).
# Nur setzen, wenn ein bestimmter Interpreter erzwungen werden muss.
# Wichtig: NICHT auf %LOCALAPPDATA%\Microsoft\WindowsApps\python.exe zeigen -
# das ist nur der Microsoft-Store-Platzhalter (bricht mit Exitcode 49 ab und
# der Export erzeugt dann keine CSV). Solche Pfade werden ignoriert.
interpreter=
[Planquadrate]
section=Planquadrate_AN
# x_origin/y_origin (in m, DXF-Koordinate der Planquadrat-Ecke A/1 bzw. 1/1):
# Der Zeichnungsnullpunkt (0,0) liegt in der Regel NICHT in der Gebaeudeecke -
# Bauteile mit negativer x/y-Koordinate wuerden ohne Offset einen Planquadrat-
# Index <= 0 ergeben und damit ein leeres Label (z.B. "/" oder "A/") liefern.
# Leer lassen/weglassen = automatisch: der Ursprung wird bei jedem Export neu
# auf das jeweils am weitesten links (x_origin) bzw. am weitesten unten
# (y_origin) liegende Element der aktuellen Zeichnung gesetzt, damit gilt
# immer Index 1 = dieses Element. Nur explizit setzen, wenn ein fester
# Bezug zur realen Gebaeudeecke gebraucht wird (z.B. Vergleich ueber
# mehrere Exportlaeufe/Zeichnungen hinweg).
x_origin=
y_origin=
# Texthoehe (mm) der Zaehlungs-Beschriftung am linken/unteren Rand des
# Planquadrat-Rasters, siehe Lisp/DrawPlanquadrate.lsp (DRAW_PLANQUADRATE).
# Nur fuer diesen Lisp-Befehl relevant, nicht fuer den CSV-/Sivas-Export.
# Default 300, falls nicht gesetzt.
text_hoehe_mm=300
# hier kann man im csv Export aus den Koordinaten der Bauteile die Planquadrate berechnen lassen, in denen sie liegen
# Zählung ist numerisch oder Alphabetisch möglich, Schrittweite in m (z.B. 2m pro Spalte, 4m pro Zeile)
# liegt man im ersten Quadrat, ist diese A/1, oder 1/1 oder 1/A, je nach Formatierung. Die Zählung beginnt immer bei 1
[Planquadrate_NA]
# z.B. 1/A
x_step=2
x_description=numerisch # zahlen, von links nach rechts, 2m pro Spalte
y_step=4
y_description=alphabetisch # Buchstaben von unten nach oben, 4m pro Zeile
format= {x}/{y} # Formatierung der Planquadrate, {y} und {x} werden durch die berechneten gerundeten Werte der Objektkoordinaten ersetzt
[Planquadrate_AN]
# z.B. A/1 (x = Alphabetisch, y = Numerisch)
x_step=2
x_description=alphabetisch # Buchstaben, von links nach rechts, 2m pro Spalte
y_step=2
y_description=numerisch # Zahlen von unten nach oben, 2m pro Zeile
format= {x}/{y}
[Planquadrate_NN]
# z.B. 2/5
x_step=2
x_description=numerisch # Zahlen, von links nach rechts, 2m pro Spalte
y_step=4
y_description=numerisch # Zahlen von unten nach oben, 4m pro Zeile
format= {x}/{y}
[Nachbarschaft]
# Toleranz fuer die Nachbarschaftserkennung beim CSV-Export (Spalte "Nachbarn").
# Die Bounding-Box jedes Elements wird um die Haelfte dieses Werts nach allen
# Seiten erweitert, bevor auf Ueberschneidung mit anderen Elementen geprueft
# wird - zwei Elemente mit einem Abstand <= toleranz_mm (z.B. zwei Kreisel)
# gelten dann ebenfalls als benachbart. Wert in mm. Siehe lib/export_neighbors.py.
toleranz_mm=200
# Rastergroesse (mm) fuer die Omniflo-Nachbarschaftspruefung (Bogen/Weiche/
# Gerade gegen Bogen/Weiche/Gerade). Wird nur als FALLBACK verwendet, wenn
# shapely (STRtree) nicht verfuegbar ist - dann werden Omniflo-Elemente vor
# dem Ueberschneidungstest nach x/y-Koordinate in Quadranten dieser Groesse
# eingeteilt und nur innerhalb derselben und der 8 angrenzenden Zellen
# geprueft (statt jedes Element gegen jedes). Im Normalfall uebernimmt der
# STRtree die Broad-Phase, dieser Wert bleibt dann ungenutzt. Sollte groesser
# als die ueblichen Omniflo-Bauteile sein (AP110-Geraden ca. 2000mm).
omniflo_zellgroesse_mm=3000
# Toleranz (mm) fuer die KOS-basierte VERFEINERUNG der Omniflo-Nachbarschaft.
# Nachdem der STRtree zwei Omniflo-Elemente (Bogen/Weiche/Gerade) anhand ihrer
# Bounding-Boxen als moegliche Nachbarn erkannt hat, wird zusaetzlich geprueft,
# ob sich ihre Anschluss-Koordinatensysteme (K1-K4) tatsaechlich beruehren:
# nur wenn ein K-Punkt des einen Elements naeher als dieser Wert an einem
# K-Punkt des anderen liegt, gelten sie als echte Nachbarn. Das trennt
# Elemente, deren Bounding-Boxen sich zwar ueberlappen, die aber nicht an
# einem gemeinsamen Anschlusspunkt zusammenstossen. Bei Elementen ohne K1-K4
# (z.B. Altbestand) faellt die Pruefung auf die reine BBox-Ueberschneidung
# zurueck. 0 = Verfeinerung aus (nur BBox). Wert in mm. Siehe
# lib/export_neighbors.py. Geraden fuehren KEINE echten K-Bloecke in der
# Zeichnung; ihre K1 (Anfang) / K2 (Ende) werden beim Export aus der Geometrie
# synthetisiert (siehe csv:gerade-k-kos-strings in Lisp/export.lsp).
omniflo_ks_toleranz_mm=10
# Kollisions-/Nachbarschafts-Debugprotokoll: 0/leer = aus, 1 = schreibt eine
# .dbg-Datei nach DXFM_LOG/export_collision.dbg (bzw. <repo>/logs/, falls
# DXFM_LOG nicht gesetzt ist). Alternativ ein expliziter Dateipfad. Das Log
# protokolliert je Element die Bounding-Box, die Gruppenzuordnung und jeden
# Ueberschneidungstest - zur Diagnose, warum (keine) Nachbarn gefunden werden.
debug_log=1
[Marker]
# Kantenlaenge (mm) des quadratischen Markers, den der Export an jedes AS-/ES-
# Kettenende einer VF_n/GF_n-Strecke setzt (Block ZZ_ASES_MARKER, siehe
# csv:asmark-* in Lisp/export.lsp). Der Marker sitzt MITTIG auf dem
# Einfuegepunkt des Schleuselements und folgt dessen Drehung. Nur optisch
# relevant - Nachbarschaft/Zuordnung rechnen nicht mit dieser Groesse.
# Wirkt erst, wenn die Blockdefinition NEU angelegt wird: in einer Zeichnung,
# die ZZ_ASES_MARKER schon kennt, bleibt die vorhandene Groesse bestehen
# (Block ueber _PURGE entfernen, um sie neu zu erzeugen). Default 200.
ases_groesse_mm=200
[Boundingbox]
# Mindesthoehe (Z-Ausdehnung) der von export.lsp (csv:get-bbox, per
# vla-getboundingbox) ermittelten Bounding-Box. Flache 2D-Bloecke (Draufsicht)
# haben oft dz=0 - wird auf diesen Wert angehoben. Wert in mm. Default 1, falls
# nicht gesetzt.
bb_minimum_height_mm=1
# Feste Bounding-Box-Masse (mm) der synthetischen, beim Export erzeugten
# Elemente OHNE eigene Zeichnungsgeometrie: der ILS-Weichen an Kreisel-
# Beruehrpunkten sowie der ILS-Ein-/Ausschleuselemente an den GF/VF-Strecken-
# enden (lib/export_neighbors.py: compute_kreisel_touch_switches /
# compute_strecke_kreisel_schleus). Dieselben Masse dienen als feste
# Kollisionsbox der AS/ES-Elemente bei der Nachbarschaftspruefung Kreisel<->
# GF/VF (compute_neighbor_ids, statt der grossen Wrapper-Box).
# LAENGE liegt QUER zur Foerder-/Kreiselachse, BREITE laengs (siehe
# _oriented_box_aabb). Der Halbe-Box-Versatz der Schleuselemente gegenueber
# dem AS/ES-Koordinatensystem betraegt BREITE/2 entlang der Foerderachse.
# Defaults (falls nicht gesetzt): 250 / 100 / 30.
element_box_laenge_mm=250
element_box_breite_mm=100
element_box_hoehe_mm=30
# Feste Bounding-Box-Masse (mm) eines Separator-Symbols. Werden fuer die in
# einer VF_n/GF_n-Kette EINGEBETTETEN Separatoren gebraucht, die seit der
# Umstellung auf die "sepliste"-XDATA nicht mehr als eigene INSERT-Bloecke in
# der Zeichnung liegen (frueher wurden sie nur kurzzeitig als Kopie erzeugt,
# um sie zu nummerieren) - fuer sie kann vla-getboundingbox keine Box liefern,
# es gibt kein reales Objekt mehr. Ohne Box nehmen diese Separatoren an der
# Nachbarschafts-/Umlauf-Erkennung nicht teil (siehe lib/export_neighbors.py:
# compute_kreisel_umlauf/compute_sensor_zuordnung brauchen item["_bbox"]).
# Quelle der Masse: gemessenes Separator_SP-Symbol (Referenz-Export, achsen-
# paralleles Symbol ~210 x 150 mm Grundflaeche, 3D-Hoehe ~14 mm). LAENGE liegt
# laengs des Symbols (bei Drehung 0 entlang X), BREITE quer, HOEHE = Z. Die
# tatsaechliche Welt-AABB wird beim Export aus diesen Massen + der Symbol-
# Drehung berechnet (rotierte Box -> achsparallele Huelle). Defaults (falls
# nicht gesetzt): 210 / 150 / 14.
separator_box_laenge_mm=210
separator_box_breite_mm=150
separator_box_hoehe_mm=14
[Kreisel]
# Kreisel-Durchmesser (Antriebs-/Spannstation AN8/SP8) in mm. Quelle der
# Wahrheit ist data/json/component_defaults.json ("kreisel"."durchmesser",
# Default 800.0) - hier fuer Python gespiegelt (Aenderungen bitte an beiden
# Stellen nachziehen, siehe Hinweis oben bei [blockpattern]).
#
# Wird von lib/export_neighbors.py (kreisel_half_bboxes) benutzt, um die
# Bounding-Box jedes Kreisels bei der Kollisionspruefung in eine linke und
# eine rechte Haelfte zu teilen: AN8 (Antriebsstation) liegt lokal bei
# (radius, 0), SP8 (Spannstation) bei (radius+abstand, 0) - siehe
# KreiselInsert.lsp::draw-module - radius = durchmesser_mm/2 (Default 400mm).
# Die gesamte Geometrie ist symmetrisch um die lokale X-Achse (Y=0, die
# Linie durch beide Stationsmitten) - genau diese Linie trennt links/rechts.
durchmesser_mm=800
[Sensorzuordnung]
# Zuordnung von manuell platzierten Separator_SP/Scanner-Bloecken zu einem
# Kreisel/Eckrad, einer VarioFoerderer-Streckengruppe (VF_*) oder einer
# Gefaellestrecke (GF_*) - siehe Lisp/count_sep_scan.lsp (cs-zuordnung-lauf).
# Laeuft automatisch vor jedem CSV-/Sivas-Export (Lisp/export.lsp,
# csv:run-export) und schreibt ANZAHL_SEPARATOR/ANZAHL_SCANNER am
# Kreisel/VF/GF sowie ZUORDNUNG (= ID des zugeordneten Elements) am Sensor.
# Toleranzrand (mm) um die Carrier-Boundingbox: Sensoren knapp ausserhalb
# gelten noch als "innerhalb". 0 = exakte Box.
senstol_mm=0
# Scanner (und Separatoren) ausserhalb JEDER Carrier-Boundingbox ohne
# vorhandenes ZUORDNUNG-Attribut werden per Abstand dem naechstgelegenen
# Kreisel/VF/GF zugeschlagen. Liegt der Abstand zum zweitnaechsten
# Kandidaten hoechstens strittig_diff_mm ueber dem des naechsten, gilt die
# Zuordnung als unsicher ("strittig"): sie wird trotzdem geschrieben, aber
# als Warnung im CSV-Export (Spalte "Warnungen") und in der BricsCAD-Konsole
# ausgegeben. Wert in mm.
strittig_diff_mm=500