Files
dxfmakros/CLAUDE.md
T
s.ayadi 7242e815f8 HundM05-Testfall und DXF-Analyse-Skripte
- lib/dxf_scan_components.py: erkennt ILS-/Omniflo-Komponenten in fremden
  Projektzeichnungen und schreibt sie im Testdaten-JSON-Schema aus
- lib/dxf_abbild.py: getreue Abbildung der Bauteile einer Fremdzeichnung
  (Attribute, Weltkoordinaten, Unterkomponenten) ohne Interpretation
- tests/test_hundm05.{lsp,py}, testdata/hundm05.json, conftest-Fixtures und
  alltests.json-Eintrag fuer den Kreisel-Abschnitt aus ST500592_05.dxf
- menu: TEST_HUNDM05 im Testmenue, Connection_Insert/Edit in SSG_LIB.cui
- Doku: hartkodierte Pfade durch (getenv "DXFMAKRO") ersetzt

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-24 12:10:58 +02:00

13 KiB
Raw Blame History

dxfmakros - Projektanweisungen

Projektbeschreibung

AutoLISP-Makros (SSG_LIB) fuer BricsCAD Pro zur automatisierten Erstellung von Foerderanlagen-Layouts (ILS Kreisel, Omniflo, Variofoerderer, Geruest). Ziel ist der Ersatz proprietaerer Tools (Bihler Omniflo, Bihler Geruest, Ruledesigner) durch eigene parametrische Makros.

Technologie-Stack

  • CAD-System: BricsCAD Pro (AutoCAD-kompatibel)
  • Hauptsprache: AutoLISP (.lsp)
  • Hilfssprache: Python (Export-Skripte in lib/)
  • Datenformate: DXF/DWG (Bloecke), JSON (Komponentendaten), CSV (Export)
  • Dialoge: DCL (Dialog Control Language, in dcl/)
  • Menu: BricsCAD .mnu/.mnl Format (in menu/)

Projektstruktur

Verzeichnis Inhalt
Lisp/ AutoLISP-Makros und Kernbibliotheken
bin/ Hilfs-Skripte (setenv.bat, start_briscad.bat)
cfg/ Konfigurationsdateien
data/ JSON-Daten, DXF-Quellen, Block-Libraries
data/ils/ DWG-Bloecke fuer ILS-Kreisel/Eckrad (AN8, SP8, AP-Typen)
data/json/ Komponentendaten (Masse, Sivas-IDs)
data/block_libraries/ DXF Block-Libraries (ils_library.dxf)
dcl/ DCL-Dialogdefinitionen
doc/ Dokumentation, Entwicklungsplan
lib/ Python-Skripte (DXF-Bearbeitung, Export)
menu/ BricsCAD-Menudefinition (SSG_LIB.mnu, SSG_LIB.mnl)
tests/ Testskripte und Referenzdaten

Lademechanismus (Lazy Loading via MNL)

Das Laden der LISP-Module erfolgt ueber das Menuesystem. Voraussetzung ist, dass das Menue einmalig in BricsCAD geladen wurde (siehe unten: "Menue einrichten").

  1. BricsCAD laedt beim Start automatisch SSG_LIB.mnl (gleichnamige MNL-Datei zum Menue)
  2. Die MNL laedt alle Kern- und Feature-Module direkt per ssg-ensure
  3. ssg-ensure ueberspringt bereits geladene Module (Flag *ssg-<modul>-loaded*)

Menue einrichten (einmalig pro BricsCAD-Installation)

  1. bin/setenv.bat ausfuehren (setzt DXFM_LISP, DXFMAKRO u.a.)
  2. BricsCAD starten
  3. In der BricsCAD-Kommandozeile: _MENULOAD eingeben
  4. Im Dialog: menu/SSG_LIB.mnu auswaehlen und laden
  5. BricsCAD laedt automatisch SSG_LIB.mnl mit alle Module werden initialisiert

Alternativ per LISP-Kommandozeile in BricsCAD:

(command "_.MENULOAD" (strcat (getenv "DXFMAKRO") "/menu/SSG_LIB.mnu"))

Das Menue bleibt dauerhaft registriert. Nach einem Update der .mnu-Datei genuegt es, BricsCAD neu zu starten oder _MENULOAD erneut aufzurufen.

Voraussetzung

Umgebungsvariable DXFM_LISP muss gesetzt sein (via bin/setenv.bat). Die start_briscad.bat ruft setenv.bat auf und startet BricsCAD.

Modulzuordnung im Menue

Menue-Bereich Modul Befehle
Kreisel-Module KreiselInsert KreiselInsert, KreiselConnect, KreiselEdit, ILS_Eckrad
TRO Tro_Edit TRO_INSERT, TRO_EDIT
Zusatzmodul/Foerderer/Kurven SSG_LIB_Commands ILS_BTMT_, ILS_ETF_, ILS_K*, ILS_GK*
VarioFoerderer VarioFoerderer FOERDERANLAGE, VARIOFOERDERER_EDIT, Vario_Kette_Merge
Gefaellestrecke Gefaellestrecke GEFAELLESTRECKE, GEFAELLESTRECKE_EDIT
Omniflo (komplett) OmniModulInsert OMNI_APB_, OMNI_W, OMNI_AP, OMNI_TEF, OMNI_TV_, OMNI_EDIT
Export export EXPORTSIVAS, EXPORTCSV, CALLPYTHON
Konfiguration SSG_LIB_Commands SSG_DIM_SWITCH, SSG_SPRACHE
Doppelklick/Kontextmenue SSG_LIB_Commands SSG_BLOCKEDIT (dispatcht Kreisel->KreiselEdit, Omniflo->OMNI_EDIT, GF_->GEFAELLESTRECKE_EDIT, VF_->VARIOFOERDERER_EDIT)

Entfernte Legacy-Dateien

  • bin/startup.scr - Entfernt (war fuer /s Parameter)
  • bin/acaddoc.lsp - Entfernt (war fuer ACAD-Pfad-basiertes Laden)
  • bin/on_start.lsp - Entfernt; Menue wird jetzt manuell per _MENULOAD eingerichtet

Detaillierte Dokumentation aller Funktionen und Befehle: siehe Lisp/README.md.

AutoLISP-Module

Datei Befehle Beschreibung
ssg_core.lsp - Kernel: ssg-start/ssg-end, ssg-cfg-or, ssg-attrib-read/write, Layer/Block-Ops
ssg_lang.lsp - Sprachumschaltung Deutsch/Englisch (ssg-text, ssg-textf, ssg-lang)
ssg_dbg.lsp - Debug-Logging (dbgopen, dbgmsg, dbgflush, dbgclose)
ssg_dialog.lsp - DCL-Dialog-Vorlagen und Hilfsfunktionen
ssg_layer.lsp - Layer-Verwaltung
KreiselInsert.lsp KreiselInsert, KreiselConnect, KreiselRedraw, KreiselQuick, KreiselEdit, KreiselParams, KreiselLabelSetup, KreiselLabelPos, KreiselLabelHoehe, ILS_Eckrad ILS Kreisel und Eckrad komplett in AutoLISP
VarioFoerderer.lsp (Wrapper fuer vf_core.lsp/vf_standard.lsp/vf_etage.lsp/vf_linienzug.lsp) FOERDERANLAGE, VARIOFOERDERER_EDIT, VARIOFOERDERER_NACHRUESTEN, Vario_Kette_Merge Vario-Foerderanlagen Generator (Typen Standard/Etage/Linienzug); Standard- UND Etage-Typ: Werteingabe per DCL-Dialog (vfs-standard-dialog-ablauf in vf_standard.lsp bzw. vfe-etage-dialog-ablauf in vf_etage.lsp, beide nutzen dieselben Dialoge vfs-dialog-eingabe-basis/vfs-dialog-winkel-verteilung); Doppelklick auf VF_n-Block ruft VARIOFOERDERER_EDIT, das per SSG_VF_EDIT-XDATA-Marker ("standard"/"etage") in den passenden Neuaufbau-Zweig dispatcht (vfe-edit-ent fuer Etage); Linienzug-/Altbestand-Bloecke ohne Marker werden abgewiesen; Vario_Kette_Merge (in vf_linienzug.lsp) fuehrt mehrere einzeln gebaute VF_n-Bloecke ab einem gewaehlten Start-Baustein ueber die reale KS_AUS->KS_EIN-Nachbarschaft zu einem Gesamt-Block zusammen (aggregierte Attribute, Luecken-Erkennung)
Gefaellestrecke.lsp GEFAELLESTRECKE, GEFAELLESTRECKE_EDIT Gefaelle-Foerderanlage (AUS -> Staustrecke skaliert -> Separator -> EIN); Modus 1 per DCL-Dialog (Einfuegehoehe, Element-Winkel 30/90); Doppelklick auf GF_n-Block ruft GEFAELLESTRECKE_EDIT (Dialog vorbelegt, Neuaufbau)
export.lsp EXPORTSIVAS, EXPORTCSV, OMNI_UPDATE_ATTRIBS JSON-Sammlung und Python-Export (Omniflo-Merkmale/Sum-Zeile via lib/export_csv.py)
OmniModulInsert.lsp OMNI_LOAD, OMNI_APB_, OMNI_W*, OMNI_AP60/AP110, OMNI_TEF, OMNI_TV_, OMNI_APBW_*, OMNI_EDIT Omniflo-Komponenten: Boegen, Weichen, Verbinder, Transferwagen, Edit-Dialog
SSG_LIB_Commands.lsp ILS_BTMT_Beladung, ILS_BTMT_Entladung, ILS_SCANNER_INSERT, ILS_SEPARATOR_INSERT, ILS_ETF_, ILS_K, ILS_GK*, SSG_BLOCKEDIT, SSG_DIM_SWITCH, SSG_SPRACHE BTMT Be-/Entladung (ils-insert-station: wiederholtes Einfuegen von BTMT-Beladung bzw. SC_Entladung, Drehung interaktiv, Layer aus LAYER-Attribut, Dimension via ssg-ils-block-laden) + Sensoren (ils-insert-sensor) + Dummy-Befehle fuer Menue + Doppelklick/Kontextmenue-Dispatcher + Konfiguration (2D/3D, Sprache)
Tro_Edit.lsp TRO_INSERT, TRO_EDIT TRO-Marker (Block TRO_SYM_<Typ>) fuer sps_skel (lib/tro_annotate.py): TRO_INSERT fuegt eine bestehende Blockdefinition an einem gewaehlten Punkt ein und setzt ID/TYPE (bricht ab, wenn der Typ noch keine Blockdefinition in der Zeichnung hat - die entsteht nur ueber tro_annotate.py); TRO_EDIT aendert ID/TYPE eines bestehenden Markers per Dialog. Typliste aus tro_types.lsp (von tro_annotate.py --emit-lisp nach DXFM_LISP geschrieben). Der Dispatcher SSG_BLOCKEDIT leitet Blocknamen TRO_* zu TRO_EDIT.
menu-inventory.lsp MenuInventory BricsCAD Diagnostik (Menuegruppen, Plugins, Startdateien)

DCL-Dialoge

Datei Verwendet von
kreisel_edit.dcl KreiselEdit (KreiselInsert.lsp)
gefaellestrecke.dcl GEFAELLESTRECKE Modus 1 (Gefaellestrecke.lsp, gf-dialog-eingabe)
variofoerderer.dcl FOERDERANLAGE Standardfall + Werteingabe (vf_standard.lsp, vfs-dialog-eingabe-basis/vfs-dialog-winkel-verteilung)
omniflo_boegen.dcl OMNI_APB_* (OmniModulInsert.lsp)
omniflo_weichen.dcl OMNI_W*_* (OmniModulInsert.lsp)
sprache.dcl SSG_SPRACHE (SSG_LIB_Commands.lsp)
tro_insert.dcl TRO_INSERT (Tro_Edit.lsp)
tro_edit.dcl TRO_EDIT (Tro_Edit.lsp)

Menue (SSG_LIB.mnu + SSG_LIB.mnl)

  • SSG_LIB.mnu - Menuedefinition mit Lazy-Loading ((ssg-ensure "Modul") Befehl)
  • SSG_LIB.mnl - Automatisch geladen mit dem Menue, definiert ssg-ensure Loader
  • ***MENUGROUP=SSG_LIB - Menuegruppenname
  • ***POP1 - Hauptmenue (ILS, Omniflo, Export, Konfiguration)
  • ***DOUBLECLICK - Doppelklick auf INSERT-Bloecke ruft SSG_BLOCKEDIT auf
  • ***POP501 - Rechtsklick-Kontextmenue (KreiselEdit, OMNI_EDIT, SSG_BLOCKEDIT)

Umgebungsvariablen

Werden via bin/setenv.bat gesetzt. Wichtigste:

  • DXFMAKRO - Projektwurzel
  • DXFM_LISP - Pfad zu Lisp-Dateien (benoetigt fuer ssg-ensure Lazy-Loader)
  • DXFM_BLOCKS - Pfad zu DWG-Bloecken
  • DXFM_DATA - Datenverzeichnis (JSON, DXF)
  • DXFM_LOG - Log-Verzeichnis
  • DXFM_DCL - Pfad zu DCL-Dialogdateien
  • DXFM_CFG - Konfigurationsverzeichnis
  • DXFM_LANG - Aktive Sprache (de_DE/en_GB), persistiert von SSG_SPRACHE; Default de_DE

Konventionen

  • AutoLISP-Funktionsnamen: ssg-* fuer Kernfunktionen, C:BEFEHLSNAME fuer User-Commands
  • Alle Texte in Dateien ohne Umlaute (ae, oe, ue statt ae, oe, ue)
  • Bloecke werden als DWG flach in data/ils/ abgelegt (Block-Libraries als DXF in data/block_libraries/). Die Dimension steckt seit dem Flach-Refactor im Dateinamen bzw. Blocknamen als Suffix _2D/_3D (z.B. AN8_2D.dwg, Vario_Bogen_auf_3_TEF_rechts_3D.dwg), damit 2D- und 3D-Variante gleichzeitig in einer Zeichnung stehen koennen. Zentrale Aufloesung: ssg-ils-blockname[-dim] / ssg-ils-block-datei[-dim] / ssg-ils-block-laden[-dim] in ssg_core.lsp. Ausnahmen ohne Suffix: KS_EIN/KS_AUS/K1-K4 und die Wrapper-Bloecke VF_*/GF_*/KREISEL_*/ECKRAD_*. Alle Feature-Module (Kreisel, VarioFoerderer, Gefaellestrecke) folgen der aktuellen Dimension (ssg-ils-dim-aktuell: transienter Override *ssg-ils-dim* -> DXFM_DIM) mit automatischem 3D-Fallback, sodass 2D- und 3D-Aufbau funktionieren. (Die alten Unterordner data/ils/2D und data/ils/3D bleiben uebergangsweise als Quelle der Batch-/Attribut-Tools bestehen.)
  • Komponentendaten (Masse, Sivas-IDs) liegen als JSON in data/json/
  • Sprache im Code und Kommentaren: Deutsch

Python-Bibliotheken

Standalone-Skripte (lib/) - laufen extern mit ezdxf

Abhaengigkeiten: ezdxf, Standard-Library. Benoetigen Umgebungsvariablen (DXFM_DATA, DXFM_RESULTS, DXFM_CFG).

Skript Beschreibung
omniflo_utils.py Gemeinsame Hilfsfunktionen fuer Omniflo-Skripte: ROW_GROUPS (Reihen-Gruppierung), SWITCH_FILTERS (Schalter-Filter), build_row_layout, import_element_as_block, draw_cross, load_omniflo_data
set_einfuegepkt.py Setzt $INSBASE (Einfuegepunkt) in Omniflo-DXF-Dateien. Schalter je Typ: --boegen, --weichen45, --weichen90, --weichenkoerper, --weichen-parallel, --delta, --dreifachweiche, --sternweiche, --show-omniflo
set_koords.py Setzt Koordinatensystem-Bloecke (K1-K4) in Omniflo-DXF-Dateien. Schalter: --k1set bis --k4set, --set-all, --force, --show-omniflo, --test, --number
export_sivas.py Erzeugt Sivas-Export-CSV mit Summierungszeilen (ILS Automation, Omniflo Sum). Aufruf: python export_sivas.py <export_raw.json> <data_dir> <output.csv>
export_csv.py Erzeugt einfache Item-Liste als CSV (ohne Summierung). Aufruf: python export_csv.py <export_raw.json> <data_dir> <output.csv>
split_block_library.py Teilt ils_library.dxf in einzelne DXF-Dateien pro Block auf (mit Abhaengigkeiten). Export-Prefixe: Vario_, Staustrecke_, 3D_AS, 3D_ES
dxf_scan_components.py Erkennt ILS-/Omniflo-Komponenten in einer fremden Projektzeichnung (ohne unsere Wrapper-Bloecke) und schreibt sie im JSON-Schema aus tests/testdata/object_data.md — Grundlage fuer Nachbau-Testfaelle wie tests/testdata/hundm05.json. Liest binaere DXF im GB-Bereich streamend per mmap (ezdxf-DOM waere zu gross), loest INSERTs inkl. OCS/Extrusionsrichtung rekursiv in Weltkoordinaten auf, paart AN8/SP8 zu Kreiseln und Antrieb/Umlenkung zu Foerderern. Aufruf: python dxf_scan_components.py <dxf> <data_dir> <output.json> [--fenster X0 Y0 X1 Y1] — ohne --fenster liefert eine Anlagenzeichnung leicht ueber 1300 Eintraege, zuviel fuer einen Testlauf

Entwickler-Tools (lib/) - kein ezdxf, reine Text-/AutoLISP-Verarbeitung

Skript Beschreibung
dbg2lsp.py Instrumentiert AutoLISP-Funktionen automatisch mit ssg_dbg.lsp (dbgf/dbg/dbgreturn/dbgopen/dbgclose). Schalter: --method (Funktion instrumentieren), --recursive (Aufrufgraph mitverfolgen), --add-open DATEI METHODE (Debug-Datei oeffnen/schliessen), --dry-run. Details: doc/dbg2lsp.md

Typische Verarbeitungskette (Omniflo-DXF)

  1. set_einfuegepkt.py - Einfuegepunkte berechnen und setzen
  2. set_koords.py - Koordinatensysteme (K1-K4) setzen
  3. export_sivas.py / export_csv.py - Export aus Zeichnung

Entwicklungsstand

Siehe doc/Entwicklungsplan.md fuer Meilensteinplanung und Aufwandsschaetzung. Fertig (DONE): ILS Kreisel, ILS Eckrad, ILS Variofoerderer, ILS BTMT Be-/Entladung (Einfuegen), Omniflo Boegen, Omniflo Weichen.

Debug

Wenn Werte für das Debug in der Bricscad Konsole ausgegeben werden z.B. mit princ, soll der Benutzer dazu ermuntert werden, statt dessen die Lisp dbg Routinen zu verwenden, welche dann eine .dbg file im log folder erzeugen. Diese können ja über eine zentrale globale Sammlung von Schalter an und abgeschaltet werden, so dass die Files per default auch nicht geschrieben werden, nur wenn der passende Schalter auf 1 gesetzt wird. Damit können debug aufrufe auch im Code verbleiben. Biete diese Architektur jeden an, der viele Werte ins Bricscad Fenster raus schreibt.