diff --git a/CLAUDE.md b/CLAUDE.md index ddef2fc..fd7a277 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -91,7 +91,7 @@ Detaillierte Dokumentation aller Funktionen und Befehle: siehe `Lisp/README.md`. | Datei | Befehle | Beschreibung | |---|---|---| -| `ssg_core.lsp` | - | Kernel: ssg-start/ssg-end, ssg-cfg-or, ssg-attrib-read/write, Layer/Block-Ops. Zentrale Helfer: `ssg-lisp-verzeichnis`/`ssg-lisp-datei-pfad` (Lisp-Pfad-Ermittlung), `ssg-rot-matrix-zy` (4x4 Rz(hz)*Ry(vert)-Rotationsmatrix, clusteruebergreifend), GUI-Aus-Schalter `*ssg-gui-aus*` + `ssg-gui-aus`/`ssg-gui-an`/`ssg-gui-p` (fuer automatische Tests: schaltet DCL-/Wizard-Dialoge ab, Module fallen auf Konsolen-/getXXX-Pfad zurueck; der Linienzug hat zusaetzlich `*vfl-headless*`, das die Konsolen-Rueckfrage selbst verbietet - siehe VarioFoerderer-Zeile) | +| `ssg_core.lsp` | - | Kernel: ssg-start/ssg-end, ssg-cfg-or, ssg-attrib-read/write, Layer/Block-Ops. Zentrale Helfer: `ssg-lisp-verzeichnis`/`ssg-lisp-datei-pfad` (Lisp-Pfad-Ermittlung), `ssg-rot-matrix-zy` (4x4 Rz(hz)*Ry(vert)-Rotationsmatrix, clusteruebergreifend), GUI-Aus-Schalter `*ssg-gui-aus*` + `ssg-gui-aus`/`ssg-gui-an`/`ssg-gui-p` (fuer automatische Tests: schaltet DCL-/Wizard-Dialoge ab, Module fallen auf Konsolen-/getXXX-Pfad zurueck; der Linienzug hat zusaetzlich `*vfl-headless*`, das die Konsolen-Rueckfrage selbst verbietet - siehe VarioFoerderer-Zeile). **Layer-Zuordnung**: `ssg-layer-cfg-load`/`-reset` (liest `cfg/layer.cfg` lazy), `ssg-layer-cfg-eintrag` (reine Aufloesung "Layername, Farbe" -> `(layer . farbe)`, in `tests/test_unit.lsp` getestet), `ssg-layer-eintrag` (Suchreihenfolge `[ils_]` -> `[allgemein]`), `ssg-layer-anlegen` (Layer mit cfg-Farbe anlegen, optional aktivieren) und `ssg-layer-setzen` (Blockreferenz auf den Baugruppen-Layer legen) - fuer ZUSAMMENGEBAUTE Baugruppen; `ssg-block-layer-vorgabe` (LAYER-Attribut -> `ssg-ils-block-ebene`) fuer nur EINGEFUEGTE Bloecke. Alle liefern nil, wenn nichts konfiguriert ist, und lassen den Layer dann unangetastet | | `ssg_ks_insert.lsp` | - | Gemeinsame KS-Extraktion + Block-Einfuegeprimitiven (von VarioFoerderer UND Gefaellestrecke genutzt, frueher in beiden dupliziert): `vec-length`, `ks-line-axis`, `ks-normalize-name`, `ks-relativize`/`-absolutize`, `ensure-block-loaded`, `extract-ks-from-block[-raw]` (Cache `*ks-cache*`), `insert-block-by-ks` (nur Rz), `insert-inclined-scaled-block`/`insert-rotated-block-with-ks` (Rz*Ry). MNL laedt es als Core-Modul VOR Gefaellestrecke/VarioFoerderer; vf_core/Gefaellestrecke haben einen guarded Nachlade-Load fuers isolierte Test-Laden | | `ssg_lang.lsp` | - | Sprachumschaltung Deutsch/Englisch (ssg-text, ssg-textf, *ssg-lang*) | | `ssg_dbg.lsp` | - | Debug-Logging (dbgopen, dbgmsg, dbgflush, dbgclose) | @@ -149,6 +149,11 @@ Werden via `bin/setenv.bat` gesetzt. Wichtigste: - 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.) +- **Layer-Zuordnung** - zwei Quellen, klar getrennt: + - Baugruppen, die ein Makro aus Einzelteilen **zusammenbaut** (`KREISEL_n`, `ECKRAD_n`, `VF_n`, `GF_n`) und die selbst gezeichnete Hilfsgeometrie (Kreisel-Tangenten, PIN-Linien, VF-/GF-/Kreisel-Beschriftung) haben keine Blockdatei in `data/` und damit kein Attribut - ihr Ziel-Layer **und die Layerfarbe** stehen in `cfg/layer.cfg` (Abschnitte `[ils_2d]`/`[ils_3d]`/`[allgemein]`, Key = Baugruppe, Wert = `Layername, Farbnummer`). Gelesen ueber `ssg-layer-setzen`/`ssg-layer-anlegen` (`ssg_core.lsp`). + - Bloecke, die nur aus `data/` **eingefuegt** werden, tragen ihren Ziel-Layer als Block-Attribut `LAYER` (gepflegt in `data/ils/allocations_collected.json` bzw. direkt in den DWGs); dieses Attribut gilt als Vorgabe, angewendet ueber `ssg-block-layer-vorgabe` (Fallback: "eigene" Ebene der Blockdefinition per `ssg-ils-block-ebene`). + - Fehlt `cfg/layer.cfg` oder ein Eintrag, bleibt der Layer unangetastet - kein Fehler, Verhalten wie vorher. + - Die **Farbe** wirkt nur bei der Neuanlage des Layers (`ssg-make-layer` laesst bestehende Layer unveraendert, damit Kundenzeichnungen nicht umgefaerbt werden). Layer, die eine Blockdatei aus `data/ils` selbst mitbringt (z.B. `ILS_SP`/`_3D_ILS_SP`), legt BricsCAD schon beim Einfuegen des Blocks mit der Farbe **aus der DWG** an - dort greift die cfg-Farbe nicht, wohl aber der Layername des Wrappers. Fuer Layer ohne Baugruppen-Key gibt es zusaetzlich den Abschnitt `[farben]` (Layername = Farbe), gelesen von `ssg-layer-farbe-fuer-name`. - Komponentendaten (Masse, Sivas-IDs) liegen als JSON in `data/json/` - Sprache im Code und Kommentaren: Deutsch diff --git a/Lisp/Gefaellestrecke.lsp b/Lisp/Gefaellestrecke.lsp index f8626f5..3232d19 100644 --- a/Lisp/Gefaellestrecke.lsp +++ b/Lisp/Gefaellestrecke.lsp @@ -249,6 +249,9 @@ (setq block-obj (vla-InsertBlock modelspace (vlax-3D-point '(0 0 0)) blockname scale 1.0 1.0 0)) + ;; Einzelteil auf die eigene Ebene der Blockdefinition legen - wie in den + ;; Zwillingen in ssg_ks_insert.lsp; hier fehlte der Aufruf bisher. + (ssg-ils-block-auf-ebene block-obj blockname) (vla-TransformBy block-obj (vlax-tmatrix (ssg-rot-matrix-zy chz shz cv sv))) (vla-Move block-obj (vlax-3D-point '(0 0 0)) (vlax-3D-point pt)) (setq endpunkt @@ -276,6 +279,9 @@ (setq block-obj (vla-InsertBlock modelspace (vlax-3D-point '(0 0 0)) blockname 1.0 1.0 1.0 0)) + ;; Einzelteil auf die eigene Ebene der Blockdefinition legen - wie in den + ;; Zwillingen in ssg_ks_insert.lsp; hier fehlte der Aufruf bisher. + (ssg-ils-block-auf-ebene block-obj blockname) (vla-TransformBy block-obj (vlax-tmatrix (ssg-rot-matrix-zy chz shz cv sv))) (vla-Move block-obj (vlax-3D-point '(0 0 0)) (vlax-3D-point pt)) (setq endpunkt @@ -317,6 +323,9 @@ (setq block-obj (vla-InsertBlock modelspace (vlax-3D-point '(0 0 0)) blockname 1.0 1.0 1.0 0)) + ;; Einzelteil auf die eigene Ebene der Blockdefinition legen - wie in den + ;; Zwillingen in ssg_ks_insert.lsp; hier fehlte der Aufruf bisher. + (ssg-ils-block-auf-ebene block-obj blockname) (vla-TransformBy block-obj (vlax-tmatrix (list (list chz (- shz) 0 0) (list shz chz 0 0) @@ -1098,7 +1107,7 @@ ;; Beschriftung: Mitte der ersten Geraden, 400mm senkrecht rechts versetzt. (defun gf-make-label (gf-nummer hoehe-von hoehe-bis deltaH deltaL L-gf-str winkel nach-aus-pt entry-hz L-first-seg / - label-txt label-pt chz-l shz-l halb basis-winkel) + label-txt label-pt chz-l shz-l halb basis-winkel lay) (setq chz-l (cos (* entry-hz (/ pi 180.0)))) (setq shz-l (sin (* entry-hz (/ pi 180.0)))) (setq halb (/ (float L-first-seg) 2.0)) @@ -1121,6 +1130,16 @@ (while (>= basis-winkel 360.0) (setq basis-winkel (- basis-winkel 360.0))) (if (>= basis-winkel 180.0) (setq basis-winkel (- basis-winkel 180.0))) (setq basis-winkel (if (or (< basis-winkel 45.0) (>= basis-winkel 135.0)) 0.0 90.0)) + ;; Beschriftungs-Layer aus cfg/layer.cfg (Baugruppe "gf_beschriftung"), sonst + ;; der bisherige Hartwert. Der Layer wird hier ANGELEGT - bisher schrieb das + ;; entmake unten auf einen Layer, den niemand erzeugt hat. + (setq lay (ssg-layer-anlegen "gf_beschriftung" nil)) + (if (null lay) + (progn + (setq lay "GF_Beschriftung") + (ssg-make-layer lay "7" nil) + ) + ) (entmake (list '(0 . "TEXT") (cons 10 label-pt) @@ -1128,7 +1147,7 @@ '(40 . 100.0) (cons 1 label-txt) '(7 . "Standard") - '(8 . "GF_Beschriftung") + (cons 8 lay) (cons 50 (* basis-winkel (/ pi 180.0))) '(72 . 1) '(73 . 2))) @@ -1196,6 +1215,9 @@ ;; Attribute auf das eingefuegte INSERT-Objekt setzen (volle Werteliste; ;; nicht vorhandene Tags ignoriert ssg-attrib-set-on -> reduzierter Satz ok). (setq gf-insert (entlast)) + ;; Ziel-Layer der Baugruppe aus cfg/layer.cfg (ohne Eintrag bleibt die + ;; Referenz auf dem aktuellen Layer, wie vor der Umstellung). + (ssg-layer-setzen gf-insert "gefaellestrecke") ;; Kette wurde bei Z=0 gebaut; der OSMODE=0-Wrap loest den OCS-Skew der ;; gekippten Elemente sauber zur logischen Position (Z=0) auf. Den fertigen ;; GF_n-Block daher nur noch senkrecht auf die Zielhoehe heben (OSMODE=0, diff --git a/Lisp/KreiselInsert.lsp b/Lisp/KreiselInsert.lsp index 98011f5..b967ca5 100644 --- a/Lisp/KreiselInsert.lsp +++ b/Lisp/KreiselInsert.lsp @@ -194,7 +194,7 @@ ) ;; Beschriftungstext erzeugen -(defun kreisel-make-label (nummer abstand kreiselart / textStr insertPoint radius mitteX mitteY textHoehe) +(defun kreisel-make-label (nummer abstand kreiselart / textStr insertPoint radius mitteX mitteY textHoehe lay) ;; Text: "KREISEL 1: PIN_4000" (setq textStr (strcat "KREISEL " (itoa nummer) ": " kreiselart "_" (rtos abstand 2 0))) @@ -216,13 +216,20 @@ ;; Schriftart Arial einstellen (kreisel-setup-textstyle) - ;; Layer erstellen - (ssg-make-layer *kreisel-beschriftung-layer* (itoa *kreisel-beschriftung-farbe*) T) - + ;; Layer erstellen: bevorzugt aus cfg/layer.cfg (Baugruppe + ;; "kreisel_beschriftung"), sonst der bisherige Hartwert. + (setq lay (ssg-layer-anlegen "kreisel_beschriftung" T)) + (if (null lay) + (progn + (setq lay *kreisel-beschriftung-layer*) + (ssg-make-layer lay (itoa *kreisel-beschriftung-farbe*) T) + ) + ) + ;; Text mit entmake erstellen (zentriert) (entmake (list '(0 . "TEXT") - (cons 8 *kreisel-beschriftung-layer*) + (cons 8 lay) (cons 10 insertPoint) (cons 40 textHoehe) (cons 1 textStr) @@ -423,8 +430,11 @@ ;; SP8 Kreis (Spannstation) bei (radius+abstand, 0) - Dim-Suffix im Dateinamen (command "_.INSERT" (strcat *block-path* "SP8_" *ki-dxfm-dim* ".dwg") (list (+ radius abstand) 0.0 0.0) 1 1 0) - ;; Tangenten auf Layer S_LP - (ssg-make-layer "S_LP" "7" T) + ;; Tangenten-Layer: bevorzugt aus cfg/layer.cfg (Baugruppe + ;; "kreisel_tangente"), sonst der bisherige Hartwert S_LP. + (if (null (ssg-layer-anlegen "kreisel_tangente" T)) + (ssg-make-layer "S_LP" "7" T) + ) (if is-pin (setvar "CECOLOR" (itoa (ssg-cfg-or "kreisel" "color_linie_1" 5))) (setvar "CECOLOR" (itoa (ssg-cfg-or "kreisel" "color_linie_2" 1))) @@ -438,7 +448,11 @@ ;; PIN-Linien (if is-pin (progn - (ssg-make-layer "pinbereich" (itoa (ssg-cfg-or "kreisel" "color_pin" 3)) T) + ;; PIN-Layer: bevorzugt aus cfg/layer.cfg (Baugruppe + ;; "kreisel_pinbereich"), sonst der bisherige Hartwert pinbereich. + (if (null (ssg-layer-anlegen "kreisel_pinbereich" T)) + (ssg-make-layer "pinbereich" (itoa (ssg-cfg-or "kreisel" "color_pin" 3)) T) + ) (setvar "CECOLOR" (itoa (ssg-cfg-or "kreisel" "color_pin" 3))) ;; Obere PIN-Linie @@ -489,6 +503,12 @@ ;; --- Attribut-Werte durch direkte Datenbankänderung setzen --- (setq block-ent (entlast)) + ;; Ziel-Layer der Baugruppe aus cfg/layer.cfg. Wichtig: der Wrapper hing + ;; bisher am CLAYER-Seiteneffekt von ssg-make-layer (S_LP bzw. pinbereich) + ;; und landete bei bereits vorhandener Blockdefinition auf dem aktiven Layer - + ;; jetzt ist er in beiden Faellen gleich. Ohne cfg-Eintrag bleibt es beim + ;; bisherigen Verhalten. + (ssg-layer-setzen block-ent (if is-pin "kreisel_pin" "kreisel")) (setq att-entity (entnext block-ent)) (while att-entity @@ -1269,6 +1289,9 @@ ;; Attribut-Werte durch direkte Datenbankaenderung setzen (setq block-ent (entlast)) + ;; Ziel-Layer der Baugruppe aus cfg/layer.cfg (der Eckrad-Zweig setzte bisher + ;; gar keinen Layer, das ECKRAD_n landete also immer auf Layer "0"). + (ssg-layer-setzen block-ent "eckrad") (setq att-entity (entnext block-ent)) (dbgp "Setze Attribut-Werte:") (while att-entity diff --git a/Lisp/OmniModulInsert.lsp b/Lisp/OmniModulInsert.lsp index b1fc57b..be18217 100644 --- a/Lisp/OmniModulInsert.lsp +++ b/Lisp/OmniModulInsert.lsp @@ -618,6 +618,11 @@ ) (ssg-attrib-set-on blockEnt attribs) + ;; Layer aus dem LAYER-Attribut setzen - dieselbe Vorgabe-Konvention wie in + ;; omni:insert-dxf und c:OMNI_EDIT. Die Quell-Attribute (srcAttribs) tragen + ;; den Layer bereits, er wurde hier bisher nur nicht angewendet. + (ssg-block-layer-vorgabe blockEnt bname attribs) + ;; 4. Text oberhalb der Linie positionieren, um Linienwinkel drehen, ;; Inhalt mit Laenge ergaenzen (setq perpX (* (- (sin angle)) textGap) @@ -1020,16 +1025,9 @@ (list (cons "HOEHE" (if hoehe hoehe (ssg-cfg-or "omniflo" "default_hoehe" "2000"))) (cons "DREHUNG" drehung-anzeige))) - ;; Layer aus LAYER-Attribut lesen und Block verschieben + ;; Layer aus der Block-Vorgabe (LAYER-Attribut) setzen (setq attribs (ssg-attrib-read blockEnt)) - (setq layer-name (cdr (assoc "LAYER" attribs))) - (if (and layer-name (> (strlen layer-name) 0)) - (progn - (ssg-make-layer layer-name 7 nil) - (entmod (subst (cons 8 layer-name) (assoc 8 (entget blockEnt)) (entget blockEnt))) - (entupd blockEnt) - ) - ) + (setq layer-name (ssg-block-layer-vorgabe blockEnt sivasnr-str attribs)) ) ) @@ -1378,16 +1376,9 @@ (list (cons "HOEHE" (if new-hoehe new-hoehe (ssg-cfg-or "omniflo" "default_hoehe" "2000"))) (cons "DREHUNG" (if new-drehung new-drehung (ssg-cfg-or "omniflo" "default_drehung" "0"))))) - ;; Layer aus LAYER-Attribut lesen und Block verschieben (wie omni:insert-dxf) + ;; Layer aus der Block-Vorgabe (LAYER-Attribut) setzen (wie omni:insert-dxf) (setq attribs (ssg-attrib-read blockEnt)) - (setq layer-name (cdr (assoc "LAYER" attribs))) - (if (and layer-name (> (strlen layer-name) 0)) - (progn - (ssg-make-layer layer-name 7 nil) - (entmod (subst (cons 8 layer-name) (assoc 8 (entget blockEnt)) (entget blockEnt))) - (entupd blockEnt) - ) - ) + (setq layer-name (ssg-block-layer-vorgabe blockEnt sivasnr-str attribs)) ) ) diff --git a/Lisp/README.md b/Lisp/README.md index c8f05b3..e379cd0 100644 --- a/Lisp/README.md +++ b/Lisp/README.md @@ -80,6 +80,34 @@ Grundfunktionen für Umgebungssicherung, Benutzerinteraktion, Layer, Blöcke, At | `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_]` → `[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 | diff --git a/Lisp/SSG_LIB_Commands.lsp b/Lisp/SSG_LIB_Commands.lsp index a68c6ed..16e50e6 100644 --- a/Lisp/SSG_LIB_Commands.lsp +++ b/Lisp/SSG_LIB_Commands.lsp @@ -17,25 +17,14 @@ (if (null *ils-btmt-beladung-block*) (setq *ils-btmt-beladung-block* "BTMT-Beladung")) (if (null *ils-btmt-entladung-block*) (setq *ils-btmt-entladung-block* "SC_Entladung")) -;; Layer einer frisch eingefuegten Blockreferenz setzen: bevorzugt aus dem -;; LAYER-Attribut des Blocks (gleiche Konvention wie omni:insert-dxf in -;; OmniModulInsert.lsp und tefl-insert-element in TEFInsert.lsp), sonst aus der -;; "eigenen" Ebene der Blockdefinition (ssg-ils-block-ebene). Liefert der Block -;; beides nicht, bleibt die Referenz auf dem aktuellen Layer. +;; Layer einer frisch eingefuegten Blockreferenz aus der Block-Vorgabe setzen. +;; Die Logik liegt zentral als ssg-block-layer-vorgabe in ssg_core.lsp (dieselbe +;; Konvention nutzen omni:insert-dxf in OmniModulInsert.lsp und +;; tefl-insert-element in TEFInsert.lsp); hier bleibt nur der bisherige Name als +;; duenner Wrapper stehen. ;; Rueckgabe: gesetzter Layername oder nil. -(defun ils-block-layer-setzen (ent realname attribs / lay) - (setq lay (cdr (assoc "LAYER" attribs))) - (if (or (null lay) (= lay "")) - (setq lay (ssg-ils-block-ebene realname)) - ) - (if (and lay (/= lay "")) - (progn - (ssg-make-layer lay 7 nil) - (entmod (subst (cons 8 lay) (assoc 8 (entget ent)) (entget ent))) - (entupd ent) - lay - ) - ) +(defun ils-block-layer-setzen (ent realname attribs) + (ssg-block-layer-vorgabe ent realname attribs) ) ;; Fuegt eine ILS-Station (BTMT-Beladung/SC_Entladung) wiederholt ein, bis der @@ -125,7 +114,7 @@ ;; Fuegt einen Sensor-Block wiederholt ein, bis der Benutzer mit ;; ENTER oder ESC abbricht. Rotation je Einfuegung interaktiv. -(defun ils-insert-sensor (fname / pfad pt oldattreq n res) +(defun ils-insert-sensor (fname / pfad pt oldattreq n res ent realname) (setq pfad (ils-sensor-pfad fname)) (if (null pfad) (princ (strcat "\n>>> FEHLER: Blockdatei '" fname ".dwg' nicht gefunden." @@ -145,6 +134,19 @@ ) (setq pt res) (command "_.INSERT" pfad pt "" "" pause) + (setq ent (entlast)) + ;; Layer aus der Block-Vorgabe setzen (LAYER-Attribut, sonst eigene + ;; Ebene der Blockdefinition) - wie bei ils-insert-station. Scanner und + ;; Separator_SP fuehren das LAYER-Attribut (ZZ_Scanner bzw. ILS_SEP-SP), + ;; es wurde hier bisher nur nicht ausgewertet. + ;; Blockname aus der Referenz selbst lesen: eingefuegt wird ueber den + ;; Dateipfad, der effektive Blockname haengt am 2D/3D-Fallback. + (if (and ent (= (cdr (assoc 0 (entget ent))) "INSERT")) + (progn + (setq realname (cdr (assoc 2 (entget ent)))) + (ssg-block-layer-vorgabe ent realname nil) + ) + ) ;; Sofort beim Einfuegen eine eindeutige ID vergeben - wie bei allen ;; anderen Bau-Routinen (Kreisel/GF/VF/Omniflo, siehe ssg-id-generate- ;; Aufrufe dort). Separator/Scanner waren bisher die einzige Ausnahme @@ -153,7 +155,7 @@ ;; das ist der Fall, den ssg-id-check-all als Sicherheitsnetz ;; eigentlich nur fuer Kopier-/Array-/Spiegel-Faelle abfangen soll. (if (atoms-family 1 '("ssg-id-generate")) - (ssg-id-generate (entlast))) + (ssg-id-generate ent)) (setq n (1+ n)) ) (setvar "ATTREQ" oldattreq) diff --git a/Lisp/TEFInsert.lsp b/Lisp/TEFInsert.lsp index 62b590a..c5cf2e3 100644 --- a/Lisp/TEFInsert.lsp +++ b/Lisp/TEFInsert.lsp @@ -98,17 +98,10 @@ (vla-TransformBy block-obj (vlax-tmatrix matrix)) (vla-Move block-obj (vlax-3D-point '(0.0 0.0 0.0)) (vlax-3D-point pt)) - ;; LAYER-Attribut auslesen und Block auf diesen Layer verschieben + ;; Layer aus der Block-Vorgabe (LAYER-Attribut) setzen (setq blockEnt (vlax-vla-object->ename block-obj)) (setq attribs (ssg-attrib-read blockEnt)) - (setq layer-name (cdr (assoc "LAYER" attribs))) - (if (and layer-name (> (strlen layer-name) 0)) - (progn - (ssg-make-layer layer-name 7 nil) - (entmod (subst (cons 8 layer-name) (assoc 8 (entget blockEnt)) (entget blockEnt))) - (entupd blockEnt) - ) - ) + (setq layer-name (ssg-block-layer-vorgabe blockEnt *tefl-blockname* attribs)) ;; Eindeutige ID zuweisen, falls das Block-Schema ein ID-Attribut fuehrt ;; (bei 0_B10030 aktuell nicht der Fall - dann folgenlos, wie in diff --git a/Lisp/ssg_core.lsp b/Lisp/ssg_core.lsp index 3efe2a8..702738f 100644 --- a/Lisp/ssg_core.lsp +++ b/Lisp/ssg_core.lsp @@ -268,6 +268,200 @@ ) ) +;; ------------------------------------------------------------ +;; ZIEL-LAYER JE BAUGRUPPE (cfg/layer.cfg) +;; ------------------------------------------------------------ +;; Fuer die Baugruppen, die die Makros aus Einzelteilen ZUSAMMENBAUEN +;; (KREISEL_n, ECKRAD_n, VF_n, GF_n) und fuer die selbst gezeichnete +;; Hilfsgeometrie (Tangenten, PIN-Linien, Beschriftungstexte) gibt es keine +;; Blockdatei in data/ und damit auch kein LAYER-Attribut - ihr Ziel-Layer +;; kommt aus cfg/layer.cfg. Bloecke, die nur EINGEFUEGT werden, nehmen +;; weiterhin ihr LAYER-Attribut (siehe ssg-block-layer-vorgabe unten). +;; +;; Bewusst hier in ssg_core.lsp und nicht in ssg_layer.lsp: jedes +;; Feature-Modul bootstrappt ssg_core selbst (KreiselInsert, Gefaellestrecke, +;; vf_core), ssg_layer aber nicht - dort waeren die Funktionen beim isolierten +;; Laden eines einzelnen Moduls nicht verfuegbar. ssg-make-layer und +;; ssg-insert-block liegen aus demselben Grund schon in dieser Datei. +;; +;; Alle Funktionen sind gutmuetig: fehlt die Datei, der Abschnitt, der Key oder +;; ist der Wert leer, liefern sie nil und der Aufrufer laesst den Layer +;; unangetastet - genau das Verhalten von vor der Umstellung. + +(if (not (boundp '*ssg-layer-cfg*)) (setq *ssg-layer-cfg* nil)) +(if (not (boundp '*ssg-layer-cfg-versucht*)) (setq *ssg-layer-cfg-versucht* nil)) + +;; cfg/layer.cfg einmalig laden (lazy, beim ersten Zugriff). +;; Ein fehlgeschlagener Ladeversuch wird gemerkt, damit nicht bei jeder +;; Einfuegung erneut auf die Platte zugegriffen wird. +;; Rueckgabe: ini-Alist oder nil. +(defun ssg-layer-cfg-load ( / cfg-dir pfad) + (if (not *ssg-layer-cfg-versucht*) + (progn + (setq *ssg-layer-cfg-versucht* T) + (setq cfg-dir (getenv "DXFM_CFG")) + (if cfg-dir + (progn + (setq pfad (strcat (vl-string-right-trim "/\\" + (vl-string-translate "\\" "/" cfg-dir)) + "/layer.cfg")) + (setq *ssg-layer-cfg* (ssg-load-ini pfad)) + ) + ) + ) + ) + *ssg-layer-cfg* +) + +;; Ladezustand zuruecksetzen (erzwingt Neu-Einlesen beim naechsten Zugriff). +;; Fuer Tests und fuer das Bearbeiten der cfg in laufender BricsCAD-Sitzung. +(defun ssg-layer-cfg-reset ( / ) + (setq *ssg-layer-cfg* nil + *ssg-layer-cfg-versucht* nil) + (princ) +) + +;; Einen Eintrag "Layername, Farbe" aus den ini-Daten aufloesen. +;; Reine Funktion (ini-Daten als Parameter) - damit ohne Datei-IO testbar. +;; Rueckgabe: (layername . farbe-als-string) oder nil, wenn Key/Wert fehlt. +;; Der Layername endet am ERSTEN Komma (Layernamen enthalten kein Komma); +;; fehlt die Farbangabe, wird "7" verwendet. +(defun ssg-layer-cfg-eintrag (ini-data sektion schluessel / roh pos lay farbe) + (setq roh (ssg-ini-get ini-data sektion schluessel nil)) + (if (and roh (= (type roh) 'STR)) + (progn + (setq pos (vl-string-search "," roh)) + (if pos + (setq lay (vl-string-trim " \t" (substr roh 1 pos)) + farbe (vl-string-trim " \t" (substr roh (+ pos 2))) + ) + (setq lay (vl-string-trim " \t" roh) + farbe "" + ) + ) + (if (> (strlen lay) 0) + (cons lay (if (> (strlen farbe) 0) farbe "7")) + ) + ) + ) +) + +;; Ziel-Layer einer Baugruppe ermitteln. +;; schluessel = Baugruppen-Key aus cfg/layer.cfg, z.B. "variofoerderer" +;; Suchreihenfolge: [ils_] -> [allgemein] +;; Rueckgabe: (layername . farbe) oder nil. +(defun ssg-layer-eintrag (schluessel / ini dim) + (setq ini (ssg-layer-cfg-load)) + (if ini + (progn + (setq dim (strcase (ssg-ils-dim-aktuell) T)) ; "2d"/"3d" + (cond + ((ssg-layer-cfg-eintrag ini (strcat "ils_" dim) schluessel)) + ((ssg-layer-cfg-eintrag ini "allgemein" schluessel)) + ) + ) + ) +) + +;; Konfigurierte Farbe zu einem LAYERNAMEN (nicht zu einer Baugruppe) suchen. +;; Gebraucht fuer Layer, die aus dem LAYER-Attribut eines Blocks bzw. aus der +;; Blockdefinition kommen und daher keinen Baugruppen-Key haben: sie werden oft +;; VOR dem Wrapper angelegt, und ssg-make-layer setzt die Farbe nur bei der +;; Neuanlage - ohne diese Suche wuerde die Farbe aus cfg/layer.cfg nie greifen. +;; Suchreihenfolge: +;; 1. Abschnitt [farben]: Key = Layername, Wert = Farbe +;; 2. alle uebrigen Abschnitte: Eintrag, dessen LAYERNAME passt +;; (Layernamen sind in AutoCAD/BricsCAD case-insensitiv) +;; 3. "7" als Grund-Default (bisheriges Verhalten) +;; Rueckgabe: Farbnummer als String, nie nil. +(defun ssg-layer-farbe-fuer-name (layname / ini treffer gesucht sek eintrag) + (setq ini (ssg-layer-cfg-load)) + (if (or (null ini) (null layname) (= layname "")) + "7" + (progn + (setq treffer (ssg-ini-get ini "farben" layname nil)) + (if (and treffer (> (strlen treffer) 0)) + (vl-string-trim " \t" treffer) + (progn + (setq gesucht (strcase layname)) + (foreach sek ini + (if (and (null treffer) (/= (car sek) "farben")) + (foreach eintrag (cdr sek) + (if (null treffer) + (progn + ;; Wert des Eintrags wieder in (layer . farbe) zerlegen + (setq eintrag (ssg-layer-cfg-eintrag + ini (car sek) (car eintrag))) + (if (and eintrag (= (strcase (car eintrag)) gesucht)) + (setq treffer (cdr eintrag)) + ) + ) + ) + ) + ) + ) + (if treffer treffer "7") + ) + ) + ) + ) +) + +;; Ziel-Layer einer Baugruppe anlegen (Farbe aus der cfg) und optional +;; aktivieren. aktiv = T setzt CLAYER auf den Layer. +;; Rueckgabe: Layername oder nil, wenn die Baugruppe nicht konfiguriert ist. +(defun ssg-layer-anlegen (schluessel aktiv / eintrag) + (if (setq eintrag (ssg-layer-eintrag schluessel)) + (progn + (ssg-make-layer (car eintrag) (cdr eintrag) aktiv) + (car eintrag) + ) + ) +) + +;; Objekt (in der Regel eine frisch eingefuegte Blockreferenz) auf den +;; Ziel-Layer seiner Baugruppe legen; der Layer wird bei Bedarf angelegt. +;; Rueckgabe: Layername oder nil, wenn die Baugruppe nicht konfiguriert ist +;; (dann bleibt das Objekt unveraendert auf seinem bisherigen Layer). +(defun ssg-layer-setzen (ent schluessel / lay ed) + (if (and ent (setq lay (ssg-layer-anlegen schluessel nil))) + (progn + (setq ed (entget ent)) + (entmod (subst (cons 8 lay) (assoc 8 ed) ed)) + (entupd ent) + lay + ) + ) +) + +;; Layer einer nur EINGEFUEGTEN Blockreferenz aus der Block-Vorgabe setzen: +;; bevorzugt aus dem LAYER-Attribut des Blocks, sonst aus der "eigenen" Ebene +;; der Blockdefinition (ssg-ils-block-ebene). Traegt der Block beides nicht, +;; bleibt die Referenz auf ihrem bisherigen Layer. +;; ent = Blockreferenz +;; realname = effektiver Blockname (fuer die Ebenen-Ermittlung) +;; attribs = Attribut-Alist (ssg-attrib-read), nil = wird selbst gelesen +;; Rueckgabe: gesetzter Layername oder nil. +(defun ssg-block-layer-vorgabe (ent realname attribs / lay ed) + (if (and ent (null attribs)) + (setq attribs (ssg-attrib-read ent)) + ) + (setq lay (cdr (assoc "LAYER" attribs))) + (if (or (null lay) (= lay "")) + (setq lay (ssg-ils-block-ebene realname)) + ) + (if (and ent lay (/= lay "")) + (progn + ;; Farbe aus cfg/layer.cfg, falls der Layername dort vorkommt (sonst "7"). + (ssg-make-layer lay (ssg-layer-farbe-fuer-name lay) nil) + (setq ed (entget ent)) + (entmod (subst (cons 8 lay) (assoc 8 ed) ed)) + (entupd ent) + lay + ) + ) +) + ;; Auswahlsatz-Iteration: Funktion fuer jedes Element aufrufen ;; ss = Auswahlsatz; func = Funktion mit einem Parameter (entity-name) (defun ssg-ss-foreach (ss func / i ename) @@ -567,7 +761,9 @@ (setq eb (ssg-ils-block-ebene realname)) (if (and eb obj) (progn - (if (not (tblsearch "LAYER" eb)) (ssg-make-layer eb 7 nil)) + ;; Farbe aus cfg/layer.cfg, falls der Layername dort vorkommt (sonst "7"). + (if (not (tblsearch "LAYER" eb)) + (ssg-make-layer eb (ssg-layer-farbe-fuer-name eb) nil)) (vl-catch-all-apply (function (lambda () (vla-put-Layer obj eb)))))) obj) diff --git a/Lisp/vf_core.lsp b/Lisp/vf_core.lsp index 777c62c..e478ef6 100644 --- a/Lisp/vf_core.lsp +++ b/Lisp/vf_core.lsp @@ -770,7 +770,7 @@ (defun vf-make-label (vf-nummer hoehe-von hoehe-bis deltaH deltaL L_VF L_GF1 L_GF2 richtung best-winkel n-separator n-scanner startpunkt hz / label-txt label-pt L_VF_str L_GF_str delta-sym - chz-l shz-l halb basis-winkel) + chz-l shz-l halb basis-winkel lay) (setq delta-sym (chr 916)) (setq L_VF_str (vl-string-subst "," "." (rtos (/ L_VF 1000.0) 2 3))) (setq L_GF_str (strcat (rtos (/ L_GF1 1000.0) 2 3) "," (rtos (/ L_GF2 1000.0) 2 3))) @@ -795,9 +795,19 @@ (while (>= basis-winkel 360.0) (setq basis-winkel (- basis-winkel 360.0))) (if (>= basis-winkel 180.0) (setq basis-winkel (- basis-winkel 180.0))) (setq basis-winkel (if (or (< basis-winkel 45.0) (>= basis-winkel 135.0)) 0.0 90.0)) + ;; Beschriftungs-Layer aus cfg/layer.cfg (Baugruppe "vf_beschriftung"), sonst + ;; der bisherige Hartwert. Der Layer wird hier ANGELEGT - bisher schrieb das + ;; entmake unten auf einen Layer, den niemand erzeugt hat. + (setq lay (ssg-layer-anlegen "vf_beschriftung" nil)) + (if (null lay) + (progn + (setq lay "VF_Beschriftung") + (ssg-make-layer lay "7" nil) + ) + ) (entmake (list '(0 . "TEXT") - (cons 8 "VF_Beschriftung") + (cons 8 lay) '(67 . 0) (cons 10 label-pt) (cons 40 *vfk-label-texthoehe*) @@ -881,6 +891,9 @@ ;; temporaer auf Welt (verhindert den 31.95mm-Z-Versatz bei ;; abweichendem BKS) und stellt es danach wieder her. (setq vf-insert (ssg-block-wrap-welt vf-bname startpunkt vf-ss)) + ;; Ziel-Layer der Baugruppe aus cfg/layer.cfg (ohne Eintrag bleibt die + ;; Referenz auf dem aktuellen Layer, wie vor der Umstellung). + (ssg-layer-setzen vf-insert "variofoerderer") (setq montagehoehe-m (/ (+ hoehe-von hoehe-bis) 2000.0)) ;; L_GF_m: kommagetrennte Segmentlaengen in Metern (vorne,hinten), ;; analog L_GF_m in Gefaellestrecke.lsp. diff --git a/Lisp/vf_etage.lsp b/Lisp/vf_etage.lsp index c986de2..0ab98c8 100644 --- a/Lisp/vf_etage.lsp +++ b/Lisp/vf_etage.lsp @@ -155,6 +155,9 @@ ) (setq block-obj (vla-InsertBlock modelspace (vlax-3D-point '(0 0 0)) blockname scale 1.0 1.0 0)) + ;; Einzelteil auf die eigene Ebene der Blockdefinition legen - wie in den + ;; Zwillingen in ssg_ks_insert.lsp; hier fehlte der Aufruf bisher. + (ssg-ils-block-auf-ebene block-obj blockname) (setq matrix (vf-rot-matrix chz shz cv sv)) (vla-TransformBy block-obj (vlax-tmatrix matrix)) (vla-Move block-obj (vlax-3D-point '(0 0 0)) (vlax-3D-point startpunkt)) @@ -186,6 +189,9 @@ ) (setq block-obj (vla-InsertBlock modelspace (vlax-3D-point '(0 0 0)) blockname 1.0 1.0 1.0 0)) + ;; Einzelteil auf die eigene Ebene der Blockdefinition legen - wie in den + ;; Zwillingen in ssg_ks_insert.lsp; hier fehlte der Aufruf bisher. + (ssg-ils-block-auf-ebene block-obj blockname) (setq matrix (vf-rot-matrix chz shz cv sv)) (vla-TransformBy block-obj (vlax-tmatrix matrix)) (vla-Move block-obj (vlax-3D-point '(0 0 0)) (vlax-3D-point startpunkt)) @@ -225,6 +231,9 @@ (setq ks-aus (cadr (assoc "KS_AUS" ks-data))) ;; Block einfuegen und rotieren (setq block-obj (vla-InsertBlock modelspace (vlax-3D-point '(0 0 0)) blockname 1.0 1.0 1.0 0)) + ;; Einzelteil auf die eigene Ebene der Blockdefinition legen - wie in den + ;; Zwillingen in ssg_ks_insert.lsp; hier fehlte der Aufruf bisher. + (ssg-ils-block-auf-ebene block-obj blockname) (vla-TransformBy block-obj (vlax-tmatrix (vf-rot-matrix chz shz cv sv))) (if (and ks-ein ks-aus) (progn @@ -287,6 +296,9 @@ (setq ks-aus (cadr (assoc "KS_AUS" ks-data))) ;; Block mit XScale einfuegen und rotieren (setq block-obj (vla-InsertBlock modelspace (vlax-3D-point '(0 0 0)) blockname scale 1.0 1.0 0)) + ;; Einzelteil auf die eigene Ebene der Blockdefinition legen - wie in den + ;; Zwillingen in ssg_ks_insert.lsp; hier fehlte der Aufruf bisher. + (ssg-ils-block-auf-ebene block-obj blockname) (vla-TransformBy block-obj (vlax-tmatrix (vf-rot-matrix chz shz cv sv))) (if (and ks-ein ks-aus) (progn diff --git a/Lisp/vf_linienzug.lsp b/Lisp/vf_linienzug.lsp index 618d9a9..f7a5ab1 100644 --- a/Lisp/vf_linienzug.lsp +++ b/Lisp/vf_linienzug.lsp @@ -3269,6 +3269,9 @@ ;; temporaer auf Welt (verhindert den 31.95mm-Z-Versatz bei abweichendem ;; BKS, siehe Kommentar dort) und stellt es danach wieder her. (setq vfl-insert (ssg-block-wrap-welt vfl-bname startpunkt vfl-ss)) + ;; Ziel-Layer der Baugruppe aus cfg/layer.cfg (ohne Eintrag bleibt die + ;; Referenz auf dem aktuellen Layer, wie vor der Umstellung). + (ssg-layer-setzen vfl-insert "variofoerderer") ;; Werte (volle Liste; nicht vorhandene Tags ignoriert ssg-attrib-set-on) (ssg-attrib-set-on vfl-insert (list @@ -6705,6 +6708,9 @@ (ssadd (entlast) merge-ss) ) (setq neuer-insert (ssg-block-wrap-welt neuer-bname chain-start merge-ss)) + ;; Ziel-Layer der Baugruppe aus cfg/layer.cfg (ohne Eintrag bleibt die + ;; Referenz auf dem aktuellen Layer, wie vor der Umstellung). + (ssg-layer-setzen neuer-insert "variofoerderer") (ssg-attrib-set-on neuer-insert aggregiert) ;; SEITE_AS/SEITE_ES explizit leeren, wenn die Kette (Ausnahmefall) ohne ;; eigenes AS-/ES-Element beginnt/endet - ssg-attrib-set-on wuerde einen diff --git a/cfg/layer.cfg b/cfg/layer.cfg new file mode 100644 index 0000000..aabaa9b --- /dev/null +++ b/cfg/layer.cfg @@ -0,0 +1,183 @@ +# ============================================================ +# layer.cfg - Ziel-Layer (und Layerfarbe) je Baugruppe +# +# Gilt fuer die Baugruppen, die von den Makros aus Einzelteilen ZUSAMMENGEBAUT +# und als neuer Block eingefuegt werden (KREISEL_n, ECKRAD_n, VF_n, GF_n) sowie +# fuer die Hilfsgeometrie, die die Makros selbst zeichnen (Tangenten, PIN-Linien, +# Beschriftungstexte). Fuer diese Baugruppen gibt es keine Blockdatei in data/ +# und damit auch kein LAYER-Attribut - der Layer muss hier festgelegt werden. +# +# NICHT hier eingetragen werden Bloecke, die nur aus data/ EINGEFUEGT werden +# (Vario_*, Staustrecke_*, AS/ES-Element, Gefaellebogen_*, Modulweiche_*, +# BTMT-Beladung, SC_Entladung, Scanner, Separator_SP, Omniflo-Module ...): +# die tragen ihren Ziel-Layer als Block-Attribut LAYER, und dieses Attribut +# gilt als Vorgabe (siehe ssg-block-layer-vorgabe in Lisp/ssg_core.lsp). +# Gepflegt werden diese Attribute in data/ils/allocations_collected.json bzw. +# direkt in den DWG-Dateien. +# +# ------------------------------------------------------------ +# Format: INI-Style, gelesen von ssg-load-ini/ssg-ini-get (Lisp/ssg_core.lsp) +# +# [Abschnitt] +# baugruppe = Layername, Farbnummer +# +# - Abschnitt = "ils_2d"/"ils_3d" fuer dimensionsabhaengige Layer, +# "allgemein" fuer Layer, die in beiden Dimensionen gleich heissen. +# Aufgeloest wird in dieser Reihenfolge: [ils_], +# dann [allgemein]. Die aktuelle Dimension liefert ssg-ils-dim-aktuell +# (transienter Override *ssg-ils-dim* -> DXFM_DIM -> "3D"). +# Sonderfall [farben] siehe unten. +# - Key = Baugruppen-Schluessel, mit dem der Lisp-Code nachfragt +# (ssg-layer-eintrag/-anlegen/-setzen). Klein geschrieben, KEINE Umlaute. +# - Wert = Layername, dann Komma, dann Farbnummer (BricsCAD-Farbindex 1-255). +# Der Layername steht VOR dem ersten Komma - Layernamen duerfen ohnehin +# kein Komma enthalten. Fehlt die Farbe, wird 7 (weiss/schwarz) verwendet. +# - LEERER Wert (oder fehlender Key) = keine Zuordnung. Der Code laesst den +# Layer dann unangetastet, das Verhalten ist genau wie ohne diese Datei. +# Eine fehlende layer.cfg ist also kein Fehler. +# +# WICHTIG - Kommentare: +# Nur ZEILEN, die mit # beginnen, sind Kommentare. Es gibt KEINE +# Inline-Kommentare: alles hinter dem ersten "=" ist Wert. Erklaerungen +# also immer in eine eigene Zeile ueber den Key schreiben. +# +# WICHTIG - Farbe (wann sie greift und wann nicht): +# ssg-make-layer setzt die Farbe nur bei der NEUANLAGE des Layers. Existiert +# der Layer in der Zeichnung schon, bleibt seine Farbe unveraendert - so +# werden Layer-Einstellungen in bestehenden Zeichnungen nie ueberschrieben. +# Daraus folgen zwei Faelle: +# a) Layer, den unsere Makros anlegen (z.B. _3D_ILS_Kreisel, +# _3D_ILS_Fingerfoerderer, S_KRS_BESCHR): die Farbe von hier greift. +# b) Layer, den eine Blockdatei aus data/ils mitbringt (z.B. ILS_SP / +# _3D_ILS_SP, ILS_SEP-SP): BricsCAD legt ihn schon beim Einfuegen des +# Blocks mit der Farbe AUS DER DWG an - lange bevor der Wrapper gebaut +# wird. Die Farbe von hier greift dann NICHT; die Blockbibliothek +# bestimmt sie. Wer sie aendern will, aendert sie in der DWG (oder +# nachtraeglich per Layer-Dialog in der Zeichnung). +# Der Layername selbst greift in beiden Faellen - nur um die Farbe geht es. +# +# WICHTIG - Kodierung: +# Diese Datei ist reines ASCII, damit sie in jedem Editor unveraendert bleibt. +# Alle hier vergebenen Layernamen sind ASCII. Falls einmal ein Layername mit +# Umlaut oder Gradzeichen eingetragen werden muss (der Firmenstandard in +# doc/layer-definitionen.xlsx enthaelt solche, z.B. "Bemassung" mit ss-Zeichen +# oder "_3D_ILS_30Bogen"), dann MUSS die Datei in ANSI/CP1252 gespeichert +# werden - BricsCAD liest sie per (read-line) in der ANSI-Codepage und der +# Layername muss byteweise zum Layer in der Zeichnung passen. Ein UTF-8- +# gespeicherter Umlaut ergibt einen falschen Layernamen. +# +# Loest den frueheren Entwurf "cfg/layer - Kopie.cfg" ab (dort war die Richtung +# umgekehrt: Layer -> Blockmuster, ohne Farbe, und alle Werte waren leer). +# ============================================================ + + +# ============================================================ +# ILS 2D +# ============================================================ +[ils_2d] + +# ILS Kreisel, Standard (Wrapper-Block KREISEL__STANDARD_) +# Die enthaltenen Teile tragen gemischte Attribute (AN8_2D -> ILS_ANTR, +# SP8_2D -> ILS_UMLENK); fuer die Baugruppe selbst gibt es kein Attribut. +# Vorbelegung aus dem Firmenstandard: ILS_LP = "Laufprofil (Kreisel)". +# Alternativen, falls die Baugruppe nach ihrer Antriebsstation sortiert +# werden soll: ILS_ANTR bzw. ILS_Strukturprofil. +kreisel = ILS_LP, 7 + +# ILS Kreisel, PIN-Variante (Wrapper-Block KREISEL__PIN_) +# Eigener Key, damit PIN-Kreisel bei Bedarf getrennt geschaltet werden koennen +# (z.B. ILS_PIN-Bereich oder "ILS_LP Halter PIN"). Vorbelegt wie kreisel. +kreisel_pin = ILS_LP, 7 + +# ILS Eckrad (Wrapper-Block ECKRAD_) +# Aus AN8 + Umfahrungsgeometrie zusammengebaut. Alternative aus dem +# Firmenstandard: ILS_Umfahrung ("Umfahrungsboegen an Kreisel"). +eckrad = ILS_LP, 7 + +# Vario-Foerderanlage (Wrapper-Block VF_; Standard, Etage, Linienzug, Merge) +# LAYER-Attribut der enthaltenen Vario_*-Bloecke. +variofoerderer = ILS_Fingerfoerderer, 4 + +# Gefaelle-Foerderanlage (Wrapper-Block GF_) +# LAYER-Attribut der enthaltenen Staustrecke_*- und Gefaellebogen_*-Bloecke. +# HINWEIS: ILS_SP bringen diese Bloecke selbst mit (Fall b oben) - die Farbe +# hier bleibt daher wirkungslos, solange die DWG den Layer definiert. +gefaellestrecke = ILS_SP, 3 + + +# ============================================================ +# ILS 3D +# ============================================================ +[ils_3d] + +# Wie ils_2d, aber mit den 3D-Layernamen. +# Fuer den zusammengebauten Kreisel nennt der Firmenstandard _3D_ILS_Kreisel +# (die Einzelteile tragen _3D_ILS_ANTR bzw. _3D_ILS_UMLENK). +kreisel = _3D_ILS_Kreisel, 7 + +kreisel_pin = _3D_ILS_Kreisel, 7 + +eckrad = _3D_ILS_Kreisel, 7 + +# LAYER-Attribut der enthaltenen Vario_*_3D-Bloecke. +variofoerderer = _3D_ILS_Fingerfoerderer, 4 + +# LAYER-Attribut der enthaltenen Staustrecke_*_3D-/Gefaellebogen_*_3D-Bloecke. +# HINWEIS zur Farbe: siehe ils_2d (Layer kommt aus der DWG, Fall b im Header). +gefaellestrecke = _3D_ILS_SP, 3 + + +# ============================================================ +# Dimensionsunabhaengig: vom Code gezeichnete Hilfsgeometrie +# ============================================================ +[allgemein] + +# Kreisel-Tangenten (die beiden Linien zwischen AN8 und SP8). +# HINWEIS: "S_LP" ist der bisher hart im Code stehende Name. Der +# Firmenstandard kennt nur "ILS_LP" - S_LP ist sehr wahrscheinlich ein +# Tippfehler aus der Anfangszeit. Bewusst NICHT automatisch umbenannt, weil +# bestehende Zeichnungen den Layer S_LP enthalten. Bei Umstellung hier auf +# ILS_LP aendern (und die Altbestaende per Layer-Umbenennung nachziehen). +kreisel_tangente = S_LP, 7 + +# PIN-Linien im Kreisel (nur bei PIN-Variante gezeichnet). +kreisel_pinbereich = pinbereich, 3 + +# Beschriftungstext des Kreisels (Laenge/Bezeichnung). +kreisel_beschriftung = S_KRS_BESCHR, 7 + +# Beschriftungstext der Vario-Foerderanlage (Hoehen-/Sektionslabel). +vf_beschriftung = VF_Beschriftung, 7 + +# Beschriftungstext der Gefaellestrecke. +gf_beschriftung = GF_Beschriftung, 7 + + +# ============================================================ +# Farben fuer Layer OHNE Baugruppen-Key +# ============================================================ +# Hier stehen Farben fuer Layer, die aus dem LAYER-Attribut eines eingefuegten +# Blocks bzw. aus der Blockdefinition kommen und daher oben keinen +# Baugruppen-Key haben. Format: Layername = Farbnummer. +# +# Gelesen von ssg-layer-farbe-fuer-name (ssg_core.lsp) beim ANLEGEN des Layers. +# Ein Layername, der oben schon als Wert einer Baugruppe vorkommt, braucht hier +# keinen Eintrag - die Farbe wird dort mitgelesen. Nicht aufgefuehrte Layer +# werden wie bisher mit Farbe 7 angelegt. +# +# Beispiele (auskommentiert - eintragen, was gewuenscht ist): +[farben] +#ILS_ANTR = 1 +#ILS_UMLENK = 2 +#ILS_AS = 5 +#ILS_ES = 5 +#ILS_SEP-SP = 82 +#ILS_Modulweiche = 6 +#ZZ_Scanner = 6 +#_3D_ILS_ANTR = 1 +#_3D_ILS_UMLENK = 2 +#_3D_ILS_AS = 5 +#_3D_ILS_ES = 5 +#_3D_ILS_SEP-SP = 82 +#_3D_ILS_Anbaugruppen = 6 +#_3D_ZZ_Scanner = 6 diff --git a/doc/layer-definitionen.xlsx b/doc/layer-definitionen.xlsx index 3be1864..62ffa30 100644 Binary files a/doc/layer-definitionen.xlsx and b/doc/layer-definitionen.xlsx differ diff --git a/tests/test_unit.lsp b/tests/test_unit.lsp index 4ff9ded..bc3264e 100644 --- a/tests/test_unit.lsp +++ b/tests/test_unit.lsp @@ -135,6 +135,74 @@ (tu-eq "ssg-parse-json-array" '((("a" . 1) ("b" . 2))) (ssg-parse-json-array '("[" "{" "\"a\": 1," "\"b\": 2" "}" "]"))) + + ;; ssg-layer-cfg-eintrag: "Layername, Farbe" -> (layer . farbe) + ;; Reine Funktion, ini-Daten als Parameter - kein Datei-IO, keine Zeichnung. + (setq _lay (ssg-ini-parse-lines + '("# Kommentar" + "[ils_2d]" + "variofoerderer = ILS_Fingerfoerderer, 4" + "ohne_farbe = ILS_SP" + "leer =" + "[ils_3d]" + "variofoerderer = _3D_ILS_Fingerfoerderer, 4" + "[allgemein]" + "vf_beschriftung = VF_Beschriftung, 7"))) + (tu-eq "ssg-layer-cfg-eintrag/layer-und-farbe" + '("ILS_Fingerfoerderer" . "4") + (ssg-layer-cfg-eintrag _lay "ils_2d" "variofoerderer")) + (tu-eq "ssg-layer-cfg-eintrag/ohne-farbe-default-7" + '("ILS_SP" . "7") + (ssg-layer-cfg-eintrag _lay "ils_2d" "ohne_farbe")) + (tu-nil "ssg-layer-cfg-eintrag/leerer-wert" + (ssg-layer-cfg-eintrag _lay "ils_2d" "leer")) + (tu-nil "ssg-layer-cfg-eintrag/key-fehlt" + (ssg-layer-cfg-eintrag _lay "ils_2d" "gibtsnicht")) + (tu-nil "ssg-layer-cfg-eintrag/sektion-fehlt" + (ssg-layer-cfg-eintrag _lay "gibtsnicht" "variofoerderer")) + + ;; ssg-layer-eintrag: Aufloesung [ils_] -> [allgemein]. + ;; Dimension und cfg werden hier injiziert (kein Datei-IO); der gemerkte + ;; Ladeversuch verhindert, dass ssg-layer-cfg-load die echte Datei liest. + (setq _lay-cfg-alt *ssg-layer-cfg* + _lay-vers-alt *ssg-layer-cfg-versucht* + _lay-dim-alt (if (boundp '*ssg-ils-dim*) *ssg-ils-dim*)) + (setq *ssg-layer-cfg* _lay *ssg-layer-cfg-versucht* T) + (setq *ssg-ils-dim* "2D") + (tu-eq "ssg-layer-eintrag/dim-2d" + '("ILS_Fingerfoerderer" . "4") (ssg-layer-eintrag "variofoerderer")) + (tu-eq "ssg-layer-eintrag/fallback-allgemein" + '("VF_Beschriftung" . "7") (ssg-layer-eintrag "vf_beschriftung")) + (setq *ssg-ils-dim* "3D") + (tu-eq "ssg-layer-eintrag/dim-3d" + '("_3D_ILS_Fingerfoerderer" . "4") (ssg-layer-eintrag "variofoerderer")) + (tu-nil "ssg-layer-eintrag/unbekannte-baugruppe" + (ssg-layer-eintrag "gibtsnicht")) + + ;; ssg-layer-farbe-fuer-name: Farbe zu einem LAYERNAMEN (nicht Baugruppe). + ;; Wird gebraucht, weil Layer aus dem LAYER-Attribut oft VOR dem Wrapper + ;; angelegt werden und ssg-make-layer die Farbe nur bei Neuanlage setzt. + (setq *ssg-layer-cfg* (ssg-ini-parse-lines + '("[ils_3d]" + "gefaellestrecke = _3D_ILS_SP, 3" + "[allgemein]" + "vf_beschriftung = VF_Beschriftung, 7" + "[farben]" + "ILS_SEP-SP = 82"))) + (tu-eq "ssg-layer-farbe-fuer-name/abschnitt-farben" + "82" (ssg-layer-farbe-fuer-name "ILS_SEP-SP")) + (tu-eq "ssg-layer-farbe-fuer-name/aus-baugruppen-wert" + "3" (ssg-layer-farbe-fuer-name "_3D_ILS_SP")) + (tu-eq "ssg-layer-farbe-fuer-name/case-insensitiv" + "3" (ssg-layer-farbe-fuer-name "_3d_ils_sp")) + (tu-eq "ssg-layer-farbe-fuer-name/unbekannt-default-7" + "7" (ssg-layer-farbe-fuer-name "GibtsNicht")) + (tu-eq "ssg-layer-farbe-fuer-name/leerer-name" + "7" (ssg-layer-farbe-fuer-name "")) + ;; Globale Zustaende wieder herstellen + (setq *ssg-ils-dim* _lay-dim-alt + *ssg-layer-cfg* _lay-cfg-alt + *ssg-layer-cfg-versucht* _lay-vers-alt) )