Files
dxfmakros/Lisp
..
2026-10-09 16:30:07 +02:00

Lisp – AutoLISP-Bibliotheken (SSG_LIB)

AutoLISP-Routinen für BricsCAD Pro zur automatisierten Erstellung von Förderanlagen-Layouts. Destilliert aus den historischen ACADSST-Makros (Schönenberger Systeme GmbH) und erweitert für die SSG_LIB-Befehle.


Menue einrichten und Module laden

Module werden automatisch ueber SSG_LIB.mnl geladen, sobald das Menue einmalig in BricsCAD registriert wurde:

Einmalige Einrichtung (BricsCAD-Kommandozeile):

_MENULOAD   →  menu/SSG_LIB.mnu auswaehlen

BricsCAD laedt daraufhin automatisch SSG_LIB.mnl, welches alle Module per ssg-ensure initialisiert. Kern-Reihenfolge (muss vor den Feature-Modulen stehen): ssg_core, ssg_lang, ssg_dbg, ssg_dialog, ssg_layer, ssg_id, ssg_ks_insert (Letzteres wird von Gefaellestrecke UND VarioFoerderer genutzt). Details: siehe ../CLAUDE.md Abschnitt "Lademechanismus".

Manuell laden (Notfall / Entwicklung, z.B. fuer .scr-Testskripte):

(load (strcat (getenv "DXFMAKRO") "/Lisp/ssg_load.lsp"))

ssg_load.lsp ist der Headless-Loader (genutzt von tests/test_unit.scr u.ae.) und laedt dieselbe Kern-Reihenfolge wie SSG_LIB.mnl, ohne Menueabhaengigkeit.


Status: noch offene Menueintraege (im Menue ausgegraut)

Die folgenden Menueintraege rufen aktuell nur eine Dummy-Funktion auf (Meldung [DUMMY], keine Geometrie). Sie sind in menu/SSG_LIB.mnu mit ~ ausgegraut und werden erst bei echter Implementierung wieder aktiviert. Der ~-Marker steht am Label-Anfang, bei Submenue-Schliessern hinter dem <- ([<-~Label]).

Menuebereich Eintraege Definiert in
Omniflo ▸ Anbaugruppen OMNI_KettenFoerderer OmniModulInsert.lsp
Omniflo ▸ Verbinder alle OMNI_TV_* (18) OmniModulInsert.lsp
Omniflo ▸ Boegen fuer Weichen alle OMNI_APBW_* (14) OmniModulInsert.lsp
ILS ▸ Zusatzmodule/Kurven ILS_ETF_Etagenfoerderer, ILS_K{90,60,30}{L,R}{A,I} (12), ILS_Gefaellestrecke SSG_LIB_Commands.lsp
Geruest GERUEST (Gattertraeger-Platzhalter, derselbe Befehl wie Saeulen/Rohrabhaenger/Wandbefestigung) GeruestInsert.lsp

OMNI_TEF_* (UmlenkR/L, AntriebL/R, TEF Gerade) sind entgegen frueherem Stand implementiert (echtes omni:insert-dxf), nur OMNI_KettenFoerderer ist weiterhin Dummy.

Aktiv (implementiert) sind u.a.: Kreisel, Eckrad, VarioFoerderer (Standard/Etage/ Linienzug), Gefaellestrecke, Geruest (Saeulen/Rohrabhaenger/Wandbefestigung/ Rohr-Geruest-Traeger), TRO-Marker, Connections, BTMT Be-/Entladung, Scanner/ Separator, Omniflo Boegen (APB)/TEF-Elemente/Aluprofil-Geraden (AP)/alle Weichen (W90/W45/WP/WK/WKomb)/Ladeschleifen, Export (Sivas/CSV), Werkzeuge (Block-/ Text-Tools, Planquadrate) und die Tests.


Dateien

ssg_core.lsp – Kernbibliothek

Grundfunktionen für Umgebungssicherung, Benutzerinteraktion, Layer, Blöcke, Attribute und JSON-Konfiguration. Muss als erstes geladen werden.

Umgebungssicherung:

Funktion Beschreibung
ssg-start titel vars Systemvariablen sichern, CMDECHO aus, Undo-Gruppe öffnen
ssg-end Systemvariablen wiederherstellen, Undo-Gruppe schließen
ssg-errhan em Fehlerhandler – räumt auf und ruft ssg-end auf

Benutzer-Abfragen:

Funktion Beschreibung
ssg-ques text defa Ja/Nein-Abfrage; defa=T → Default Ja, nil → Default Nein
ssg-emsg text Fehlermeldung mit optionalem Signalton (ssg-bell)

Layer-Hilfsfunktionen:

Funktion Beschreibung
ssg-get-layer text Layer eines angeklickten Objektes ermitteln
ssg-layer-ss name typ Auswahlsatz aller Objekte eines Layers (optional nach Typ filtern)
ssg-make-layer name farbe aktiv Layer anlegen (falls nicht vorhanden) und optional aktivieren
ssg-ss-foreach ss func Iteration über Auswahlsatz – func für jeden Entity-Name
ssg-ss-redraw ss modus Auswahlsatz hervorheben (3), invertieren (4) oder normal (0)
ssg-ss-add src dest Auswahlsatz src zu dest hinzufügen (in-place, mit Highlight)

Ziel-Layer je Baugruppe (cfg/layer.cfg):

Für Baugruppen, die ein Makro aus Einzelteilen zusammenbaut (KREISEL_n, ECKRAD_n, VF_n, GF_n) und für die selbst gezeichnete Hilfsgeometrie (Kreisel-Tangenten, PIN-Linien, Beschriftungstexte) gibt es keine Blockdatei in data/ und damit kein LAYER-Attribut – ihr Ziel-Layer und die Layerfarbe kommen aus cfg/layer.cfg. Nur eingefügte Blöcke nehmen dagegen ihr LAYER-Attribut als Vorgabe. Alle Funktionen liefern nil, wenn nichts konfiguriert ist; der Layer bleibt dann unangetastet (kein Fehler bei fehlender cfg/layer.cfg).

Funktion Beschreibung
ssg-layer-cfg-load cfg/layer.cfg einmalig (lazy) einlesen, Rückgabe ini-Alist oder nil
ssg-layer-cfg-reset Ladezustand verwerfen (cfg in laufender Sitzung neu einlesen, Tests)
ssg-layer-cfg-eintrag ini sektion key Reine Aufl./Zerlegung "Layername, Farbe" → (layer . farbe); Farbe fehlt → "7"
ssg-layer-eintrag key Ziel-Layer einer Baugruppe: [ils_<Dimension>] → [allgemein] → nil
ssg-layer-anlegen key aktiv Layer der Baugruppe mit cfg-Farbe anlegen, optional aktivieren; Rückgabe Layername
ssg-layer-setzen ent key Blockreferenz auf den Ziel-Layer ihrer Baugruppe legen (Layer wird angelegt)
ssg-layer-farbe-fuer-name name Farbe zu einem Layernamen (Abschnitt [farben], sonst passender Baugruppen-Wert, sonst "7")
ssg-block-layer-vorgabe ent blockname attribs Layer einer nur eingefügten Referenz aus der Block-Vorgabe: LAYER-Attribut → ssg-ils-block-ebene → nichts

Die Farbe greift nur bei der Neuanlage eines Layers – ssg-make-layer lässt bestehende Layer unverändert. Layer, die eine Blockdatei aus data/ils selbst mitbringt (z. B. ILS_SP), legt BricsCAD bereits beim Einfügen des Blocks mit der Farbe aus der DWG an; dort wirkt die cfg-Farbe nicht, der Layername des Wrappers aber schon.

Block-Operationen:

Funktion Beschreibung
ssg-timestamp Zeitstempel als YYYYMMDDHHMMSS-String erzeugen
ssg-make-blockname pt Eindeutigen Blocknamen aus Einfügepunkt + Zeitstempel erzeugen
ssg-insert-block layer farbe pfad pt xs ys rot Layer anlegen und Block einfügen
ssg-make-block pt rotation ss Auswahlsatz als Block definieren und gleich einfügen

ILS-Blockdateien laden (2D/3D):

Funktion Beschreibung
ssg-ils-dim-aktuell Gültige Dimension: *ssg-ils-dim* → DXFM_DIM → "3D"
ssg-ils-blockname[-dim] roh [dim] Effektiver Blockname mit Suffix _2D/_3D
ssg-ils-block-datei[-dim] roh [dim] Pfad zu data/ils/<blockname>.dwg (3D-Fallback)
ssg-ils-block-laden[-dim] roh [dim] Blockdefinition sicherstellen; Rückgabe = effektiver Name
ssg-block-refresh-reset roh Redefine-Sperre lösen (nil = alle Blöcke) → DWG wird neu gelesen

Jede Block-DWG wird einmal pro Zeichnung aus der Datei neu definiert (Redefine); danach greift eine Sperre (*ssg-block-refreshed*, siehe ssg-block-refreshed-p/ -set). Ohne sie las jede einzelne Element-Einfügung die DWG erneut von der Platte und regenerierte alle bereits platzierten Referenzen – bei den großen 3D-Blöcken (AS_Element_90_links_3D ~52 MB) waren Tests wie TEST_MUBEA dadurch minutenlang beschäftigt. Wurde eine Block-DWG während der laufenden Sitzung geändert, hebt ssg-block-refresh-reset die Sperre auf.

Attribut-Operationen:

Funktion Beschreibung
ssg-attrib-set tag wert ersetzen Ein Attribut der letzten Einfügung setzen oder anfügen
ssg-attrib-set-many alist Mehrere Attribute der letzten Einfügung auf einmal setzen
ssg-attrib-set-on ent alist Attribute eines bestimmten INSERT-Entity setzen (nicht entlast)
ssg-attrib-read ent Alle Attribute eines INSERT-Entity als Assoziationsliste lesen
ssg-attrib-read-dwg pfad Block temporär einfügen, ATTRIBs lesen, Block wieder löschen
ssg-attrib-defaults defs Default-Attribute aus Definitionsliste ((TAG DEFAULT) ...) erzeugen
ssg-attrib-merge given defs Übergebene Attribute mit Defaults zusammenführen
ssg-attrib-make-defs defs hoehe Unsichtbare ATTDEF-Entities erzeugen (für Block-Definition)
ssg-attrib-alist-to-defs alist Assoziationsliste (TAG . Wert) in ATTDEF-Definitionsliste umwandeln
ssg-attrib-by-handle handle tag wert ersetzen Attribut eines Blocks anhand seines Entity-Handles suchen und ändern

Dialog-Hilfsfunktionen:

Funktion Beschreibung
ssg-dialog-run dcl id init-fn accept-fn Generischer DCL-Dialog: laden, initialisieren, starten, entladen

Zoom-Hilfsfunktionen:

Funktion Beschreibung
ssg-zoom-save Aktuelle View-Größe merken
ssg-zoom-restore Auf gemerkte View-Größe zurückschalten (nur wenn verändert)

JSON-Konfigurationssystem:

Liest data/json/component_defaults.json beim Laden über ssg-load-config. Die Config wird in der globalen Variable *ssg-config* gehalten.

Funktion Beschreibung
ssg-load-config Config aus $DXFM_DATA/json/component_defaults.json laden
ssg-cfg section key Wert aus Config lesen, nil wenn nicht vorhanden
ssg-cfg-or section key default Wert aus Config lesen, default als Fallback

Interne Parser-Funktionen (nicht direkt aufrufen): ssg-read-file-lines, ssg-cfg-trim, ssg-cfg-split-comma, ssg-cfg-parse-value, ssg-cfg-parse-array, ssg-cfg-parse-kv, ssg-cfg-parse-nested


ssg_lang.lsp – Sprachumschaltung (Deutsch/Englisch)

Zentrale Textverwaltung fuer benutzersichtbare Meldungen. Kern-Modul, wird direkt nach ssg_core geladen. Wird schrittweise auf weitere Module ausgerollt (siehe doc/plan/translate.md).

Funktion Beschreibung
ssg-text key Liefert Text zu key in *ssg-lang*, Fallback de_DE, dann Key selbst
ssg-textf key werte Wie ssg-text, ersetzt Platzhalter %1 %2 ... durch werte (Liste)

Sprache umschalten: Befehl SSG_SPRACHE (Menue → Konfiguration → Sprache) setzt *ssg-lang* live und persistiert via (setenv "DXFM_LANG" ...). Default ohne DXFM_LANG ist "de_DE".


ssg_dbg.lsp – Debug-Logging

Dateibasiertes Debug-Log mit gepuffertem Schreiben. dbgf/dbg/dbgmsg puffern im Speicher, dbgreturn flusht auf die Platte (open/append/close).

Funktion Beschreibung
dbgopen filename envvar Debug-Datei öffnen (Verzeichnis via Umgebungsvariable, z.B. "DXFM_LOG")
dbgclose Puffer schreiben und Datei schließen
dbgon Debug-Ausgabe aktivieren
dbgoff Debug-Ausgabe deaktivieren (verhindert Dateianlage wenn vor dbgopen)
dbgf funcname Funktionseintritt loggen, Einrückung erhöhen
dbgreturn retval Funktionsaustritt loggen, Puffer flushen, Rückgabewert durchreichen
dbg varname Variable oder Wert loggen: (dbg 'x) oder (dbg wert)
dbgmsg text Freitext-Nachricht loggen
dbgp text Alias für dbgmsg
dbgflush Puffer sofort schreiben (ohne dbgreturn, z.B. in Startup-Code)

Beispiel:

(dbgopen "test.dbg" "DXFM_LOG")
(dbgf "meine-funktion")
(dbg 'x)
(dbgreturn ergebnis)   ; schreibt Puffer auf Platte
(dbgclose)

Zentrale Debug-Schalter (default je nach Schalter)

Damit dbg*-Aufrufe dauerhaft im Code stehen bleiben können, ohne im Normalbetrieb ungeplant .dbg-Dateien zu erzeugen, gibt es eine zentrale Schalter-Sammlung (*dbg-schalter*, Symbol → 0/1). Eine Routine öffnet ihre Debug-Datei nur, wenn ihr Schalter eingeschaltet ist. Unbekannte/neue Schalter gelten implizit als 0/aus; die VF-Linienzug-Schalter unten sind bewusst mit Default 1/an vorregistriert (siehe Tabelle).

Funktion Beschreibung
dbg-schalter-on name Schalter name einschalten (1)
dbg-schalter-off name Schalter name ausschalten (0)
dbg-schalter-p name T wenn eingeschaltet, sonst nil
dbg-schalter-open name filename envvar Öffnet die Datei nur wenn Schalter=1; gibt T/nil zurück
dbg-schalter-liste Alle bekannten Schalter + Zustand ausgeben

Bekannte Schalter:

Schalter Default Modul Loggt nach
"vfl-modus1" AN (1) Linienzug Modus 1 (manuelle Eingabe, vf-linienzug-modus) DXFM_LOG/vfl_modus1.dbg
"vfl-modus2" AN (1) Linienzug Modus 2 (3D-Objekte + Ziel-Höhe, vf-linienzug-modus2) DXFM_LOG/vfl_modus2.dbg
"vfl-modus3" AN (1) Linienzug Modus 3 (Vorwärts-Nachbau, vf-linienzug-modus3) DXFM_LOG/vfl_modus3.dbg

Alle drei Modi loggen automatisch jede interaktive Eingabe, weil sie durchgehend über die gemeinsamen Wrapper vfl-in-point/-string/-real/ -int/-value/-selection gehen, die zentral in vfl-journal-record protokolliert werden – keine einzelne Aufrufstelle im Bau-Ablauf musste dafür angefasst werden. Da der Default AN ist, wird bei jedem Aufruf von FOERDERANLAGE → linienzug ohne weiteres Zutun mitgeloggt; bei Bedarf einzeln abschaltbar mit (dbg-schalter-off "vfl-modus1") usw.

;; Standardmaessig bereits an - nur zur Kontrolle:
(dbg-schalter-liste)
;; ... FOERDERANLAGE -> linienzug -> Modus 1/2/3 durchspielen ...
;; -> Datei DXFM_LOG/vfl_modus<N>.dbg enthält Session + alle Eingaben
(dbg-schalter-off "vfl-modus1")   ; bei Bedarf einzeln abschalten

Muster in einer Routine:

(setq dbg-an (dbg-schalter-open "vfl-modus3" "vfl_modus3.dbg" "DXFM_LOG"))
(if dbg-an (dbgmsg "FRAGE: ..."))
;; ... get* ...
(if dbg-an (progn (dbgmsg "ANTWORT:") (dbg 'wert) (dbgflush)))
;; am Ende:
(if dbg-an (progn (dbgreturn ergebnis) (dbgclose)))

ssg_dialog.lsp – Dialog-Pattern für Modul-Einfüge-Makros

Kapselt das wiederkehrende DCL-Muster: Dialog mit Vorschaubild, Radio-Auswahl, Block einfügen, Attribute setzen. Setzt ssg_core.lsp voraus.

Funktion Beschreibung
ssg-dia-show-slide tile lib name Vorschau-Slide im image-Tile anzeigen (Hintergrundfarbe aus Config: infrastruktur/dialog_preview_bg_color)
ssg-dia-update-preview tile idx lib liste Vorschau anhand Index-String aus Radio-/List-Tile aktualisieren
ssg-modul-dialog dcl id sel-tile start-val prev-tile lib slides extra-init extra-read Vollständiger Modul-Dialog: lädt DCL, setzt Tiles, verknüpft Vorschau, liefert gewählten Index
ssg-insert-modul layer farbe pfad attribs rotation Standardsequenz: Layer anlegen → Punkt abfragen → Block einfügen → Attribute setzen

Die Datei enthält außerdem ein auskommentiertes Template für neue c:BEFEHL-Definitionen nach dem SSG-Muster.


ssg_layer.lsp – Interaktive Layer-Verwaltung

Benutzerfreundliche BricsCAD-Befehle für Layer-Operationen. Alle Befehle sichern die Umgebung über ssg-start/ssg-end. Setzt ssg_core.lsp voraus.

Hilfsfunktionen:

Funktion Beschreibung
ssg-layer-list-all Alle Layernamen als Liste
ssg-layer-info-all Alle Layer als Assoziationslisten (Name, Farbe, Linientyp, Flags)
ssg-layer-visible-p name Sichtbarkeitsstatus prüfen (T = sichtbar)
ssg-layer-safe-p name gruppe Prüfen ob Layer ausgeschaltet werden darf (nicht aktiver Layer)
ssg-layer-group name Gruppen-Kennung aus Layernamen extrahieren (Position 2–3)
ssg-layer-rename-group name neu Neuen Layernamen mit geänderter Gruppen-Kennung berechnen
ssg-layer-group-move alt neu Alle Objekte einer Layergruppe auf neue Gruppen-Kennung verschieben

BricsCAD-Befehle:

Befehl Beschreibung
c:SSG-LayerSet Layer des angeklickten Objektes als aktiven Layer setzen
c:SSG-LayerInfo Layer des angeklickten Objektes anzeigen
c:SSG-LayerMove Auswahlsatz auf Layer eines anderen Objektes verschieben
c:SSG-LayerCopy Auswahlsatz kopieren und Kopie auf Ziel-Layer legen
c:SSG-LayerMoveType Alle Objekte des gleichen Typs auf dem gleichen Layer verschieben
c:SSG-LayerOff Layer durch Anklicken ausschalten (Schleife bis Enter)
c:SSG-LayerFreeze Layer durch Anklicken einfrieren (Schleife bis Enter)
c:SSG-FreezeAll Alle Layer außer einem einfrieren
c:SSG-ThawAll Alle Layer auftauen
c:SSG-LayerOnAll Alle ausgeschalteten Layer einschalten
c:SSG-LayerDelete Layer mit Sicherheitsabfrage löschen (Objekte + Layer)

ssg_input.lsp – Generische Eingabe-Wrapper

Abfragen mit Vorgabewert (<..> im Prompt, Enter = Vorgabe). Steht neben den VF-spezifischen vfl-in-* (vf_linienzug.lsp); diese bleiben unveraendert. Kein Journal, aber ein optionaler Hook. ESC bricht wie ueblich ueber *error* ab.

Funktion Beschreibung
ssg-in-real text default Reelle Zahl (getreal), Vorgabe ohne ueberfluessige Nullen angezeigt
ssg-in-int text default Ganzzahl (getint)
ssg-in-string text default String mit Leerzeichen; Enter ohne Eingabe liefert die Vorgabe (ohne Vorgabe nil)
ssg-in-point text default base Punkt, base = Gummiband-Basispunkt oder nil
ssg-in-dist text default base Abstand (getdist)
ssg-in-keyword text schluessel default Schluesselwort im initget-Format, z.B. "Alle Auswahl"
ssg-in-yesno text default Ja/Nein, T = Ja; default T = Enter bedeutet Ja. Woerter aus ssg-text "in-yesno-keys"
ssg-in-default wert default, ssg-in-fmt-real, ssg-in-fmt-pt, ssg-in-prompt, ssg-in-first-word, ssg-in-second-word Reine Hilfsfunktionen (in tests/test_unit.lsp getestet)

Hook (z.B. fuer ein Eingabe-Journal): (setq *ssg-in-hook* 'meine-funktion) mit (defun meine-funktion (art prompt wert) ...); art ist "REAL", "INT", "STRING", "POINT", "DIST", "KEYWORD" oder "YESNO". Ein Hook, der einen Fehler wirft, wird abgeschaltet.


ssg_id.lsp – Eindeutige Block-IDs

Jedes exportierbare Element bekommt ein Attribut ID mit einer eindeutigen, vierstelligen Nummer. Kern-Modul (nach ssg_layer, vor ssg_ks_insert).

Befehl / Funktion Beschreibung
c:IDGENERATE Weist dem zuletzt eingefuegten Block eine neue ID zu
c:IDSCHECK Prueft alle Bloecke auf doppelte IDs und korrigiert sie
ssg-id-format n Zahl als 4-stelligen String formatieren (1 → "0001")
ssg-id-max Hoechste bereits vergebene ID in der Zeichnung
ssg-id-generate ent Neue ID erzeugen und auf den Block setzen
ssg-id-check-all Zeichnungsweit auf Doubletten pruefen und korrigieren
ssg-id-collect-blocks Alle ID-faehigen INSERT-Entities sammeln (gleiche Muster wie csv:collect-export-blocks, inkl. Separator/Scanner/BTMT)

ssg_ks_insert.lsp – KS-Extraktion und Block-Einfuegeprimitiven

Gemeinsame Basis fuer VarioFoerderer (vf_core.lsp) UND Gefaellestrecke – frueher in beiden Modulen dupliziert, jetzt einzige Quelle. Muss laut MNL vor Gefaellestrecke/vf_core geladen sein; Kern-Modul.

Funktion Beschreibung
vec-length v Laenge eines 3er-Vektors
ks-line-axis laenge Achsenkennung (X/Y/Z) aus Linienlaenge der KS-Hilfslinie
ks-normalize-name nm Historische KS-Blocknamen (KSYS_EIN/-AUS) auf KS_EIN/KS_AUS normalisieren
ks-relativize / ks-absolutize KS-Punkte zwischen relativem und Welt-Koordinatensystem umrechnen
ensure-block-loaded name Block aus der Bibliothek einmalig ins aktive Dokument laden
extract-ks-from-block[-raw] name KS_EIN/KS_AUS-Punkte eines Blocks ermitteln (Cache *ks-cache*)
insert-block-by-ks name ks-nr pt Block anhand KS-Punkt einfuegen (nur Rz-Rotation)
insert-inclined-scaled-block / insert-rotated-block-with-ks Geneigten/rotierten Block mit KS-Offset einfuegen (Rz*Ry)

ssg_blocktools.lsp – Block-Werkzeuge

Ursprung: ACADSST TOOLS.LSP (BLKANZAHL, BLKENTF), DINGEN2 (g-bli), ssg.lsp (suchen-aendern). Arbeitet im aktuellen Layout-Reiter. Blocknamen werden ueber den wirksamen Namen verglichen (dynamische Bloecke); Muster mit wcmatch (*, ?, #, ohne Gross-/Kleinschreibung).

Befehl Beschreibung
SSG_BLOCK_COUNT Block anklicken, Name fuer ein Muster, oder Enter fuer eine Statistik aller Bloecke
SSG_BLOCK_DELETE Alle Einfuegungen eines Blocks/Musters loeschen; Rueckfrage (Vorgabe Nein), Einfuegungen auf gesperrten Layern bleiben stehen; eine Undo-Gruppe
SSG_ATTR_ERSETZEN Attributwerte suchen/ersetzen: Bereich (Alle mit Blockname-Muster / Auswahl), Tag-Muster, Suchtext, Ersatz, Modus Teil (Teilstring) oder Gesamt (ganzer Wert). Zeigt vorab die Anzahl und fragt nach
Funktion Beschreibung
ssg-bt-inserts muster Entity-Liste aller Einfuegungen im Layout (optional nach Muster)
ssg-bt-statistik muster ((NAME . ANZAHL) ...) alphabetisch
ssg-bt-attr-ersetzen-ent ent tag suche ersatz teil-p probe-p Attribute EINER Einfuegung ersetzen bzw. nur zaehlen (probe-p); Rueckgabe Anzahl
ssg-bt-attr-ersetzen-liste ents tag suche ersatz teil-p probe-p Dasselbe fuer eine Entity-Liste
ssg-bt-wert-neu wert suche ersatz teil-p Reiner Kern: neuer Wert oder nil (unveraendert); beachtet Gross-/Kleinschreibung
ssg-bt-name-passt-p, ssg-bt-zaehle-namen, ssg-bt-muster-escape Reine Hilfsfunktionen (getestet)

ssg_texttools.lsp – Text-Werkzeuge

Ursprung: ACADSST CHGTEXT.LSP, PARTEXT.LSP, ALTHOEHE.LSP, ALTSTIL.LSP. Laden nach ssg_blocktools (nutzt ssg-bt-wert-neu und ssg-bt-attr-ersetzen-liste). Arbeitet in der XY-Ebene des Welt-KS.

Befehl Beschreibung
SSG_TEXT_ERSETZEN Suchen/Ersetzen in TEXT, MTEXT und Block-Attributen; Bereich Alle (Layout) oder Auswahl; Vorschau mit Anzahl, Rueckfrage
SSG_TEXT_PARALLEL Linie/Polylinie/Bogen anklicken, Text wird parallel (lesbar, nie auf dem Kopf) mit Abstand gesetzt; Hoehe, Abstand und letzter Text werden fuer die Sitzung gemerkt; Enter beendet
SSG_TEXT_HOEHE Texthoehe gewaehlter TEXT/MTEXT aendern
SSG_TEXT_STIL Textstil gewaehlter TEXT/MTEXT aendern (Stil muss existieren)

Reine Kerne (getestet): ssg-tt-lesbarer-winkel (Winkel 90 Grad bis 270 Grad um 180 Grad drehen, Ergebnis in [0, 2 pi)), ssg-tt-versetzt.

Nicht uebernommen aus Walz: Export/Import von Texten (besser per Python/ezdxf), KREISTXT, TXTBOXED, CHTEXT/ASCTEXT/PTEXT (Autodesk 1990, durch BricsCAD-Standard ersetzt).


ssg_load.lsp – Laderoutine

Headless-Loader fuer .scr-Testskripte (z.B. tests/test_unit.scr). Laedt alle Kern- und Feature-Module in derselben Reihenfolge wie SSG_LIB.mnl, ohne Menueabhaengigkeit. Ermittelt den Pfad automatisch über findfile. Ruft direkt nach ssg_core.lsp die Funktion ssg-load-config auf, damit die JSON-Konfiguration für alle nachfolgenden Module verfügbar ist.


VarioFoerderer.lsp – Vario-Förderer (Wrapper)

Kompatibilitäts-Wrapper, der vf_core.lsp lädt (Plugin-Dispatcher-Architektur über *vf-typ-registry*; lädt seinerseits vf_konstanten.lsp, vf_standard.lsp, vf_etage.lsp, vf_linienzug.lsp, danach vf_spec.lsp). Parametrischer Generator für ILS Vario-Förderanlagen (Typen Standard/Etage/Linienzug). Liest Block-Geometrie aus einer DWG-Bibliothek (DXFM_BLOCKS) über die Primitiven aus ssg_ks_insert.lsp. Alle Konstanten (Abstände, Winkel, Skalierung) werden über ssg-cfg-or (component_defaults.json, Sektion vario) bzw. die zentralen *vfk-*-Konstanten aus vf_konstanten.lsp gelesen.

Befehl: c:FOERDERANLAGE / c:VarioFoerderer – wählt zuerst den Anlagen-Typ (Standard/Etage/Linienzug):

  • Typ „standard“ und „etage“ + Werteingabe: laufen über denselben, typ-parametrisierten Dialog-Ablauf (vf-dialog-ablauf in vf_core.lsp; vfs-standard-dialog-ablauf/vfe-etage-dialog-ablauf sind nur noch duenne Wrapper darauf) mit den Dialogen vfs-dialog-eingabe-basis/ vfs-dialog-winkel-verteilung (dcl/variofoerderer.dcl): Dialog 1 erfasst deltaL, Förderrichtung, Einfügehöhe/deltaH, Fahrtrichtung und Seite/Motorseite; Dialog 2 lässt Winkel und L_GF-Verteilung (vorne/hinten) wählen. Startpunkt (X/Y) wird vorher in der Zeichnung gepickt.
  • Typ „standard“/„etage“ + 3D-Linie laufen ueber denselben Basis-Dialog statt rein interaktiv auf der Konsole.
  • Typ „linienzug“ (Streckengruppe, vf-linienzug-modus in vf_linienzug.lsp) hat drei Modi (manuell/Wizard, 3D-Objekte+Zielhoehe, Vorwaerts-Nachbau) und zeichnet jede Eingabe in einem Journal auf (XDATA SSG_VF_EDIT am VF_n-Block); Standard laeuft per Default ueber DCL-Dialoge (VF_WIZARD_AN/VF_WIZARD_AUS schalten um). Details, Journal-Format, Headless-Modus (*vfl-headless*) und Spec-basierter Bau ohne Dialog (vf_spec.lsp, VF_SPEC_BAU): siehe ../doc/variofoerderer.md und ../CLAUDE.md.

Bearbeiten (c:VARIOFOERDERER_EDIT): Doppelklick auf einen VF_n-Block – bzw. Rechtsklick-Kontextmenü/SSG_BLOCKEDIT – dispatcht per XDATA-Marker ("standard"/"etage"/"linienzug") in den passenden Neuaufbau-Zweig (vfe-edit-ent fuer Etage, vfl-edit-ent fuer Linienzug) und öffnet dieselben Dialoge, vorbelegt mit den aktuellen Parametern; der Block wird am selben Startpunkt neu aufgebaut (neue VF_n-Nummer). Altbestand-Blöcke ohne Marker werden mit einer Meldung abgewiesen, statt sie zu verändern. Winkel und L_GF1 werden aus den Sivas-Attributen (VF_WINKEL, L_GF_m) vorbelegt.

Die Block-Einfuege-Primitiven (ensure-block-loaded, insert-block-by-ks, insert-inclined-scaled-block, insert-rotated-block-with-ks u.a.) sind seit der Konsolidierung zentral in ssg_ks_insert.lsp definiert (von vf_core.lsp, Gefaellestrecke.lsp und TEFInsert.lsp genutzt). Weitere interne Helfer: init-bibliothek (Block-Bibliothek aus DWG laden), get-line-start-end-points ename, punkt-differenz p1 p2.


Gefaellestrecke.lsp – Gefällestrecken-Generator

Erzeugt eine einfache Förderanlage mit festem Gefällewinkel: AUS-Element → Staustrecke (skaliert) → Separator → EIN-Element

Setzt VarioFoerderer.lsp voraus (nutzt dessen init-bibliothek, insert-block-by-ks und weitere Hilfsfunktionen). Alle Defaults (default_delta_l, default_winkel, separator_breite) kommen aus Config-Sektion gefaelle.

Befehl: c:GEFAELLESTRECKE

Drei Modi:

  • Modus 1: Startpunkt (X/Y) picken, restliche Parameter über den DCL-Dialog dcl/gefaellestrecke.dcl eingeben (ΔL, Einfügehöhe Z, Gefällewinkel, Fahrtrichtung, AUS-/EIN-Element je Winkel 30/90 und Seite links/rechts). Die Einfügehöhe aus dem Dialog setzt die Z-Koordinate des Startpunkts.
  • Modus 2: Bestehende 3D-Linie wählen (ΔL und Fahrtrichtung werden daraus berechnet), restliche Parameter interaktiv über die Kommandozeile.
  • Modus 3: Linienzug aus LINE-/ARC-Objekten; ARC-Segmente werden durch Gefällebogen-Blöcke ersetzt, Winkel aus ΔH und Geometrie berechnet.

Dialog-Hilfsfunktionen: gf-dialog-eingabe (lädt/liest den DCL-Dialog, liefert (deltaL winkel hz-winkel as-seite es-seite einfuegehoehe as-winkel es-winkel dim geruest-einzelmodul geruest-typ) oder nil bei Abbruch) und gf-modus12-abschluss (gemeinsamer Abschluss für Modus 1+2: setzt die Element-Masse per vf-set-as-masse/vf-set-es-masse, berechnet die Staustreckenlänge, zeigt die Zusammenfassung und ruft gefaellestrecke-einfuegen).

Die AUS-/EIN-Element-Varianten (30/90 Grad, links/rechts) liegen als DWG-Blöcke AS_Element_<30|90>_<links|rechts> bzw. ES_Element_… flach in data/ils/ (Dimension im Dateinamen als Suffix _2D/_3D, aufgelöst über ssg-ils-block-datei); ihre Maße werden direkt aus dem Block gemessen (vf-element-masse), es gibt dafür keine JSON-Tabelle.

Bearbeiten (c:GEFAELLESTRECKE_EDIT): Doppelklick auf einen Gefällestrecken-Block (GF_n) – bzw. Rechtsklick-Kontextmenü/SSG_BLOCKEDIT – öffnet denselben DCL-Dialog, vorbelegt mit den aktuellen Parametern, und baut die Strecke bei OK am selben Startpunkt neu auf. Damit Fahrtrichtung und Element-Winkel (30/90) verlustfrei rekonstruiert werden, schreibt gefaellestrecke-einfuegen diese beim Erstellen als XDATA (App SSG_GF_EDIT, Helfer gf-xdata-schreiben/gf-xdata-lesen) auf das GF_n-INSERT – bewusst nicht in den Sivas-Attributsatz, damit der Export unverändert bleibt. Ältere Blöcke ohne XDATA werden aus den Attributen vorbelegt (Fahrtrichtung 0°, Element-Winkel 90° als Vorgabe). Der Neuaufbau läuft über gf-rebuild (nicht-interaktiv, ohne Konsolen-Rückfrage).


TEFInsert.lsp – TEF-Geradenstuecke entlang einer Linie

Befehl: c:TEF_FOERDERER_LINIE. Zeichnet eine Linie zwischen zwei gewaehlten Punkten und reiht darauf 1000-mm-TEF-Geradenelemente (0_B10030 aus DXFM_OMNIFLO) aneinander; ist die Linienlaenge kein exaktes Vielfaches, wird ein zusaetzliches, zurueckverschobenes Element eingefuegt, sodass der Foerderer exakt am Linienende endet (keine Luecke, kein abgeschnittenes Element). Die Linie darf geneigt sein (3D) – Elemente werden dann analog zu vf_core.lsp/ssg_ks_insert.lsp (Rz*Ry-Rotation) gekippt eingefuegt. Nicht zu verwechseln mit den einzelnen OMNI_TEF_*-Befehlen in OmniModulInsert.lsp.


export.lsp – Export-Funktionen

Sammelt INSERT-Blöcke aus der Zeichnung und exportiert sie als JSON oder ruft Python-Skripte für den Sivas-Export auf.

Befehl / Funktion Beschreibung
c:EXPORTSIVAS Alle Blöcke als JSON sammeln und export_sivas.py aufrufen (Sivas-CSV)
c:EXPORTCSV Alle Blöcke als JSON sammeln und export_csv.py aufrufen (einfache Item-Liste, inkl. Omniflo Bogen/Weiche/Gerade und abschließender "Omniflo Sum"-Zeile)
csv:collect-export-blocks Alle INSERT-Blöcke der Zeichnung als JSON-Array sammeln
csv:run-export py-skript json-datei output-csv Python-Skript mit gesammelten Daten aufrufen; legt vorher fuer in VF_n/GF_n/KREISEL_n verpackte Separator_SP_2D/_3D-Sub-INSERTs (Sensor-Symbol; siehe ssg-collect-nested-inserts in ssg_core.lsp - NICHT der interne Staustrecke_Separator_SP-Trennsteg) je eine echte, temporaere Kopie an derselben Stelle an (csv:sep-proxies-erzeugen, Position/Drehung/Skalierung ueber alle Verschachtelungsebenen hinweg identisch zum Vorbild - kein kosmetischer Versatz mehr, der die geometrische Sensor-Zuordnung verfaelschen wuerde), damit sie ganz normal ueber ssg-id-check-all/csv:collect-export-blocks erfasst werden, und entfernt sie danach wieder (csv:sep-proxies-loeschen). Die verpackten AS-/ES-Schleuselemente derselben Kette bekommen stattdessen einen DAUERHAFTEN Marker (csv:asmark-aktualisieren, siehe unten); beide Wege teilen sich die Platzierungsrechnung (csv:nested-welt-records + csv:block-einfuegen-welt). Reihenfolge ist wesentlich: erst ssg-id-check-all (Wrapper-IDs endgueltig), dann die Kopien/Marker (ZUORDNUNG direkt beim Erzeugen), dann csv:ketten-verarbeiten (IDs in Kettenfolge, Separator-Typ, sepliste-Stellvertreter), dann ein zweites ssg-id-check-all (Restnummerierung)
csv:asmark-aktualisieren AS-/ES-Kettenenden sichtbar machen: setzt an jedes verpackte AS_Element*/ES_Element* einer VF_n/GF_n-Kette ein kleines Rechteck (Block ZZ_ASES_MARKER, Groesse aus cfg/export.cfg [Marker], Layer aus cfg/layer.cfg ases_marker), das nach dem Export stehen bleibt. Unsichtbare Attribute ID/ZUORDNUNG/TYP/LFDNR/ELEMENT/ARTINR; die ID fuellt ssg-id-check-all und der naechste Export uebernimmt sie, ein AS/ES behaelt seine TeileId also ueber Laeufe hinweg. Baut bei jedem Export alle Marker neu auf (Wiederfinden ueber ZUORDNUNG+TYP+LFDNR) und entfernt verwaiste
csv:ketten-verarbeiten sep-proxies element-proxies asmarks Je VF_n/GF_n aus DERSELBEN KS-geordneten Kette (csv:kette-von, einmal je Lauf berechnet): Einheiten-Proxies (group_vf_gf), IDs in Kettenfolge, Separator-Typ VF/GF (csv:kette-sep-typen -> *cs-sep-typ-by-handle*) und der Stellvertreter jedes sepliste-Eintrags (*csv-sepliste-id-by-handle*, Key = Wrapper-Handle; csv:block-to-json liest dessen ID beim Schreiben als Feld id)
csv:sepliste-kette-paare eintraege typen Zuordnung sepliste-Eintrag -> Kettenbaustein ueber die Reihenfolge je Typ (k-tes AS/SEP/ES der sepliste = k-tes der KS-Kette), ohne die (teils gespiegelten) sepliste-Koordinaten. Reine Rechenfunktion, getestet in tests/test_unit.lsp
csv:element-familien EINZIGE Tabelle Familie -> Blockmuster (pattern_nested_* aus cfg/export.cfg) fuer Suche (csv:pattern-nested-element) UND Klassifizierung (csv:element-teileart, darauf aufbauend csv:kette-typ)
csv:read-attribs ename Attribute eines INSERT als JSON-Objekt lesen
c:OMNI_UPDATE_ATTRIBS HOEHE/DREHUNG aller Omniflo-Elemente aus der Zeichnung aktualisieren

Der Omniflo-CSV-Export (Bogen/Weiche/Gerade, inkl. Merkmale-Aufbau und Sum-Zeile) läuft seit Entfernung von c:OMNI_EXPORT ausschließlich über c:EXPORTCSV → lib/export_csv.py (build_bogen_merkmale, build_weiche_merkmale, build_gerade_merkmale, build_omni_sum_merkmale).

Ausgabeordner: c:EXPORTSIVAS/c:EXPORTCSV schreiben immer nach DXFM_RESULTS. TEST_EXPORT_ALL (siehe tests/test_export_all.lsp) leitet waehrend des Testlaufs stattdessen nach DXFM_TESTOUT um, über die reine Lisp-Sitzungsvariable *export-test-override* (wird von csv:run-export zusaetzlich zu DXFM_RESULTS abgefragt und danach garantiert wieder auf nil zurueckgesetzt, auch bei einem Fehler, ueber vl-catch-all-apply).

Wichtig: Der Umweg über *export-test-override* ist bewusst gewaehlt und kein (setenv "DXFM_RESULTS" ...). In BricsCAD/AutoCAD schreibt (setenv ...) nicht nur in den Windows-Prozess, sondern dauerhaft in die Profil-Registry der Anwendung – der Wert überlebt damit jeden Neustart und jedes setenv.bat, bis er erneut per (setenv) überschrieben wird. Ein einziger (setenv "DXFM_RESULTS" ...)-Aufruf (z. B. ein frueherer, unvollstaendiger Testlauf) würde DXFM_RESULTS für alle künftigen Sitzungen unwiderruflich auf den Testordner umbiegen. Falls das bereits passiert ist, hilft nur ein manuelles (setenv "DXFM_RESULTS" "<richtiger Pfad>") in BricsCAD, um den Profil-Wert zu korrigieren.


tests.lsp – Testbefehle

Testbefehle für die Python-Integration. Export-Funktionen wurden in export.lsp ausgelagert.

Befehl Beschreibung
c:CALLPYTHON testpycall.py via _.SHELL aufrufen und Rückgabe einlesen (Integrationstest LISP↔Python)

Tests

Zwei Test-Ebenen, beide gesteuert über bin\run_tests.bat (Details und Verzeichnisstruktur: ../tests/README.md):

  1. LISP-Unit-Tests (tests/test_unit.lsp) – prüfen reine Standardfunktionen direkt in AutoLISP, ohne Zeichnung.
  2. Zeichnungsbasierte Integrationstests (tests/test_*.lsp + tests/test_*.py) – erzeugen Blöcke in BricsCAD und validieren das Ergebnis anschließend mit pytest/ezdxf. Module: test_kreisel, test_foerderer, test_linienzug, test_gefaellestrecke, test_omniflo, test_omniflo_strecke und test_mubea (Gesamtmodell: Kreisel + Vario + Gefällestrecken + Separatoren aus tests/testdata/mubea.json in einer Zeichnung; über SSG_RUN_ALL_TESTS bzw. Menü „Tests → Mubea Gesamtmodell").

Welche JSON-Angaben pro Element-Typ nötig sind (abgeleitet aus den Produktions-Routinen, nicht aus den Test-Wrappern), dokumentiert ../tests/testdata/object_data.md – inkl. der Unterscheidung scriptbar vs. nur-interaktiv.

LISP-Unit-Tests (test_unit.lsp)

Testen reine Hilfsfunktionen – solche, die nur aus ihren Argumenten ein Ergebnis berechnen und keine Zeichnungsdatenbank, Auswahlsätze, Dialoge oder Blockdateien brauchen (String-, Zahl-, Vektor-, Listen- und Alist-Helfer). Abgedeckt werden Funktionen aus ssg_core, ssg_lang, ssg_id, vf_core, export, Gefaellestrecke, OmniModulInsert und KreiselInsert.

Aufruf über die Kommandozeile (startet BricsCAD headless):

bin\run_tests.bat --lisp

run_tests.bat --lisp löscht das alte Ergebnis, startet BricsCAD mit tests/test_unit.scr (lädt ssg_load.lsp + test_unit.lsp, ruft TEST_UNIT auf und beendet BricsCAD), gibt danach tests/output/unit_results.txt aus und liefert Exit-Code 1, wenn ein Test fehlschlägt oder kein Report entsteht.

Aufruf direkt in BricsCAD (SSG_LIB geladen):

(load (strcat (getenv "DXFMAKRO") "/tests/test_unit.lsp"))
TEST_UNIT

Aufbau eines Testfalls. test_unit.lsp enthält ein Mini-Framework: jeder Testfall ruft eine Funktion auf und vergleicht das Ergebnis gegen einen erwarteten Wert. Die Assertion-Helfer zählen Treffer/Fehler mit und schreiben je eine PASS/FAIL-Zeile:

Helfer Vergleich
tu-eq name erwartet ist exakt (equal) – Strings, Ganzzahlen, Listen davon
tu-eqf name erwartet ist numerisch mit Toleranz 1e-6 – Fliesskomma, auch verschachtelte Listen
tu-true name ist Ergebnis ist nicht nil
tu-nil name ist Ergebnis ist nil

Beispiel – Formatierung einer ID und ein Vektor-Kreuzprodukt:

(tu-eq  "ssg-id-format/1"      "0001"          (ssg-id-format 1))
(tu-eqf "vec3-cross/x-cross-y" '(0.0 0.0 1.0)  (vec3-cross '(1.0 0.0 0.0) '(0.0 1.0 0.0)))

Die Testfälle sind in tu-tests-<modul>-Funktionen gruppiert; c:TEST_UNIT ruft alle nacheinander auf, gibt eine Zusammenfassung (Gesamt / PASS / FAIL) aus und schreibt den Report unit_results.txt mit einer abschließenden Zeile RESULT: OK bzw. RESULT: FAIL (die run_tests.bat auswertet).

Neuen Testfall ergänzen: in der passenden tu-tests-<modul>-Funktion eine tu-eq/tu-eqf/tu-true/tu-nil-Zeile hinzufügen. Für ein neues Modul eine eigene tu-tests-<modul>-Funktion anlegen und in c:TEST_UNIT aufrufen. Getestet werden sollten nur Funktionen ohne Zeichnungs-/Dialog-Umfeld – alles mit ssget/entget/entmake/command/vla-*/entsel/DCL gehört in die zeichnungsbasierten Integrationstests.


KreiselInsert.lsp – ILS Kreisel und Eckrad

AutoLISP-Implementierung fuer ILS Kreisel und Eckrad. Enthaelt alle Befehle fuer Einfuegen, Verbinden, Neuzeichnen und Bearbeiten.

Befehl Beschreibung
c:KreiselInsert Kreisel-Block einfuegen: Basispunkt (AN-Seite), Abstand als Gummiband-Linie (deren Richtung = Rotation), Hoehe, Kreiselart
c:KreiselConnect Zwei Punkte waehlen, Kreisel dazwischen einfuegen
c:KreiselRedraw Bestehenden Kreisel mit neuen Parametern neu zeichnen
c:KreiselQuick Schnelleinfuegung mit Standardwerten
c:KreiselEdit Kreisel-Attribute ueber DCL-Dialog bearbeiten
c:KreiselParams Aktuelle Kreisel-Parameter anzeigen
c:KreiselLabelSetup Schriftart, Hoehe und Farbe fuer Kreisel-Beschriftung konfigurieren
c:KreiselLabelPos Label-Offset (dx/dy) setzen
c:KreiselLabelHoehe Label-Hoehe aendern
c:ILS_Eckrad Eckrad an Tangentenpunkt einfuegen, Parameter per DCL-Dialog (eckrad_edit.dcl; ohne GUI Konsolen-Rueckfall)
c:EckradEdit Eckrad ueber DCL-Dialog bearbeiten (Bezeichnung, Hoehe, Drehung, Drehrichtung, Geruest; kein Abstand/Typ), Neuaufbau mit gleicher Nummer
c:KREISEL_WEICHEN Beruehrpunkte (= ILS-Weichen) aller Kreisel/Eckraeder gleicher Hoehe ermitteln: Rad/Rad und Rad/Laufprofil auf der freien Radseite, Toleranz toleranz_beruehrung/toleranz_hoehe (component_defaults.json). Ueberschneidungen und Seite-an-Seite-Kreisel werden als Kollision gemeldet. Konsolenliste + Kreis-Marker (Layer kreisel_weiche/kreisel_kollision), ein neuer Lauf ersetzt die Marker. Derselbe Kern (kreisel-bp-ermitteln) liefert beim Export kreisel_weichen.json fuer export_csv.py/export_sivas.py

OmniModulInsert.lsp – Omniflo-Komponenten

AutoLISP-Implementierung fuer alle Omniflo-Komponenten: Boegen, Weichen, Verbinder, Transferwagen. Liest JSON-Daten aus omniflo_boegen.json und omniflo_weichen.json. Alle Konstanten via ssg-cfg-or aus Config.

Befehlsgruppe Befehle Beschreibung
Daten OMNI_LOAD, OMNI_INFO_BOGEN, OMNI_INFO_WEICHE JSON-Daten laden und abfragen
Boegen OMNI_APB_630_90, OMNI_APB_550_675, OMNI_APB_630_45, OMNI_APB_550_225, OMNI_APB_650_180 Omniflo-Boegen ueber DCL-Dialog einfuegen
Weichen OMNI_W90_*, OMNI_W45_*, OMNI_WP_*, OMNI_WK_*, OMNI_WKomb_* Omniflo-Weichen (Einfach/Doppel/Dreiwege, Delta, Stern)
Geraden OMNI_AP60, OMNI_AP110, OMNI_APG110 Omniflo-Geradenstuecke
Ladeschleifen OMNI_LADESCHLEIFE_AP110 Ladeschleife aus omniflo_ladeschleifen.json ueber DCL-Dialog (dcl/omniflo_ladeschleifen.dcl) einfuegen; Daten per ssg-json-laden (Beschreibungen enthalten Kommas). Blockdatei <Sivasnr>.dwg unter DXFM_OMNIFLO (omni:insert-dxf faellt auf .dwg zurueck, wenn keine .dxf existiert). Per OMNI_EDIT editierbar
TEF Elemente OMNI_TEF_UmlenkR/L, OMNI_TEF_AntriebL/R, OMNI_TEF_Gerade Feste TEF-Bauteile ohne Sivas-Auswahl, direkt per omni:insert-dxf an gewaehltem Punkt eingefuegt (Dateien unter DXFM_OMNIFLO)
Anbaugruppen ⚠️ OMNI_KettenFoerderer Dummy (noch nicht implementiert, im Menue ausgegraut); OMNI_STOPPER/OMNI_SCANNER/OMNI_BUERSTENBREMSE sind implementiert
Transferwagen ⚠️ OMNI_TV_* Dummy (noch nicht implementiert, im Menue ausgegraut)
Bogenweichen ⚠️ OMNI_APBW_* Dummy (noch nicht implementiert, im Menue ausgegraut)
Bearbeiten OMNI_EDIT Omniflo-Block selektieren und Attribute bearbeiten

Daneben zeichnet TEFInsert.lsp (TEF_FOERDERER_LINIE) eine Kette von TEF-Geradenelementen (1000 mm) entlang einer frei gewaehlten Linie – nicht zu verwechseln mit den einzelnen OMNI_TEF_*-Befehlen oben.


SSG_LIB_Commands.lsp – BTMT, Sensoren, Dummy-Befehle, Konfiguration und SSG_BLOCKEDIT

Sammeldatei fuer Menue-Befehle: teils Platzhalter fuer noch nicht implementierte Eintraege, teils bereits echte Funktionalitaet (BTMT Be-/Entladung, Sensoren, Konfiguration, Doppelklick-Dispatcher). Alle noch offenen Dummy-Menueintraege sind in menu/SSG_LIB.mnu mit ~ ausgegraut (siehe Abschnitt "Status: noch offene Menueintraege").

Sensoren einfuegen (real, ueber ils-insert-sensor → wiederholtes _.INSERT mit interaktivem Einfuegepunkt/Rotation, Blockdatei via ssg-ils-block-datei):

Befehl Block Beschreibung
ILS_SCANNER_INSERT Scanner Scanner wiederholt einfuegen (ENTER/ESC beendet)
ILS_SEPARATOR_INSERT Separator_SP Separator wiederholt einfuegen (Menue „Separator einfuegen")

BTMT Be-/Entladestation einfuegen (real, ueber ils-insert-station):

Befehl ROH-Block Datei (3D) Beschreibung
ILS_BTMT_Beladung BTMT-Beladung BTMT-Beladung_3D.dwg Beladestation wiederholt einfuegen (ENTER/ESC beendet)
ILS_BTMT_Entladung SC_Entladung SC_Entladung_3D.dwg Entladestation wiederholt einfuegen (ENTER/ESC beendet)

Ablauf je Einfuegung: Einfuegepunkt abfragen → _.INSERT mit interaktiver Drehung (pause) → Layer aus dem LAYER-Attribut bzw. der eigenen Ebene der Blockdefinition setzen (ils-block-layer-setzen, gleiche Konvention wie omni:insert-dxf/tefl-insert-element) → ssg-id-generate, falls der Block ein ID-Attribut fuehrt.

Die Blockdefinition kommt aus ssg-ils-block-laden (aktuelle Dimension *ssg-ils-dim* → DXFM_DIM → 3D, DWG wird nur einmal pro Zeichnung gelesen); eingefuegt wird der zurueckgegebene dim-suffigierte Blockname. Fehlt die Datei der gewuenschten Dimension, greift der 3D-Fallback mit Warnung – aktuell fuer BTMT-Beladung_2D.dwg; sobald diese Datei in data/ils/ liegt, wird sie im 2D-Modus ohne Codeaenderung verwendet (SC_Entladung_2D.dwg existiert bereits).

Beide Stationen werden ueber pattern_btmt_beladung/pattern_btmt_entladung (cfg/export.cfg) von ssg-id-collect-blocks (ssg_id.lsp) UND von csv:collect-export-blocks (export.lsp) erfasst und erscheinen im Sivas-/ CSV-Export als eigene TeileArt-Zeilen ("ILS 2.0 BTMT Beladung"/"ILS 2.0 BTMT Entladung" bzw. "BT - Beladung ..."/"Abwurf fuer Klammerbuegel ..."); im Sivas-Export zusaetzlich in den Summenzaehlern "Anzahl aller BTBeladung"/ "Anzahl aller Abwurfstationen" der ILS-Automation-Zeile.

Eingang-/Ausgang-Symbol: ILS_EINGANG_INSERT/ILS_AUSGANG_INSERT nutzen dieselbe ils-insert-station-Routine wie BTMT Be-/Entladung (frei platzierbar, Blöcke Eingang_<DIM>.dwg/Ausgang_<DIM>.dwg in data/ils).

Registrierte Dummy-Befehle:

Gruppe Befehle
ILS Zusatzmodule ILS_ETF_Etagenfoerderer
ILS Kurven angetrieben Aussen ILS_K90LA, ILS_K90RA, ILS_K60LA, ILS_K60RA, ILS_K30LA, ILS_K30RA
ILS Kurven angetrieben Innen ILS_K90LI, ILS_K90RI, ILS_K60LI, ILS_K60RI, ILS_K30LI, ILS_K30RI
ILS Gefaellestrecken-Kurven ILS_Gefaellestrecke

FOERDERANLAGE ist nicht hier definiert – dieser Befehl ist in VarioFoerderer.lsp implementiert.

Konfigurationsbefehle (Menue → Konfiguration):

Befehl Beschreibung
SSG_DIM_SWITCH Schaltet zwischen 2D/3D-Bloecken um (setzt DXFM_DIM, DXFM_BLOCKS, DXFM_OMNIFLO)
SSG_SPRACHE Oeffnet Dialog sprache.dcl, setzt *ssg-lang* und persistiert via DXFM_LANG (siehe ssg_lang.lsp)

SSG_BLOCKEDIT – Doppelklick/Kontextmenue-Dispatcher:

Erkennt den Blocktyp des selektierten INSERT-Blocks und ruft den passenden Bearbeitungsbefehl auf (Reihenfolge wichtig: GR_* vor dem Omniflo-Zweig, da Geruest-Bloecke ebenfalls ein TEILEART-Attribut tragen):

Blockmuster Aktion
KREISEL_* KreiselEdit
ECKRAD_* EckradEdit
GF_* GEFAELLESTRECKE_EDIT
VF_* VARIOFOERDERER_EDIT
GR_* Geruest – BEDIT (kein eigener Edit-Pfad; siehe GeruestInsert.lsp)
TRO_* TRO_EDIT
Omniflo (TEILEART-Attribut, AP110*, numerisch) OMNI_EDIT
Sonstige BEDIT (Block-Editor)

GeruestInsert.lsp – Geruest-Baugruppen

Rohr-Geruest-Baugruppen (Saeulen, Rohrabhaenger, Wandbefestigung, Rohr-Geruest-Traeger) aus data/json/geruest.json bzw. data/json/geruest_traeger.json konfigurieren und einfuegen. Die Dialogdefinition wird zur Laufzeit erzeugt (geruest-dcl-schreiben, temporaere DCL-Datei) – es gibt keine feste dcl/geruest.dcl, weil je Anbauteil ein eigenes Mengenfeld gebraucht wird. Ausfuehrliche Beschreibung (Konfigurationen, Attribut-Schema, Querstreben/Muffe, Traeger-Beschriftung): siehe ../CLAUDE.md Abschnitt "AutoLISP-Module".

Befehl Beschreibung
c:GERUEST Dialog ohne Vorgabe-Bereich (Dropdown Rohrabhaenger/Saeulen/Wandbefestigung)
c:GERUEST_SAEULEN / c:GERUEST_ROHRABHAENGER / c:GERUEST_WANDBEFESTIGUNG Dialog mit vorgewaehltem Bereich (derselbe Dialog wie GERUEST)
c:GERUEST_TRAEGER Eigener fester Dialog (dcl/geruest_traeger.dcl): Rohr-Geruest-Traeger mit Linien-Logik (Start-/Endpunkt oder Laenge, Laengenabzuege, Querstreben/Muffe-Verteilung)
c:GERUEST_TRAEGER_BESCHRIFTEN Alle Traeger der Zeichnung neu beschriften (eigenes TEXT-Objekt, verknuepft per XDATA SSG_GR_BESCHR)

Block-Praefix GR_<id>_<timestamp> – nicht kosmetisch: SSG_BLOCKEDIT muss GR_* vor dem Omniflo-Zweig abfangen, da Geruest-Bloecke ebenfalls ein TEILEART-Attribut tragen. Export-Pattern pattern_geruest = GR_* (cfg/export.cfg).


Tro_Edit.lsp – TRO-Marker

TRO-Marker (Block TRO_SYM_<Typ>) fuer sps_skel/lib/tro_annotate.py.

Befehl Beschreibung
c:TRO_INSERT Bestehende Blockdefinition an gewaehltem Punkt einfuegen, setzt ID/TYPE; bricht ab, wenn der Typ noch keine Blockdefinition in der Zeichnung hat (entsteht nur ueber tro_annotate.py)
c:TRO_EDIT ID/TYPE eines bestehenden Markers per Dialog aendern

Typliste kommt aus tro_types.lsp (von tro_annotate.py --emit-lisp nach DXFM_LISP geschrieben). SSG_BLOCKEDIT leitet Blocknamen TRO_* zu TRO_EDIT.


Connection_Edit.lsp – Verbindungen (SPS)

Verbindungslinien zwischen zwei Punkten/Bausteinen fuer SPS-Dokumentation.

Befehl Beschreibung
c:CONNECTION_INSERT Verbindung zwischen zwei Punkten einfuegen (Laenge/Winkel/Mitte werden berechnet)
c:CONNECTION_EDIT Bestehende Verbindung bearbeiten

DrawPlanquadrate.lsp – Planquadrat-Raster

Zeichnet auf Z=0 ein Planquadrat-Linienraster (senkrecht/waagerecht) im Abstand/Zaehlschema der aktiven [Planquadrate]-Konfiguration aus cfg/export.cfg – dieselbe Quelle wie lib/export_planquadrat.py fuer den CSV-Export. Bereich und Ursprung kommen aus der Bounding-Box derselben Blockmenge wie EXPORTCSV (csv:collect-export-blocks), nicht aus dem reinen Einfuegepunkt oder den Zeichnungs-Extents. Lazy geladen ueber (ssg-ensure "DrawPlanquadrate"), nicht Teil der Core-Ladereihenfolge.

Befehl Beschreibung
c:DRAW_PLANQUADRATE Raster neu aufbauen (entfernt zuerst einen evtl. vorhandenen Block)
c:DELETE_PLANQUADRATE Raster-Block entfernen
c:PLANQUADRATE_TOGGLE Dispatcht auf Zeichnen bzw. Loeschen, je nachdem ob der Block existiert

Das fertige Raster (Linien + Zaehl-Texte) wird zu einem einzigen Block ZZ_PLANQUADRATE bei (0,0,0) zusammengefasst; Layer aus cfg/layer.cfg.