diff --git a/CLAUDE.md b/CLAUDE.md index 462a468..48dbdc5 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -23,7 +23,7 @@ AutoLISP-Makros (SSG_LIB) fuer BricsCAD Pro zur automatisierten Erstellung von F | `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); Geruest: `geruest.json` (GERUEST-Dialog) und `geruest_traeger.json` (Traeger mit Linien-Logik) | +| `data/json/` | Komponentendaten (Masse, Sivas-IDs); Geruest: `geruest.json` (GERUEST-Dialog) und `geruest_traeger.json` (Traeger mit Linien-Logik); `omniflo_fahrstrecke.json` (Omniflo-Fahrstrecke, gleiche Linien-Logik) | | `data/block_libraries/` | DXF Block-Libraries (ils_library.dxf) | | `cfg/rahmen/` | DIN-Rahmen + Schriftkopf-DWGs (A0-A4, Kopf11 DE/EN/FR/IT), kopiert aus `\\infor-ln\SSG_Tools\ACADSST\KOEPFE`, fuer `DIN_FORMATE` (DinFormate.lsp) | | `dcl/` | DCL-Dialogdefinitionen | @@ -75,8 +75,8 @@ Die `start_briscad.bat` ruft `setenv.bat` auf und startet BricsCAD. | Zusatzmodul/Foerderer/Kurven | `SSG_LIB_Commands` | ILS_BTMT_*, ILS_ETF_*, 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_LADESCHLEIFE_*, OMNI_EDIT | -| Geruest | `GeruestInsert` | GERUEST_SAEULEN, GERUEST_ROHRABHAENGER, GERUEST_WANDBEFESTIGUNG (derselbe Dialog, im jeweiligen Bereich geoeffnet), GERUEST_TRAEGER (eigener Dialog), GERUEST_TRAEGER_BESCHRIFTEN (Untermenue Geruest -> Funktionen -> Traeger beschriften; alle Traeger der Zeichnung neu beschriften); Gattertraeger noch Platzhalter auf GERUEST | +| Omniflo (komplett) | `OmniModulInsert` + `GeruestInsert` | OMNI_APB_*, OMNI_W*_*, OMNI_AP*, OMNI_TEF_*, OMNI_TV_*, OMNI_LADESCHLEIFE_*, OMNI_EDIT; OMNI_FAHRSTRECKE / OMNI_FAHRSTRECKE_BESCHRIFTEN (GeruestInsert, Linien-Logik wie GERUEST_TRAEGER) | +| Geruest | `GeruestInsert` | GERUEST_SAEULEN, GERUEST_ROHRABHAENGER, GERUEST_WANDBEFESTIGUNG (je eigener Dialog aus der Vorlage geruest.dcl, keine Umschaltung), GERUEST_TRAEGER (eigener Dialog), GERUEST_TRAEGER_BESCHRIFTEN (Untermenue Geruest -> Funktionen -> Traeger beschriften; alle Traeger der Zeichnung neu beschriften); Gattertraeger noch Platzhalter auf GERUEST (zeigt nur einen Hinweis) | | Connections | `Connection_Edit` + `SSG_LIB_Commands` | CONNECTION_INSERT, CONNECTION_EDIT, ILS_EINGANG_INSERT, ILS_AUSGANG_INSERT | | Export | `export` | EXPORTSIVAS, EXPORTCSV, CALLPYTHON | | Werkzeuge | `ssg_blocktools`, `ssg_texttools`, `ssg_stueckliste`, `DinFormate` | SSG_BLOCK_COUNT, SSG_BLOCK_DELETE, SSG_ATTR_ERSETZEN, SSG_TEXT_ERSETZEN, SSG_TEXT_PARALLEL, SSG_TEXT_HOEHE, SSG_TEXT_STIL, SSG_FAEHNCHEN_STUECKLISTE, DIN_FORMATE | @@ -95,7 +95,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). **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. **JSON**: drei Parser nebeneinander, bewusst nicht zusammengelegt - `ssg-load-json`/`ssg-parse-json-array` (flaches Array von Objekten) und `ssg-cfg-parse-nested` (genau 1 Ebene) sind ZEILENbasiert und koennen weder echte Verschachtelung noch mehrzeilige Arrays, maskierte Anfuehrungszeichen (`\"`) oder Kommas in Strings lesen; ihre Konsumenten (Konfiguration, Sprache, VF-Spec) sind auf dieses Verhalten eingestellt und bleiben unangetastet. Fuer alles andere `ssg-json-laden`/`ssg-json-parse`/`ssg-json-get` (rekursiver Descent-Parser ueber einen Positionszeiger): Objekt -> Alist, Array -> Liste, true -> T, false/null -> nil (beide nil, "Feld fehlt" ist also nicht von "Feld ist false" unterscheidbar), `\uXXXX` nur fuer ASCII. In `tests/test_unit.lsp` (`tu-tests-json`) gegen die echte Geruest-Datendatei getestet. Dazu `ssg-join` (Liste + Trennzeichen -> String). `ssg-lastent-ohne-attribute`: Startmarke fuer "alles Neue seit Marke per entnext einsammeln" - statt nacktem `(entlast)` verwenden, sonst laeuft `entnext` in die ATTRIBs/SEQEND eines vorherigen Attribut-Blocks und `_.-BLOCK` entfernt sie dort (realer Bug: per Strg+C/V kopierter GR_-Block verlor beim naechsten GERUEST seine Attribute; Test `tests/test_lastent.lsp`) | +| `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. **JSON**: drei Parser nebeneinander, bewusst nicht zusammengelegt - `ssg-load-json`/`ssg-parse-json-array` (flaches Array von Objekten) und `ssg-cfg-parse-nested` (genau 1 Ebene) sind ZEILENbasiert und koennen weder echte Verschachtelung noch mehrzeilige Arrays, maskierte Anfuehrungszeichen (`\"`) oder Kommas in Strings lesen; ihre Konsumenten (Konfiguration, Sprache, VF-Spec) sind auf dieses Verhalten eingestellt und bleiben unangetastet. Fuer alles andere `ssg-json-laden`/`ssg-json-parse`/`ssg-json-get` (rekursiver Descent-Parser ueber einen Positionszeiger): Objekt -> Alist, Array -> Liste, true -> T, false/null -> nil (beide nil, "Feld fehlt" ist also nicht von "Feld ist false" unterscheidbar), `\uXXXX` nur fuer ASCII. In `tests/test_unit.lsp` (`tu-tests-json`) gegen die echte Geruest-Datendatei getestet. Dazu `ssg-join` (Liste + Trennzeichen -> String). **DCL-Vorlagen**: `ssg-dcl-vorlage-fuellen` (Vorlage lesen, Markerzeilen `//@NAME@` durch erzeugte Zeilen ersetzen - reiner Kern `ssg-dcl-zeilen-ersetzen`, getestet - und per `ssg-dcl-temp-schreiben` als Temp-Datei schreiben) fuer Dialoge mit fester Grundstruktur und einzelnen datenabhaengigen Bloecken. `ssg-lastent-ohne-attribute`: Startmarke fuer "alles Neue seit Marke per entnext einsammeln" - statt nacktem `(entlast)` verwenden, sonst laeuft `entnext` in die ATTRIBs/SEQEND eines vorherigen Attribut-Blocks und `_.-BLOCK` entfernt sie dort (realer Bug: per Strg+C/V kopierter GR_-Block verlor beim naechsten GERUEST seine Attribute; Test `tests/test_lastent.lsp`) | | `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) | @@ -113,7 +113,7 @@ Detaillierte Dokumentation aller Funktionen und Befehle: siehe `Lisp/README.md`. | `OmniModulInsert.lsp` | OMNI_LOAD, OMNI_APB_*, OMNI_W*_*, OMNI_AP60/AP110, OMNI_TEF_*, OMNI_TV_*, OMNI_APBW_*, OMNI_LADESCHLEIFE_AP110, OMNI_EDIT | Omniflo-Komponenten: Boegen, Weichen, Verbinder, Transferwagen, Ladeschleifen (`data/json/omniflo_ladeschleifen.json`, per `ssg-json-laden`, da die Beschreibungen Kommas enthalten; Blockdatei darf `.dwg` statt `.dxf` sein), Edit-Dialog | | `SSG_LIB_Commands.lsp` | ILS_BTMT_Beladung, ILS_BTMT_Entladung, ILS_SCANNER_INSERT, ILS_SEPARATOR_INSERT, ILS_EINGANG_INSERT, ILS_AUSGANG_INSERT, ILS_ETF_*, 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`) + Eingang-/Ausgang-Symbol (frei platzierbar wie BTMT Be-/Entladung, ueber `ils-insert-station` mit den Rohnamen `Eingang`/`Ausgang`, Bloecke `Eingang_.dwg`/`Ausgang_.dwg` in data/ils) + Dummy-Befehle fuer Menue + Doppelklick/Kontextmenue-Dispatcher + Konfiguration (2D/3D, Sprache) | | `Tro_Edit.lsp` | TRO_INSERT, TRO_EDIT | TRO-Marker (Block `TRO_SYM_`) 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. | -| `GeruestInsert.lsp` | GERUEST, GERUEST_SAEULEN, GERUEST_ROHRABHAENGER, GERUEST_WANDBEFESTIGUNG, GERUEST_TRAEGER, GERUEST_TRAEGER_BESCHRIFTEN | Geruest-Baugruppen aus `data/json/geruest.json` konfigurieren und einfuegen. **Ein Dialog fuer alle Bereiche**: oben ein Dropdown `bereich` (Rohrabhaenger / Saeulen / Wandbefestigung, Reihenfolge = Dateireihenfolge, Anzeigename aus dem ASCII-Feld `titel`). DCL hat **kein Reiter-Tile**, und da sich die Teilezeilen je Bereich unterscheiden, schliesst ein Bereichswechsel den Dialog (`done_dialog 4`) und die Schleife in `c:GERUEST` baut ihn neu auf; der Stand jedes Bereichs bleibt in `*geruest-zustand*` erhalten, ein versehentlicher Wechsel verwirft also nichts. 1"- und 2"-Saeulen liegen in EINER Baugruppe `Saeulen` mit gemeinsamer Anbauteil-Liste; **`teileart` und `dummy` duerfen je Geometrie-Variante ueberschrieben werden** (`geruest-variante-wert`, Variante gewinnt vor Baugruppe; fuer `dummy` ueber `geruest-dummy-wahl`: fehlt die DWG der Variante, Meldung + Rueckfall auf den Baugruppen-Dummy; ist der Dummy zugleich eine Teile-DWG, wird er per `geruest-ohne-pfad` nicht doppelt eingefuegt) - so liefert `R 1"` weiterhin TEILEART `Geruest Saeule 1 Zoll` und die `R 2"`-Varianten `Geruest Saeule 2 Zoll`, die Groessen bleiben im Export also unterscheidbar. **Die Dialogdefinition wird zur Laufzeit erzeugt** (`geruest-dcl-schreiben` -> temporaere Datei per `vl-filename-mktemp`, nach `unload_dialog` wieder geloescht) - es gibt KEINE `dcl/geruest.dcl`. Grund: je Anbauteil wird ein eigenes Mengenfeld gebraucht, und eine DCL-Liste (`list_box`) kann keine Eingabefelder enthalten; DCL kann weder Dateien einbinden noch Tiles zur Laufzeit erzeugen. Inhalt: Basis-Variante aus `geometrie_varianten` (Dropdown), Laenge (gegen `attribute.Laenge` min/max geprueft, Retry-Schleife), Farbe (`attribute.Teilefarbe`, Freitext bei `frei_option`) und **zwei Befestigungslisten** ("oben"/"unten"), die BEIDE alle `anbaugruppen` enthalten - dasselbe Teil kann oben, unten oder gleichzeitig an beiden Positionen sitzen, je mit eigener Anzahl. **Zwei Mengenfelder im JSON, bewusst verschieden benannt**: `stueckzahl` = wie oft ein Teil TATSAECHLICH geschrieben wird (je Variante bzw. je Satz/Anbauteil, fehlt = 1), `anzahl_vorgabe` = NUR die Vorbelegung des Anzahl-Feldes im Dialog (Anbaugruppen, fehlt = 1); ein Anbauteil wird Anzahl x `stueckzahl` mal geschrieben, bei einer Gruppe (`teile`) zaehlt die Anzahl die Saetze (`geruest-stueckzahl`/`geruest-anzahl-vorgabe`). In Konfigurationen (`oben`/`unten`) heisst der gespeicherte Dialogwert `anzahl`. Baugruppen ohne `attribute`-Block (Wandbefestigung) bekommen Laenge/Farbe gesperrt, Baugruppen ohne Anbauteile bekommen gar keine Spalten (ein leerer DCL-Cluster ist unzulaessig). Im generierten Label wird `"` zu `''` ersetzt (`geruest-dcl-label`) - fuenf Artikelnamen enthalten ein Anfuehrungszeichen, das das DCL-Label sonst vorzeitig beendet und die Datei zerstoert. **Konfigurationen**: gepflegte Bibliothek je Baugruppe unter `konfigurationen` in `geruest.json` (schreibgeschuetzt) plus eigene in `cfg/geruest_user.json` (gitignored, `geruest-user-schreiben`; getrennte Datei, damit Benutzerdaten und versionierte Bibliothek nicht kollidieren). Eigene Eintraege sind in der Liste mit `*` markiert und nur diese loeschbar. Konfigurationen verweisen ueber den ANZEIGENAMEN auf Variante und Anbauteile; ein unbekannter Name wird gemeldet und uebersprungen, statt die Konfiguration scheitern zu lassen. Speichern/Loeschen laufen ueber `done_dialog 2`/`3` (Dialog schliessen, Aktion, neu zeigen) - `getstring` funktioniert aus einem `action_tile`-Rueckruf heraus nicht. Der Block wird - wie KREISEL_n/VF_n - SELBST zusammengebaut: Dummy-DWG aus `data/geruest` liefert nur Geometrie, das Attribut-Schema kommt aus `*geruest-attrib-defs*` (ID, ARTINR, LAENGE, BEZEICHNUNG, TEILEART, TEILEFARBE, LAYER) und wird per `ssg-attrib-merge` mit den Dummy-Tags zusammengefuehrt - sonst verschluckt `ssg-attrib-set-on` stillschweigend jeden Tag, den die Dummy-DWG nicht als ATTDEF kennt. **Teile-Geometrie**: jede ausgewaehlte Artikelnummer (Basis/oben/unten inkl. aufgeloester Gruppen), fuer die `data/geruest/.dwg` existiert, wird zusaetzlich einmal bei 0,0,0 mit in den Block eingefuegt (`geruest-teile-dwgs`, dedupliziert, fehlende DWGs still uebergangen) - reine visuelle Rueckmeldung, die Attribut-Logik bleibt davon unberuehrt. **TEILEFARBE** ist eine kommagetrennte Liste parallel zu ARTINR (z.B. `,,RAL7030,,RAL7030`): Teile mit `"farbig": true` in `geruest.json` (je Artikel; eine Gruppe vererbt es an ihre Teile, fehlend = false) bekommen die im Dialog gewaehlte Baugruppenfarbe, alle anderen einen leeren Eintrag. ARTINR und TEILEFARBE entstehen aus demselben Durchlauf (`geruest-teile-paare`/`-paare-n`, `geruest-farbliste`), sind also garantiert gleich lang. `export_sivas.py` schreibt daraus je Artikelnummer das Merkmal `{"108": ""}` in `details` (Nummer aus `cfg/export.cfg` `[Sivas] merkmal_teilefarbe`). Blockname `GR__` (Kollisionszaehler wie in OmniModulInsert). **Das `GR_`-Praefix ist nicht kosmetisch**: `SSG_BLOCKEDIT` haelt JEDEN Block mit TEILEART-Attribut fuer ein Omniflo-Element, deshalb steht in `SSG_LIB_Commands.lsp` ein `GR_*`-Zweig VOR dem Omniflo-Zweig. ARTINR listet jede Sivas-ID so oft, wie Anzahl x `stueckzahl` es vorgeben - erst Basis, dann Befestigung oben, dann unten; bei einer benannten Gruppe (`teile`) wird das ganze Set n-mal wiederholt, die Mengen INNERHALB des Sets bleiben dabei erhalten (`geruest-artikelnummern-n`). BEZEICHNUNG nennt Position und Menge je Teil ("oben 2x ...") und verkettet mit `" + "`, NICHT mit Komma - die Artikelbezeichnungen enthalten selbst Kommas ("ROHR R 1\" 33,7 x 2,6"). Zuordnung Menue -> JSON laeuft ueber das ASCII-Feld `id`, weil die aeusseren JSON-Schluessel Umlaute bzw. Anfuehrungszeichen tragen. CSV-/Sivas-Export: `pattern_geruest = GR_*` (cfg/export.cfg), `csv:collect-export-blocks`/`ssg-id-collect-blocks` sammeln GR_-Bloecke wie BTMT eigenstaendig; `*geruest-attrib-defs*` traegt zusaetzlich ein leeres `ID`-ATTDEF (Voraussetzung fuer `ssg-id-check-all`, das nur bestehende ATTRIBs beschreiben kann). ARTINR/BEZEICHNUNG/TEILEART/LAENGE landen in export_csv.py/export_sivas.py in festen Spalten, TEILEFARBE/LAYER (+ ARTINR bei export_csv.py) im Merkmale-/details-JSON. **Attribut-Keys in `geruest.json` sind GROSS** (`LAENGE`, `TEILEFARBE`, ...) = die Block-Attribut-Tags; `ssg-json-get` unterscheidet Gross/Klein. **Rohr-Geruest-Traeger** (`GERUEST_TRAEGER`): Traeger-Baugruppen mit Linien-Logik liegen in einer EIGENEN Datei `data/json/geruest_traeger.json` (gleicher Aufbau wie geruest.json, eigener Lader/Cache `geruest-traeger-daten`, Suche `geruest-baugruppe id daten`; gemeinsamer Lader `geruest-json-laden-cache`) - sie tauchen darum nicht im Bereichs-Dropdown von GERUEST auf; dort kann spaeter auch der Gattertraeger hin. eigener fester Dialog `dcl/geruest_traeger.dcl` (Variante, Farbe, je eine Checkbox + Feld fuer `LAENGENABZUGANFANG`/`LAENGENABZUGENDE`, Vorgabe `vorgabe`/`aktiv` aus dem attribute-Block, je Variante ueberschreibbar via `geruest-attr-feld`); danach Einfuege-Schleife bis ESC/Enter: Startpunkt, dann Endpunkt ODER getippte Laenge (+ Richtung). Aktive Abzuege ruecken die Linie beidseitig ein (Strecke 1000, Abzug Anfang 20/Ende 35 -> Start 20 mm hinter dem Klick, Linie 945 mm); `LAENGE` = Netto-Laenge, gegen `LAENGE.min/max` geprueft. KEINE Dummy-DWG: die Geometrie ist eine per `entmake` erzeugte LINE (0,0,0)-(L,0,0) auf dem `layer` der Variante, eingefuegt mit dem Richtungswinkel (ANGBASE/ANGDIR/AUNITS dafuer kurz auf 0). **Querstreben + Muffe** als verschachtelte Dummy-DWGs im selben Block, reine Grafik ohne Export: `querstrebe.dummy` (`data/geruest/dummy_Strebe_30x4.dwg`, Basispunkt Strebenmitte, 30 mm laengs X) an jeder Strebenposition; fehlt die DWG, Rueckfall auf je eine 25-mm-Querlinie an Strebenanfang/-ende (`laenge`/`querlinie`, Standard 30/25 nur im Code). `muffe.dummy` (`dummy_Muffe_1zoll.dwg`, Basispunkt Muffenmitte) am Linienende, NUR bei Varianten mit ausdruecklichem `"mit_muffe": true` (nicht aus dem Namen geraten; bei "mit 2 Muffen" trotzdem nur eine am Ende); `querstrebe`/`muffe` per Variante ueberschreibbar (`geruest-variante-wert`). Dummys werden ohne Drehung eingefuegt (Traeger laeuft im Block entlang +X), ab dem zweiten Mal per Blockname (`geruest-dummy-einfuegen`). Verteilungs-Konfiguration `querstrebe` (`abstand`/`rand_min`/`rand_max`, Variante vor Baugruppe), Plan `geruest-traeger-streben-plan` -> (rand positionen): der Abstand zwischen zwei Streben ist IMMER genau `abstand`, beide Raender gleich (netto = k*abstand + 2*rand); gewaehlt wird die Strebenzahl, deren Rand am naechsten an `rand_min`..`rand_max` liegt (Gleichstand -> weniger Streben). Mit 500/100..250 geht das nur auf, wenn netto mod 500 = 0 oder in [200, 500) liegt (z.B. 1300 -> 150|500|500|150); sonst (1001..1199, unter 200 mm) liegt der Rand ausserhalb (1100 -> 300|500|300) - `geruest-traeger-rand-pruefen` zeigt dann eine Messagebox (ohne GUI: Konsole), der Traeger wird trotzdem eingefuegt. Schema `*geruest-traeger-attrib-defs*` = `*geruest-attrib-defs*` + die zwei Abzug-Tags; gemeinsamer Block-Schluss mit den anderen Bereichen in `geruest-block-abschliessen`. Reine Berechnung (`geruest-traeger-laenge`/`-start`/`-pruefen`, `geruest-mm-zahl`) in `tests/test_unit.lsp`. **Traeger-Beschriftung** (Checkbox im Dialog, Standard an; z.B. `RT 80/80 L=2650`): EIGENES TEXT-Objekt neben dem Block, abgeleitet NUR aus dem fertigen Block (Einfuegepunkt, DXF 50, Attribute `LAENGE` + `VARIANTE`) - darum nutzen Einfuegen und `GERUEST_TRAEGER_BESCHRIFTEN` dieselbe Funktion `geruest-traeger-beschriften`, und ein von Hand verschobener/gedrehter Traeger wird beim Neubeschriften korrekt erfasst. Verknuepfung Text -> Block per XDATA `SSG_GR_BESCHR` (1005 = Block-Handle): Neubeschriften ersetzt statt verdoppelt, der Sammelbefehl entfernt verwaiste Texte. JSON `beschriftung` (je FELD Variante vor Baugruppe, `geruest-obj-feld`): Inhalt `format` (`%1` Text, `%2` Laenge auf ganze mm) + `text` (fehlt -> Variantenname) und `layer` (je Variante verschieden, darum in JEDER Variante gepflegt - keine Baugruppen-Vorgabe; fehlt er doch, aktueller Layer); Formatierung NUR `stil`/`ausrichtung`/`hoehe` - alles andere regelt der Textstil ausserhalb, es wird kein Stil angelegt (fehlt er: Meldung, aktueller TEXTSTYLE). `ausrichtung` = Codes von TEXT "Ausrichten" (T/M/B + L/C/R), Bezugspunkt auf der Traegerlinie, L/R in LESErichtung. Textwinkel entlang des Traegers, DIN: fuer 90 < w <= 270 Grad um 180 gedreht (`geruest-text-winkel`). Noch NICHT enthalten: Edit-Pfad (GERUEST_EDIT) | +| `GeruestInsert.lsp` | GERUEST, GERUEST_SAEULEN, GERUEST_ROHRABHAENGER, GERUEST_WANDBEFESTIGUNG, GERUEST_TRAEGER, GERUEST_TRAEGER_BESCHRIFTEN, OMNI_FAHRSTRECKE, OMNI_FAHRSTRECKE_BESCHRIFTEN | Geruest-Baugruppen aus `data/json/geruest.json` konfigurieren und einfuegen. **Ein Dialog je Bereich**: Rohrabhaenger / Saeulen / Wandbefestigung oeffnen NUR ueber ihren eigenen Menuebefehl (`geruest-starten id`, Dialogtitel aus dem ASCII-Feld `titel`); eine Umschaltung im Dialog gibt es nicht (DCL hat kein Reiter-Tile), `GERUEST` ohne Bereich zeigt nur einen Hinweis. Der Dialogstand beginnt je Aufruf frisch. 1"- und 2"-Saeulen liegen in EINER Baugruppe `Saeulen` mit gemeinsamer Anbauteil-Liste; **`teileart` und `dummy` duerfen je Geometrie-Variante ueberschrieben werden** (`geruest-variante-wert`, Variante gewinnt vor Baugruppe; fuer `dummy` ueber `geruest-dummy-wahl`: fehlt die DWG der Variante, Meldung + Rueckfall auf den Baugruppen-Dummy; ist der Dummy zugleich eine Teile-DWG, wird er per `geruest-ohne-pfad` nicht doppelt eingefuegt) - so liefert `R 1"` weiterhin TEILEART `Geruest Saeule 1 Zoll` und die `R 2"`-Varianten `Geruest Saeule 2 Zoll`, die Groessen bleiben im Export also unterscheidbar. **Das Layout steht als Vorlage in `dcl/geruest.dcl`** (bzw. `dcl/geruest_traeger.dcl`); nur die datenabhaengigen Bloecke - ein `radio_button` je Variante (Key `v`, `geruest-radio-key`/`-index`), Mengenfeld + Ankreuzfeld je Anbauteil - werden zur Laufzeit an Markerzeilen `//@NAME@` eingesetzt (`geruest-dcl-ersetzungen` -> `ssg-dcl-vorlage-fuellen` in ssg_core, Temp-Datei, nach `unload_dialog` geloescht). Grund: DCL kann Tiles weder zur Laufzeit erzeugen noch ausblenden, Radiobutton-Labels lassen sich per `set_tile` nicht aendern, und eine `list_box` kann keine Eingabefelder enthalten. Varianten bewusst als Radiobuttons statt `list_box`: BricsCAD zeichnet die Listenspalte nur halb so breit, und ein `tabs`-Wert passt nur schrift-/skalierungsabhaengig. Inhalt: Basis-Variante aus `geometrie_varianten` (`list_box` mit Einfachauswahl, Hoehe nach Variantenzahl, `geruest-dcl-listenhoehe`), **Winkel Platte** (0/90 Grad, `*geruest-winkel-werte*`): Ausrichtung der Anbauteile zur Basis - die Teile-DWGs aus oben/unten/sonstiges werden um diesen Winkel um Z gedreht in den Block eingefuegt, Basis und Dummy bleiben ungedreht (`geruest-teile-dwgs-rot`; in Konfigurationen als echter Wert `winkel_platte`, kein Block-Attribut), Laenge (gegen `attribute.Laenge` min/max geprueft, Retry-Schleife), Farbe (`attribute.Teilefarbe`, Freitext bei `frei_option`) und **eine Befestigungsspalte** "Befestigung oben und unten" mit allen `anbaugruppen.befestigung` - die Anzahl ist die GESAMTanzahl je Teil (oben und unten zusammen; Tile-Keys `b`/`bm`, Zustand `*geruest-dlg-bef*`). Unter jedem Teil (auch in Sonstiges) zeigt eine Textzeile "Art.-Nr. ..." die Artikelnummer(n) (`geruest-artnr-anzeige`: Einzelteil -> `sivas_id`, Gruppe -> eindeutige Nummern der Teile; DCL kennt keine Schriftgroesse, darum normale Groesse in eigener Zeile). `anbaugruppen` ist ein Objekt mit zwei Listen: `befestigung` (Befestigungsspalte) und `sonstiges` (Teile, die weder oben noch unten sitzen, z.B. die Saeulen-Haltearme) - letztere bekommen eine eigene Zeile darunter (nur wenn nicht leer), in ARTINR/BEZEICHNUNG nach "unten" als "sonstiges" (`geruest-anbau-liste`; ein altes flaches Array gilt als `befestigung`). **Zwei Mengenfelder im JSON, bewusst verschieden benannt**: `stueckzahl` = wie oft ein Teil TATSAECHLICH geschrieben wird (je Variante bzw. je Satz/Anbauteil, fehlt = 1), `anzahl_vorgabe` = NUR die Vorbelegung des Anzahl-Feldes im Dialog (Anbaugruppen, fehlt = 1); ein Anbauteil wird Anzahl x `stueckzahl` mal geschrieben, bei einer Gruppe (`teile`) zaehlt die Anzahl die Saetze (`geruest-stueckzahl`/`geruest-anzahl-vorgabe`). In Konfigurationen (`befestigung`/`sonstiges`, dazu `winkel_platte`) heisst der gespeicherte Dialogwert `anzahl`. Aeltere Konfigurationen mit getrennten `oben`/`unten`-Listen laden weiter: deren Mengen werden zur Gesamtanzahl addiert (`geruest-konfig-befestigung`), Sonstiges-Teile darin still in die Sonstiges-Zeile umgehaengt (`geruest-konfig-sonstiges`); beim naechsten Speichern steht alles im neuen Format. Baugruppen ohne `attribute`-Block (Wandbefestigung) bekommen Laenge/Farbe gesperrt, Baugruppen ohne Anbauteile bekommen gar keine Spalten (ein leerer DCL-Cluster ist unzulaessig). Im generierten Label wird `"` zu `''` ersetzt (`geruest-dcl-label`) - fuenf Artikelnamen enthalten ein Anfuehrungszeichen, das das DCL-Label sonst vorzeitig beendet und die Datei zerstoert. **Konfigurationen**: gepflegte Bibliothek je Baugruppe unter `konfigurationen` in `geruest.json` (schreibgeschuetzt) plus eigene in `cfg/geruest_user.json` (gitignored, `geruest-user-schreiben`; getrennte Datei, damit Benutzerdaten und versionierte Bibliothek nicht kollidieren). Eigene Eintraege sind in der Liste mit `*` markiert und nur diese loeschbar. **Geaenderte Konfiguration**: beim Anwenden wird der Dialogstand als Vergleichsbasis gemerkt (`*geruest-dlg-konfig-basis*`); jede Eingabe vergleicht den aktuellen Record damit (`geruest-dlg-aenderung-pruefen`, Vergleich statt Flag - Zuruecknehmen hebt die Markierung wieder auf) und kennzeichnet den Listeneintrag mit "(geaendert)" plus Statuszeile `kstatus`. Speichern bietet bei einer gewaehlten EIGENEN Konfiguration deren Namen als Vorgabe an (Enter = ueberschreiben, `geruest-konfig-name-vorgabe`); Bibliotheks-Konfigurationen brauchen einen neuen Namen. Konfigurationen verweisen ueber den ANZEIGENAMEN auf Variante und Anbauteile; ein unbekannter Name wird gemeldet und uebersprungen, statt die Konfiguration scheitern zu lassen. Speichern/Loeschen laufen ueber `done_dialog 2`/`3` (Dialog schliessen, Aktion, neu zeigen) - `getstring` funktioniert aus einem `action_tile`-Rueckruf heraus nicht. Der Block wird - wie KREISEL_n/VF_n - SELBST zusammengebaut: Dummy-DWG aus `data/geruest` liefert nur Geometrie, das Attribut-Schema kommt aus `*geruest-attrib-defs*` (ID, ARTINR, LAENGE, BEZEICHNUNG, TEILEART, TEILEFARBE, LAYER) und wird per `ssg-attrib-merge` mit den Dummy-Tags zusammengefuehrt - sonst verschluckt `ssg-attrib-set-on` stillschweigend jeden Tag, den die Dummy-DWG nicht als ATTDEF kennt. **Teile-Geometrie**: jede ausgewaehlte Artikelnummer (Basis/oben/unten inkl. aufgeloester Gruppen), fuer die `data/geruest/.dwg` existiert, wird zusaetzlich einmal bei 0,0,0 mit in den Block eingefuegt (`geruest-teile-dwgs`, dedupliziert, fehlende DWGs still uebergangen) - reine visuelle Rueckmeldung, die Attribut-Logik bleibt davon unberuehrt. **TEILEFARBE** ist eine kommagetrennte Liste parallel zu ARTINR (z.B. `,,RAL7030,,RAL7030`): Teile mit `"farbig": true` in `geruest.json` (je Artikel; eine Gruppe vererbt es an ihre Teile, fehlend = false) bekommen die im Dialog gewaehlte Baugruppenfarbe, alle anderen einen leeren Eintrag. ARTINR und TEILEFARBE entstehen aus demselben Durchlauf (`geruest-teile-paare`/`-paare-n`, `geruest-farbliste`), sind also garantiert gleich lang. `export_sivas.py` schreibt daraus je Artikelnummer das Merkmal `{"108": ""}` in `details` (Nummer aus `cfg/export.cfg` `[Sivas] merkmal_teilefarbe`). Blockname `GR__` (Kollisionszaehler wie in OmniModulInsert). **Das `GR_`-Praefix ist nicht kosmetisch**: `SSG_BLOCKEDIT` haelt JEDEN Block mit TEILEART-Attribut fuer ein Omniflo-Element, deshalb steht in `SSG_LIB_Commands.lsp` ein `GR_*`-Zweig VOR dem Omniflo-Zweig. ARTINR listet jede Sivas-ID so oft, wie Anzahl x `stueckzahl` es vorgeben - erst Basis, dann Befestigung, dann Sonstiges; bei einer benannten Gruppe (`teile`) wird das ganze Set n-mal wiederholt, die Mengen INNERHALB des Sets bleiben dabei erhalten (`geruest-artikelnummern-n`). BEZEICHNUNG nennt Position und Menge je Teil ("Befestigung 4x ...", "sonstiges 1x ...") und verkettet mit `" + "`, NICHT mit Komma - die Artikelbezeichnungen enthalten selbst Kommas ("ROHR R 1\" 33,7 x 2,6"). Zuordnung Menue -> JSON laeuft ueber das ASCII-Feld `id`, weil die aeusseren JSON-Schluessel Umlaute bzw. Anfuehrungszeichen tragen. CSV-/Sivas-Export: `pattern_geruest = GR_*` (cfg/export.cfg), `csv:collect-export-blocks`/`ssg-id-collect-blocks` sammeln GR_-Bloecke wie BTMT eigenstaendig; `*geruest-attrib-defs*` traegt zusaetzlich ein leeres `ID`-ATTDEF (Voraussetzung fuer `ssg-id-check-all`, das nur bestehende ATTRIBs beschreiben kann). ARTINR/BEZEICHNUNG/TEILEART/LAENGE landen in export_csv.py/export_sivas.py in festen Spalten, TEILEFARBE/LAYER (+ ARTINR bei export_csv.py) im Merkmale-/details-JSON. **Attribut-Keys in `geruest.json` sind GROSS** (`LAENGE`, `TEILEFARBE`, ...) = die Block-Attribut-Tags; `ssg-json-get` unterscheidet Gross/Klein. **Rohr-Geruest-Traeger** (`GERUEST_TRAEGER`): Traeger-Baugruppen mit Linien-Logik liegen in einer EIGENEN Datei `data/json/geruest_traeger.json` (gleicher Aufbau wie geruest.json, eigener Lader/Cache `geruest-traeger-daten`, Suche `geruest-baugruppe id daten`; gemeinsamer Lader `geruest-json-laden-cache`) - sie tauchen darum nicht im Bereichs-Dropdown von GERUEST auf; dort kann spaeter auch der Gattertraeger hin. eigener Dialog aus der Vorlage `dcl/geruest_traeger.dcl` (Variante als Radiobuttons, JEDE Variante - auch die mit Muffe - mit eigenem Button, Beschriftung "Name (Artikelnummern)" ueber `geruest-varianten-label`; Varianten mit `"disabled": true` erscheinen in allen drei Geruest-Dialogen ausgegraut und nicht waehlbar (`geruest-variante-gesperrt-p`, `geruest-varianten-sperren` per `mode_tile`; Vorauswahl ueber `geruest-variante-waehlbar`/`-erste-freie-variante`; eine Konfiguration mit gesperrter Variante laesst die Auswahl unveraendert und meldet `gr-konfig-variante-gesperrt`) - bleiben aber in den Daten, damit Konfigurationen und Neubeschriften sie weiter ueber den Namen finden; eine Muffen-Checkbox gab es zwischenzeitlich, sie wurde wieder entfernt, weil die Artikelnummer der Muffen-Variante dann im Dialog nicht sichtbar war; Farbe, je eine Checkbox + Feld fuer `LAENGENABZUGANFANG`/`LAENGENABZUGENDE`, Vorgabe `vorgabe`/`aktiv` aus dem attribute-Block, je Variante ueberschreibbar via `geruest-attr-feld`); danach Einfuege-Schleife bis ESC/Enter: Startpunkt, dann Endpunkt ODER getippte Laenge (+ Richtung). Aktive Abzuege ruecken die Linie beidseitig ein (Strecke 1000, Abzug Anfang 20/Ende 35 -> Start 20 mm hinter dem Klick, Linie 945 mm); `LAENGE` = Netto-Laenge, gegen `LAENGE.min/max` geprueft. KEINE Dummy-DWG: die Geometrie ist eine per `entmake` erzeugte LINE (0,0,0)-(L,0,0) auf dem `layer` der Variante, eingefuegt mit dem Richtungswinkel (ANGBASE/ANGDIR/AUNITS dafuer kurz auf 0). **Querstreben + Muffe** als verschachtelte Dummy-DWGs im selben Block, reine Grafik ohne Export: `querstrebe.dummy` (`data/geruest/dummy_Strebe_30x4.dwg`, Basispunkt Strebenmitte, 30 mm laengs X) an jeder Strebenposition, NUR bei Varianten mit ausdruecklichem `"mit_querstrebe": true` (z.B. nicht beim `Rohr 1"`); fehlt die DWG, Rueckfall auf je eine 25-mm-Querlinie an Strebenanfang/-ende (`laenge`/`querlinie`, Standard 30/25 nur im Code). `muffe.dummy` (`dummy_Muffe_1zoll.dwg`, Basispunkt Muffenmitte) am Linienende, NUR bei Varianten mit ausdruecklichem `"mit_muffe": true` (nicht aus dem Namen geraten; bei "mit 2 Muffen" trotzdem nur eine am Ende); `querstrebe`/`muffe` per Variante ueberschreibbar (`geruest-variante-wert`). Dummys werden ohne Drehung eingefuegt (Traeger laeuft im Block entlang +X), ab dem zweiten Mal per Blockname (`geruest-dummy-einfuegen`). Verteilungs-Konfiguration `querstrebe` (`abstand`/`rand_min`/`rand_max`, Variante vor Baugruppe), Plan `geruest-traeger-streben-plan` -> (rand positionen): der Abstand zwischen zwei Streben ist IMMER genau `abstand`, beide Raender gleich (netto = k*abstand + 2*rand); gewaehlt wird die Strebenzahl, deren Rand am naechsten an `rand_min`..`rand_max` liegt (Gleichstand -> weniger Streben). Mit 500/100..250 geht das nur auf, wenn netto mod 500 = 0 oder in [200, 500) liegt (z.B. 1300 -> 150|500|500|150); sonst (1001..1199, unter 200 mm) liegt der Rand ausserhalb (1100 -> 300|500|300) - `geruest-traeger-rand-pruefen` zeigt dann eine Messagebox (ohne GUI: Konsole), der Traeger wird trotzdem eingefuegt. Schema `*geruest-traeger-attrib-defs*` = `*geruest-attrib-defs*` + die zwei Abzug-Tags; gemeinsamer Block-Schluss mit den anderen Bereichen in `geruest-block-abschliessen`. Reine Berechnung (`geruest-traeger-laenge`/`-start`/`-pruefen`, `geruest-mm-zahl`) in `tests/test_unit.lsp`. **Traeger-Beschriftung** (Checkbox im Dialog, Standard an; z.B. `RT 80/80 L=2650`): EIGENES TEXT-Objekt neben dem Block, abgeleitet NUR aus dem fertigen Block (Einfuegepunkt, DXF 50, Attribute `LAENGE` + `VARIANTE`) - darum nutzen Einfuegen und `GERUEST_TRAEGER_BESCHRIFTEN` dieselbe Funktion `geruest-traeger-beschriften`, und ein von Hand verschobener/gedrehter Traeger wird beim Neubeschriften korrekt erfasst. Verknuepfung Text -> Block per XDATA `SSG_GR_BESCHR` (1005 = Block-Handle): Neubeschriften ersetzt statt verdoppelt, der Sammelbefehl entfernt verwaiste Texte. JSON `beschriftung` (je FELD Variante vor Baugruppe, `geruest-obj-feld`): Inhalt `format` (`%1` Text, `%2` Laenge auf ganze mm) + `text` (fehlt -> Variantenname) und `layer` (je Variante verschieden, darum in JEDER Variante gepflegt - keine Baugruppen-Vorgabe; fehlt er doch, aktueller Layer); Formatierung NUR `stil`/`ausrichtung`/`hoehe` - alles andere regelt der Textstil ausserhalb, es wird kein Stil angelegt (fehlt er: Meldung, aktueller TEXTSTYLE). `ausrichtung` = Codes von TEXT "Ausrichten" (T/M/B + L/C/R), Bezugspunkt auf der Traegerlinie, L/R in LESErichtung. Textwinkel entlang des Traegers, DIN: fuer 90 < w <= 270 Grad um 180 gedreht (`geruest-text-winkel`). **Omniflo-Fahrstrecke** (`OMNI_FAHRSTRECKE`, Daten `data/json/omniflo_fahrstrecke.json`, Vorlage `dcl/fahrstrecke.dcl`): dieselbe Linien-Logik wie der Traeger, Code geteilt - `geruest-linien-starten id daten dcl-datei dlg-name` (Dialog `geruest-traeger-dialog` mit Vorlage + Dialogname als Argument, Einfuegen `geruest-traeger-einfuegen`), Beschriftung `geruest-traeger-beschriften blockEnt bg` mit der Baugruppe als Argument, Sammelbefehle je Typ ueber `geruest-linien-beschriften id daten` (Bloecke `GR__*`; verwaiste Texte werden typunabhaengig entfernt). Unterschiede stehen nur in den Daten: keine Querstreben (kein `mit_querstrebe`), Muffen-Dummy wie beim Traeger ueber den `muffe`-Block der Baugruppe (nur Varianten mit `"mit_muffe": true`), `farbig` nur bei ST/STL, Muffen-Varianten nur fuer ST/STL. Der Dialogstand bleibt je Baugruppe erhalten (`*geruest-tr-id*`; Wechsel Traeger <-> Fahrstrecke setzt ihn zurueck). Meldungstexte `gr-tr-*` nennen den Bauteilnamen aus `titel` als Platzhalter. In der Stueckliste eigene Klasse `fahrstrecke` (`GR_Fahrstrecke_*` vor dem allgemeinen `GR_*`). Noch NICHT enthalten: Edit-Pfad (GERUEST_EDIT) | | `menu-inventory.lsp` | MenuInventory | BricsCAD Diagnostik (Menuegruppen, Plugins, Startdateien) | | `DinFormate.lsp` | DIN_FORMATE | Ersatz fuer das alte ACADSST-Makro `DINFORM.LSP`/`.DCL` (SSG2-Menue "DIN-FORMATE..."): fuegt einen DIN-Rahmen (A0-A3, A4 quer/hoch) und optional einen Schriftkopf (KOPF11, Sprachen DE/EN/FR/IT) per Dialog (`dcl/dinformate.dcl`) ein. Block-DWGs liegen flach in `cfg/rahmen/` (kopiert aus `\\infor-ln\SSG_Tools\ACADSST\KOEPFE` - nur die von DINFORM.LSP tatsaechlich referenzierten Dateien: `A0`/`A1`/`A2`/`A3`/`A4Q`/`A4H.DWG` + `Kopf11`/`Kopf11e`/`Kopf11f`/`Kopf11i.dwg`). Rahmen wird im Zeichenmassstab-Faktor eingefuegt, der Kopf im Faktor/100 (Kopf-DWG ist 100x groesser als die Rahmen-DWGs angelegt) - unveraendert aus dem Original-Massstabsschema uebernommen. Blockdefinitionen werden einmalig per `_.-INSERT ... _X 0` nachgeladen (`dinformate-block-laden`), falls noch nicht in der Zeichnung vorhanden. Lazy geladen ueber `(ssg-ensure "DinFormate")`, Menue: Werkzeuge > Din Formate. | | `DrawPlanquadrate.lsp` | DRAW_PLANQUADRATE, DELETE_PLANQUADRATE, PLANQUADRATE_TOGGLE | 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 kommt NICHT aus den Zeichnungs-Extents, sondern aus derselben Blockmenge wie EXPORTCSV (`csv:collect-export-blocks`, export.lsp; siehe `plq-export-bbox`): Ursprung (Index 1) UND obere Grenze kommen BEIDE aus der tatsaechlichen Bounding-Box jedes Blocks (`csv:get-bbox`, wie `bbox_columns()`/`planquadrat_column()`/`_bbox_min()` in `lib/export_csv.py` bzw. `lib/export_planquadrat.py`), NICHT aus dem reinen Einfuegepunkt - bei einem gedrehten/exzentrisch eingefuegten Block (z.B. ein um 90 Grad gedrehter Kreisel) kann das Bounding-Box-Zentrum weit vom Einfuegepunkt abweichen; Ursprung und Zellzuordnung muessen auf derselben Referenz beruhen, sonst driften sie auseinander (realer Bug, behoben). Reine Hilfsgeometrie (Kreisel-Umfahrungsboegen als eigene Linien, Texte) zaehlt bewusst nicht mit, sonst weicht das Raster vom CSV-Export ab. `x_origin`/`y_origin` ueberschreiben den Ursprung, Fallback auf EXTMIN/EXTMAX falls keine Export-Bloecke vorhanden sind bzw. `csv:get-bbox` fuer einen Block scheitert. Spalten-/Zeilenzahl wird IMMER aufgerundet auf volle Rasterschritte, damit alle senkrechten Linien auf der letzten waagerechten enden und umgekehrt - das Raster bildet immer ein geschlossenes Rechteck. Zaehlung (alphabetisch/numerisch je Achse) als Text am linken/unteren Rand. Das fertige Raster (Linien+Texte) wird per `_.-BLOCK`/`_.INSERT` zu einem einzigen Block `ZZ_PLANQUADRATE` bei (0,0,0) zusammengefasst. Layer aus `cfg/layer.cfg` (`[allgemein]` Key `planquadrate`, Fallback `ZZ_Planquadrate`). DRAW_PLANQUADRATE entfernt vor dem Neuaufbau zuerst einen evtl. vorhandenen Block (`plq-block-entfernen`: INSERTs loeschen + `_-PURGE _B`), DELETE_PLANQUADRATE ruft nur diese Entfernung auf. PLANQUADRATE_TOGGLE ("Planquadrate an/aus", Menue: Konfiguration) prueft per `tblsearch`/`ssget "X"`, ob der Block existiert, und dispatcht auf Zeichnen bzw. Loeschen. Lazy geladen ueber `(ssg-ensure "DrawPlanquadrate")`, nicht in der Core-Ladereihenfolge. Die Planquadrat-SPALTE im CSV-Export (`export_csv.py::planquadrat_column`/`resolve_origins`, `lib/export_planquadrat.py::compute_planquadrat`/`_bbox_min`) rechnet ebenfalls durchgaengig auf Bounding-Box-Basis (nicht nur Einfuegepunkt) und liefert eine SPANNE ("A/1-J/1") statt nur einer Zelle, wenn ein Element mehr als eine Zelle ueberdeckt (Kreisel, lange VF-/GF-Ketten). | @@ -131,7 +131,9 @@ Detaillierte Dokumentation aller Funktionen und Befehle: siehe `Lisp/README.md`. | `sprache.dcl` | SSG_SPRACHE (SSG_LIB_Commands.lsp) | | `tro_insert.dcl` | TRO_INSERT (Tro_Edit.lsp) | | `tro_edit.dcl` | TRO_EDIT (Tro_Edit.lsp) | -| `geruest_traeger.dcl` | GERUEST_TRAEGER (GeruestInsert.lsp, `geruest-traeger-dialog`) | +| `geruest.dcl` | VORLAGE fuer GERUEST_SAEULEN/_ROHRABHAENGER/_WANDBEFESTIGUNG (GeruestInsert.lsp, `geruest-dialog`); Platzhalter `//@TITEL@`/`//@VARIANTEN@`/`//@BEFESTIGUNG@`/`//@SONSTIGES@` werden per `ssg-dcl-vorlage-fuellen` gefuellt, nicht direkt ladbar | +| `geruest_traeger.dcl` | VORLAGE fuer GERUEST_TRAEGER (GeruestInsert.lsp, `geruest-traeger-dialog`), Platzhalter `//@VARIANTEN@` | +| `fahrstrecke.dcl` | VORLAGE fuer OMNI_FAHRSTRECKE (GeruestInsert.lsp, `geruest-traeger-dialog`), gleiche Tile-Keys wie `geruest_traeger.dcl`, Platzhalter `//@VARIANTEN@` | | `dinformate.dcl` | DIN_FORMATE (DinFormate.lsp) | | `vfl_edit.dcl` | Linienzug-Editieren/Fortsetzen (vf_linienzug.lsp, `vfl-dlg-position`, aufgerufen aus `vfl-edit-ent`) | | `vf_linienzug_wizard.dcl` | Linienzug-Assistent (Modus 1, 2 UND 3): zwei generische Einzel-Dialoge (Zahl-Eingabe, Mehrfachauswahl; `vflw-zahl`/`vflw-wahl`, aufgerufen aus `vfl-in-real`/`vfl-in-string`/`vfl-in-int` bei aktivem `*vfl-wizard-mode*`) PLUS sieben Gruppen-Dialoge, die mehrere immer unmittelbar aufeinanderfolgende Fragen in einem Bildschirm zusammenfassen (Kettenstart, AS-Element, GF-Bogen, ES-Element, Vario-Kurve, Gefaelle festlegen, Ziel-Hoehe, Horizontales Stueck - inkl. Punktwahl-Button mit X/Y/Z-Anzeige; `vflw-gruppe-*-impl` in vf_linienzug.lsp fuellen dafuer vorab eine kleine Pending-Queue `*vflw-pending*`, die einzelnen `vfl-in-*`-Aufrufe bleiben dabei unveraendert) PLUS drei Segment-Gruppen-Dialoge fuer die segmentweise Klassifizierung in Modus 2/3 (`vflw_seg_linie_m2` = Typ+GF-Neigung, `vflw_seg_linie_m3` = 4-fach-Typ+kontextabh. Wertfeld, `vflw_seg_bogen` = Typ+Variante; `vflw-seg-*-impl`). Beide Modi heben vor der Frage das aktuelle Pfad-Segment (LINE/ARC) per `vfl-seg-highlight` (`redraw`) in der Zeichnung hervor und zeigen "Segment i/n ..." im Dialogkopf. Details: `doc/variofoerderer.md` | diff --git a/Lisp/GeruestInsert.lsp b/Lisp/GeruestInsert.lsp index e38fde2..691a4d4 100644 --- a/Lisp/GeruestInsert.lsp +++ b/Lisp/GeruestInsert.lsp @@ -2,17 +2,22 @@ ;; GeruestInsert.lsp - Geruest-Baugruppen konfigurieren und einfuegen ;; ;; Liest data/json/geruest.json (rekursiv per ssg-json-laden), laesst den -;; Nutzer eine Basis-Variante, Anbauteile fuer "Befestigung oben" UND -;; "Befestigung unten" (je mit eigener Stueckzahl), Laenge und Farbe waehlen, -;; und fuegt das Ergebnis als Block GR__ ein. +;; Nutzer eine Basis-Variante, Anbauteile fuer die Befestigung (oben und +;; unten zusammen, Gesamtanzahl je Teil) und Sonstiges, Laenge und Farbe +;; waehlen, und fuegt das Ergebnis als Block GR__ ein. ;; Rohr-Geruest-Traeger (GERUEST_TRAEGER) lesen data/json/geruest_traeger.json. ;; -;; Beide Befestigungslisten enthalten ALLE Anbauteile der Baugruppe - dasselbe -;; Teil kann oben, unten oder gleichzeitig an beiden Positionen sitzen. +;; "anbaugruppen" hat zwei Listen: "befestigung" (eine Spalte "Befestigung +;; oben und unten", die Anzahl ist die Gesamtanzahl) und "sonstiges" (z.B. +;; Haltearme, eigene Zeile darunter; geruest-anbau-liste). Unter jedem Teil +;; zeigt der Dialog seine Artikelnummer(n). ;; -;; Die Dialogdefinition wird zur Laufzeit erzeugt (geruest-dcl-schreiben): -;; eine DCL-Liste kann keine Eingabefelder enthalten, ein Mengenfeld je Teil -;; ist also nur mit generierten Zeilen moeglich. +;; Das Dialog-Layout steht als Vorlage in dcl/geruest.dcl bzw. +;; dcl/geruest_traeger.dcl; nur die datenabhaengigen Bloecke (Radiobutton je +;; Variante, Mengenfeld + Ankreuzfeld je Anbauteil) werden zur Laufzeit an +;; //@NAME@-Platzhaltern eingesetzt (geruest-dcl-schreiben, +;; ssg-dcl-vorlage-fuellen) - DCL kann Tiles weder zur Laufzeit erzeugen noch +;; ausblenden. ;; ;; Konfigurationen kommen aus zwei getrennten Quellen: der gepflegten ;; Bibliothek in geruest.json und den eigenen in cfg/geruest_user.json. @@ -23,9 +28,10 @@ ;; die Dummy-DWG einen Tag nicht kennt (ssg-attrib-set-on schreibt nur Tags, ;; die als ATTDEF existieren). ;; -;; Zusaetzlich wird jede ausgewaehlte Artikelnummer (Basis, oben, unten, inkl. -;; aufgeloester Gruppen), fuer die data/geruest/.dwg existiert, einmal -;; bei 0,0,0 mit in den Block eingefuegt (geruest-teile-dwgs) - reine +;; Zusaetzlich wird jede ausgewaehlte Artikelnummer (Basis, oben, unten, +;; sonstiges, inkl. aufgeloester Gruppen), fuer die data/geruest/.dwg +;; existiert, einmal bei 0,0,0 mit in den Block eingefuegt (geruest-teile-dwgs, +;; Anbauteile im "Winkel Platte" gedreht) - reine ;; Geometrie als visuelle Rueckmeldung, die Attribute bleiben davon unberuehrt. ;; Teile ohne DWG werden still uebergangen. ;; @@ -37,13 +43,12 @@ ;; TEILEART-Attribut fuer ein Omniflo-Element (SSG_LIB_Commands.lsp). Der ;; Doppelklick-Dispatcher erkennt Geruest-Bloecke an diesem Praefix. ;; -;; Alle Bereiche liegen in EINEM Dialog; oben wird per Dropdown zwischen -;; Rohrabhaenger, Saeulen und Wandbefestigung umgeschaltet. DCL hat kein -;; Reiter-Tile, und da sich die Teilezeilen je Bereich unterscheiden, wird der -;; Dialog beim Wechsel geschlossen und neu aufgebaut - der Stand jedes -;; Bereichs bleibt dabei in *geruest-zustand* erhalten. +;; Jeder Bereich (Rohrabhaenger, Saeulen, Wandbefestigung) hat seinen eigenen +;; Menuebefehl und Dialog; eine Umschaltung im Dialog gibt es nicht. GERUEST +;; ohne Bereich zeigt nur einen Hinweis. ;; -;; Befehl: GERUEST +;; Befehle: GERUEST_SAEULEN, GERUEST_ROHRABHAENGER, GERUEST_WANDBEFESTIGUNG, +;; GERUEST_TRAEGER, GERUEST_TRAEGER_BESCHRIFTEN ;; ============================================================ (vl-load-com) @@ -149,21 +154,14 @@ (geruest-json-laden-cache "geruest_traeger.json" '*geruest-traeger-daten*) ) -;; Alle Baugruppen als ((id . objekt) ...) in Dateireihenfolge - diese -;; Reihenfolge bestimmt auch die Reihenfolge im Bereichs-Dropdown. Die -;; Traeger stehen in geruest_traeger.json und gehoeren nicht hierher. -(defun geruest-baugruppen-liste ( / erg) - (setq erg nil) - (foreach eintrag (geruest-daten) - (if (listp (cdr eintrag)) - (setq erg (append erg - (list (cons (ssg-json-get (cdr eintrag) "id") (cdr eintrag))))) - ) - ) - erg +;; Omniflo-Fahrstrecken (AP 110, APG 110, AP 60, ST, STL) - dieselbe +;; Linien-Logik wie der Traeger (Dialog, Laenge aus der Zeichnung, +;; Muffen-Checkbox, Beschriftung), aber eigene Datei und eigener Dialog. +(defun geruest-fahrstrecke-daten ( / ) + (geruest-json-laden-cache "omniflo_fahrstrecke.json" '*geruest-fahrstrecke-daten*) ) -;; Anzeigename einer Baugruppe fuer Dropdown und Kopfzeile. Bewusst das +;; Anzeigename einer Baugruppe fuer den Dialogtitel. Bewusst das ;; ASCII-Feld "titel" und nicht der aeussere JSON-Schluessel - der traegt ;; Umlaute ("Rohrabhänger", "Säulen"). (defun geruest-titel (bg / t1) @@ -183,6 +181,22 @@ (if (and w (/= w "")) w (ssg-json-get bg schluessel)) ) +;; Anbauteil-Liste einer Baugruppe. "anbaugruppen" ist ein Objekt mit zwei +;; Listen: "befestigung" (erscheint in den Spalten oben UND unten) und +;; "sonstiges" (eigene Zeile, z.B. Haltearme - weder oben noch unten). +;; schluessel = "befestigung" oder "sonstiges". Ein altes flaches Array gilt +;; als "befestigung". Unterscheidung: ein Objekt wird zur Alist mit +;; String-Schluesseln, ein Array von Objekten zur Liste von Alists. +(defun geruest-anbau-liste (bg schluessel / anb) + (setq anb (ssg-json-get bg "anbaugruppen")) + (cond + ((null anb) nil) + ((and (listp (car anb)) (= (type (car (car anb))) 'STR)) + (ssg-json-get anb schluessel)) + ((= schluessel "befestigung") anb) + ) +) + ;; Pfad der Dummy-DWG fuer den Block. Ein "dummy" in der Geometrie-Variante ;; wird bevorzugt; fehlt die Datei unter data/geruest, wird gemeldet und auf ;; den "dummy" der Baugruppe zurueckgefallen. Rueckgabe: (datei . pfad) - @@ -208,11 +222,12 @@ ) ) -;; Liste ohne die Eintraege, die (ohne Gross/Klein) gleich pfad sind. Damit -;; landet eine Teile-DWG, die zugleich der Dummy ist, nicht doppelt im Block. +;; Teile-Liste ((pfad . rot) ...) ohne die Eintraege, deren Pfad (ohne +;; Gross/Klein) gleich pfad ist. Damit landet eine Teile-DWG, die zugleich der +;; Dummy ist, nicht doppelt im Block. (defun geruest-ohne-pfad (pfad liste) (if pfad - (vl-remove-if '(lambda (p) (= (strcase p) (strcase pfad))) liste) + (vl-remove-if '(lambda (e) (= (strcase (car e)) (strcase pfad))) liste) liste ) ) @@ -316,6 +331,12 @@ (reverse erg) ) +;; Liste ohne die ersten n Elemente. +(defun geruest-rest-liste (lst n) + (repeat n (setq lst (cdr lst))) + lst +) + ;; Teile-DWGs zu einer Liste von Artikelnummern: data/geruest/.dwg, ;; soweit vorhanden. Jede Nummer nur einmal - alle Teile sitzen bei 0,0,0, ;; eine Mehrfach-Stueckzahl waere visuell nicht unterscheidbar. Fehlende @@ -332,6 +353,38 @@ (reverse erg) ) +;; Teile-DWGs mit Drehwinkel: ((pfad . rot) ...). Die Basis-Teile bleiben +;; ungedreht, die Anbauteile (oben/unten/sonstiges) bekommen den "Winkel +;; Platte" (Grad, Drehung um Z am Blockursprung). Ein Teil, das schon in der +;; Basis steckt, wird nicht ein zweites Mal als Anbauteil eingefuegt. +(defun geruest-teile-dwgs-rot (basis-pfade anbau-pfade winkel / erg) + (setq erg (mapcar '(lambda (p) (cons p 0.0)) basis-pfade)) + (foreach p anbau-pfade + (if (not (assoc p erg)) + (setq erg (append erg (list (cons p (float winkel))))) + ) + ) + erg +) + +;; "Winkel Platte" im Dialog: Tile-Index ("0"/"1") <-> Grad (0/90). +;; Konfigurationen speichern den echten Winkel, nicht den Listenindex. +(setq *geruest-winkel-werte* '(0 90)) + +(defun geruest-winkel-aus-index (idx-str / w) + (setq w (nth (atoi idx-str) *geruest-winkel-werte*)) + (if w w 0) +) + +(defun geruest-winkel-index (winkel / i idx) + (setq i 0 idx 0) + (foreach w *geruest-winkel-werte* + (if (and (numberp winkel) (equal (float w) (float winkel) 1e-6)) (setq idx i)) + (setq i (1+ i)) + ) + (itoa idx) +) + ;; ============================================================ ;; DIALOG @@ -479,47 +532,102 @@ ;; Listenindex einer Konfiguration im popup_list (0 = "", die ;; Konfigurationen beginnen deshalb bei 1). 0, wenn nicht gefunden. -(defun geruest-konfig-index (name / i idx) - (setq i 1 idx 0) +;; Eine eigene Konfiguration gewinnt vor einer gleichnamigen aus der +;; Bibliothek - gesucht wird nach dem Speichern, und gespeichert wird immer +;; eine eigene. +(defun geruest-konfig-index (name / i idx bib) + (setq i 1 idx 0 bib 0) (foreach k *geruest-konfig-liste* - (if (and (= idx 0) (equal (ssg-json-get (cdr k) "name") name)) - (setq idx i)) + (if (equal (ssg-json-get (cdr k) "name") name) + (if (car k) + (if (= idx 0) (setq idx i)) + (if (= bib 0) (setq bib i)))) (setq i (1+ i)) ) - idx + (if (> idx 0) idx bib) ) -;; Positionsliste ("oben"/"unten") einer Konfiguration auf die Anbauteile +;; Namensvorgabe beim Speichern: der Name der gewaehlten EIGENEN +;; Konfiguration (Enter ueberschreibt sie), sonst nil - die Bibliothek ist +;; schreibgeschuetzt. +(defun geruest-konfig-name-vorgabe (konfig-idx / k) + (setq k (if (> konfig-idx 0) (nth (1- konfig-idx) *geruest-konfig-liste*))) + (if (and k (car k)) (ssg-json-get (cdr k) "name")) +) + +;; Teileliste ("befestigung"/"sonstiges", in alten Konfigurationen auch +;; "oben"/"unten") einer Konfiguration auf die Anbauteile ;; abbilden. Rueckgabe: ein Eintrag je Anbauteil - nil (nicht gewaehlt) oder ;; die Anzahl (Feld "anzahl"). Ein unbekannter Artikelname wird gemeldet und ;; uebersprungen, statt die ganze Konfiguration scheitern zu lassen. -(defun geruest-konfig-position (konfig schluessel anbauteile / mengen idx n) +;; ausweich = Teileliste, deren Namen still uebersprungen werden (sie werden +;; von einem anderen Aufruf eingesammelt), oder T = nie melden. +(defun geruest-konfig-position (konfig schluessel anbauteile ausweich + / mengen idx n name) (setq mengen (geruest-nil-liste (length anbauteile))) (foreach e (ssg-json-get konfig schluessel) - (setq idx (geruest-name-index (ssg-json-get e "artikel") anbauteile)) - (if idx - (progn + (setq name (ssg-json-get e "artikel")) + (setq idx (geruest-name-index name anbauteile)) + (cond + (idx (setq n (ssg-json-get e "anzahl")) (setq mengen (geruest-liste-setzen mengen idx (if (and n (numberp n) (> n 0)) (fix n) 1))) ) - (princ (ssg-textf "gr-konfig-teil-unbekannt" - (list (ssg-json-get e "artikel") - (ssg-json-get konfig "name")))) + ((or (= ausweich T) (geruest-name-index name ausweich)) nil) + (T + (princ (ssg-textf "gr-konfig-teil-unbekannt" + (list name (ssg-json-get konfig "name"))))) ) ) mengen ) +;; Zwei Mengenlisten (nil oder Zahl je Teil) elementweise addieren. +(defun geruest-mengen-addieren (a b) + (mapcar '(lambda (x y) + (cond ((and x y) (+ x y)) (x x) (y y))) + a b) +) + +;; Befestigungs-Mengen einer Konfiguration (Gesamtanzahl je Teil). Aeltere +;; Konfigurationen fuehren die Befestigung getrennt unter "oben"/"unten" - +;; deren Mengen werden addiert; beim naechsten Speichern steht alles unter +;; "befestigung". Sonstiges-Teile werden hier still uebergangen (die sammelt +;; geruest-konfig-sonstiges ein). +(defun geruest-konfig-befestigung (konfig befestigung sonstiges) + (geruest-mengen-addieren + (geruest-konfig-position konfig "befestigung" befestigung sonstiges) + (geruest-mengen-addieren + (geruest-konfig-position konfig "oben" befestigung sonstiges) + (geruest-konfig-position konfig "unten" befestigung sonstiges))) +) + +;; Sonstiges-Mengen einer Konfiguration. Aeltere Konfigurationen kennen keine +;; Sonstiges-Liste und fuehren solche Teile (z.B. einen Haltearm) unter +;; "oben"/"unten"/"befestigung" - die werden hier still mit eingesammelt; +;; beim naechsten Speichern stehen sie dann unter "sonstiges". +(defun geruest-konfig-sonstiges (konfig sonstiges befestigung) + (geruest-mengen-addieren + (geruest-konfig-position konfig "sonstiges" sonstiges befestigung) + (geruest-mengen-addieren + (geruest-konfig-position konfig "befestigung" sonstiges T) + (geruest-mengen-addieren + (geruest-konfig-position konfig "oben" sonstiges T) + (geruest-konfig-position konfig "unten" sonstiges T)))) +) + ;; ============================================================ ;; DIALOGDEFINITION ERZEUGEN ;; ============================================================ -;; Die Anbauteil-Zeilen haengen an der Baugruppe, deshalb wird die DCL-Datei -;; pro Aufruf geschrieben statt fest vorgehalten: DCL kann weder Dateien -;; einbinden noch Tiles zur Laufzeit erzeugen, und eine Liste (list_box) kann -;; keine Eingabefelder enthalten - ohne Generierung gaebe es also kein -;; Mengenfeld je Teil. +;; Das Layout steht als Vorlage in dcl/geruest.dcl bzw. dcl/geruest_traeger.dcl. +;; Hier entstehen nur die datenabhaengigen Bloecke, die ssg-dcl-vorlage-fuellen +;; (ssg_core.lsp) an den //@NAME@-Platzhaltern einsetzt: ein Radiobutton je +;; Variante und Mengenfeld + Ankreuzfeld je Anbauteil. DCL kann weder Tiles +;; zur Laufzeit erzeugen noch ausblenden, Radiobutton-Labels lassen sich per +;; set_tile nicht aendern, und eine list_box kann keine Eingabefelder +;; enthalten. ;; Ein Anfuehrungszeichen im Artikelnamen wuerde das DCL-Label vorzeitig ;; beenden und die erzeugte Datei unbrauchbar machen (fuenf Bezeichnungen @@ -536,9 +644,104 @@ erg ) -;; Eine Befestigungsspalte. Das Mengenfeld steht LINKS vom Ankreuzfeld: die -;; Eingabefelder sind dadurch alle gleich breit und die Teilenamen beginnen -;; auf gleicher Hoehe - DCL richtet Zeileninhalte nicht von sich aus aus. +;; Pfad einer DCL-Vorlage unter DXFM_DCL bzw. DXFMAKRO/dcl, oder nil. +(defun geruest-dcl-vorlage-pfad (datei / basis) + (setq basis (cond ((getenv "DXFM_DCL")) + ((getenv "DXFMAKRO") (strcat (getenv "DXFMAKRO") "/dcl")))) + (if basis + (strcat (vl-string-translate "\\" "/" basis) "/" datei) + ) +) + +;; Radiobutton-Keys der Varianten: "v", i = Index in geometrie_varianten. +;; get_tile auf der radio_column liefert den Key des gewaehlten Buttons. +(defun geruest-radio-key (i) (strcat "v" (itoa i))) + +(defun geruest-radio-index (key) + (if (and key (> (strlen key) 1)) (atoi (substr key 2)) 0) +) + +;; (0 1 ... n-1) +(defun geruest-indizes (n / i erg) + (setq i (1- n) erg nil) + (while (>= i 0) (setq erg (cons i erg) i (1- i))) + erg +) + +;; Beschriftung einer Variante im Dialog: Name und dahinter die enthaltenen +;; Artikelnummern in Klammern, z.B. "R 2\" (821006051, 821004201)". Ohne +;; Nummern nur der Name. +(defun geruest-varianten-label (variante / nr) + (setq nr (geruest-artnr-anzeige variante)) + (if (/= nr "") + (strcat (geruest-eintrag-name variante) " (" nr ")") + (geruest-eintrag-name variante) + ) +) + +;; Gesperrte Varianten: "disabled": true in der JSON. Sie erscheinen im +;; Dialog ausgegraut (mode_tile) und sind nicht waehlbar - so laesst sich eine +;; Variante aus dem Angebot nehmen, ohne sie zu loeschen (Konfigurationen und +;; GERUEST_TRAEGER_BESCHRIFTEN finden sie weiter ueber den Namen). +(defun geruest-variante-gesperrt-p (variante) + (if (ssg-json-get variante "disabled") T nil) +) + +;; Index der ersten nicht gesperrten Variante; 0, wenn alle gesperrt sind. +(defun geruest-erste-freie-variante (varianten / i idx) + (setq i 0 idx nil) + (foreach v varianten + (if (and (null idx) (not (geruest-variante-gesperrt-p v))) (setq idx i)) + (setq i (1+ i)) + ) + (if idx idx 0) +) + +;; Gueltiger Varianten-Index fuer die Vorauswahl: idx selbst, wenn er +;; existiert und nicht gesperrt ist, sonst die erste freie Variante. +(defun geruest-variante-waehlbar (varianten idx) + (if (and idx (>= idx 0) (< idx (length varianten)) + (not (geruest-variante-gesperrt-p (nth idx varianten)))) + idx + (geruest-erste-freie-variante varianten) + ) +) + +;; Radiobuttons gesperrter Varianten ausgrauen (im laufenden Dialog). +(defun geruest-varianten-sperren (varianten / i) + (setq i 0) + (foreach v varianten + (if (geruest-variante-gesperrt-p v) (mode_tile (geruest-radio-key i) 1)) + (setq i (1+ i)) + ) +) + +;; Ein Radiobutton je Variante aus idx-liste (Indizes in varianten). +(defun geruest-dcl-varianten-zeilen (varianten idx-liste / erg) + (setq erg nil) + (foreach i idx-liste + (setq erg (append erg + (list (strcat " : radio_button { key = \"" (geruest-radio-key i) + "\"; label = \"" + (geruest-dcl-label (geruest-varianten-label (nth i varianten))) + "\"; }")))) + ) + erg +) + +;; Artikelnummer(n) eines Anbauteils fuer die Anzeige im Dialog: Einzelteil +;; -> seine sivas_id, Gruppe -> die Nummern ihrer Teile, jede nur einmal +;; (die Stueckzahl steckt in ARTINR, nicht in der Anzeige). +(defun geruest-artnr-anzeige (eintrag) + (ssg-join (geruest-eindeutig (geruest-artikelnummern eintrag)) ", ") +) + +;; Eine Anbauteil-Spalte als DCL-Zeilen. Je Teil: Mengenfeld LINKS, rechts +;; daneben Ankreuzfeld mit dem Teilenamen und darunter eine Textzeile mit der +;; Artikelnummer (DCL kennt keine Schriftgroesse - die Nummer steht darum in +;; normaler Groesse in einer eigenen Zeile). Das Mengenfeld links haelt die +;; Eingabefelder gleich breit und laesst die Teilenamen auf gleicher Hoehe +;; beginnen - DCL richtet Zeileninhalte nicht von sich aus aus. ;; ;; Zwei DCL-Eigenheiten muessen dafuer gesetzt werden: ;; - alignment = left, weil DCL Tiles in einer Spalte sonst ZENTRIERT: bei @@ -549,76 +752,60 @@ ;; klaffte dadurch eine wechselnd grosse Luecke. Mit fixed_width wird die ;; Zeile nur so breit wie ihr Inhalt, das Ankreuzfeld sitzt also direkt am ;; Mengenfeld. -(defun geruest-dcl-spalte (f anbauteile prefix titel / i) - (write-line " : boxed_column {" f) - (write-line (strcat " label = \"" titel "\";") f) - (write-line " alignment = left;" f) +(defun geruest-dcl-spalte (anbauteile prefix titel / i erg) + (setq erg (list " : boxed_column {" + (strcat " label = \"" titel "\";") + " alignment = left;")) (setq i 0) (foreach a anbauteile - (write-line " : row {" f) - (write-line " alignment = left;" f) - (write-line " fixed_width = true;" f) - (write-line (strcat " : edit_box { key = \"" prefix "m" (itoa i) - "\"; label = \"\"; edit_width = 3;" - " fixed_width = true; }") f) - (write-line (strcat " : toggle { key = \"" prefix (itoa i) - "\"; label = \"" - (geruest-dcl-label (geruest-eintrag-name a)) - "\"; fixed_width = true; }") f) - (write-line " }" f) + (setq erg (append erg + (list " : row {" + " alignment = left;" + " fixed_width = true;" + (strcat " : edit_box { key = \"" prefix "m" (itoa i) + "\"; label = \"\"; edit_width = 3; fixed_width = true; }") + " : column {" + " alignment = left;" + (strcat " : toggle { key = \"" prefix (itoa i) + "\"; label = \"" + (geruest-dcl-label (geruest-eintrag-name a)) + "\"; fixed_width = true; }") + (strcat " : text { label = \"Art.-Nr. " + (geruest-dcl-label (geruest-artnr-anzeige a)) + "\"; }") + " }" + " }"))) (setq i (1+ i)) ) - (write-line " }" f) + (append erg (list " }")) ) -;; Rueckgabe: Pfad der temporaeren DCL-Datei oder nil. -(defun geruest-dcl-schreiben (anbauteile / pfad f) - (setq pfad (vl-filename-mktemp "geruest" nil ".dcl")) - (setq f (open pfad "w")) - (if (null f) - nil - (progn - (write-line "geruest : dialog {" f) - (write-line " label = \"Geruest-Baugruppe konfigurieren\";" f) - ;; Bereichswechsel (Rohrabhaenger/Saeulen/Wandbefestigung). DCL hat kein - ;; Reiter-Tile, deshalb ein Dropdown; sein Rueckruf schliesst den Dialog - ;; und die Schleife baut ihn mit dem neuen Bereich neu auf - die - ;; Teilezeilen unterscheiden sich je Bereich und lassen sich zur - ;; Laufzeit nicht austauschen. - (write-line " : popup_list { key = \"bereich\"; label = \"Bereich:\"; width = 30; }" f) - (write-line " : text { key = \"kopf\"; label = \"\"; width = 64; }" f) - (write-line " : row {" f) - (write-line " : popup_list { key = \"konfig\"; label = \"Konfiguration:\"; width = 40; }" f) - (write-line " : button { key = \"kspeichern\"; label = \"Speichern...\"; fixed_width = true; }" f) - (write-line " : button { key = \"kloeschen\"; label = \"Loeschen\"; fixed_width = true; }" f) - (write-line " }" f) - (write-line " : boxed_column {" f) - (write-line " label = \"Basis\";" f) - (write-line " : popup_list { key = \"variante\"; label = \"Variante:\"; width = 56; }" f) - (write-line " : row {" f) - (write-line " : edit_box { key = \"laenge\"; label = \"Laenge (mm):\"; edit_width = 10; }" f) - (write-line " : popup_list { key = \"farbe\"; label = \"Farbe:\"; width = 25; }" f) - (write-line " : edit_box { key = \"farbe_frei\"; label = \"eigene:\"; edit_width = 12; }" f) - (write-line " }" f) - (write-line " }" f) - ;; Ohne Anbauteile bleiben die Spalten weg - ein leerer Cluster ist - ;; in DCL nicht zulaessig (betrifft z.B. die 1-Zoll-Saeule). - (if (> (length anbauteile) 0) - (progn - (write-line " : row {" f) - (geruest-dcl-spalte f anbauteile "o" "Befestigung oben (Anzahl / Teil)") - (geruest-dcl-spalte f anbauteile "u" "Befestigung unten (Anzahl / Teil)") - (write-line " }" f) - ) - ) - (write-line " ok_cancel;" f) - (write-line "}" f) - (close f) - pfad - ) +;; Ersetzungen fuer dcl/geruest.dcl. Ohne Teile entfallen die Blocks ganz - +;; ein leerer Cluster ist in DCL nicht zulaessig (z.B. Wandbefestigung ohne +;; Sonstiges). +(defun geruest-dcl-ersetzungen (titel anbauteile sonstiges varianten) + (list + (cons "TITEL" + (list (strcat " label = \"" (geruest-dcl-label (ssg-textf "gr-dlg-kopf" (list titel))) + "\";"))) + (cons "VARIANTEN" + (geruest-dcl-varianten-zeilen varianten (geruest-indizes (length varianten)))) + (cons "BEFESTIGUNG" + (if anbauteile + (geruest-dcl-spalte anbauteile "b" + "Befestigung oben und unten (Anzahl / Teil)"))) + (cons "SONSTIGES" + (if sonstiges + (geruest-dcl-spalte sonstiges "s" "Sonstiges (Anzahl / Teil)"))) ) ) +;; Rueckgabe: Pfad der gefuellten temporaeren DCL-Datei oder nil. +(defun geruest-dcl-schreiben (titel anbauteile sonstiges varianten) + (ssg-dcl-vorlage-fuellen (geruest-dcl-vorlage-pfad "geruest.dcl") "geruest" + (geruest-dcl-ersetzungen titel anbauteile sonstiges varianten)) +) + ;; ============================================================ ;; DIALOGZUSTAND @@ -629,20 +816,21 @@ ;; Dialogfunktion aus, auf deren Locals kaeme er nicht. ;; Ausgangszustand einer Spalte: nichts angehakt, Mengenfeld mit der -;; JSON-Vorgabe vorbelegt (beim Klemmring also 2). -(defun geruest-dlg-standard ( / erg) +;; JSON-Vorgabe vorbelegt (beim Klemmring also 2). teile = Anbauteile der +;; Spalte (befestigung oder sonstiges). +(defun geruest-dlg-standard (teile / erg) (setq erg nil) - (foreach a *geruest-anbauteile* + (foreach a teile (setq erg (append erg (list (cons "0" (itoa (geruest-anzahl-vorgabe a)))))) ) erg ) ;; Mengenliste (nil oder Zahl je Teil) in den Tile-Zustand umsetzen. -(defun geruest-anzahlen->tiles (mengen / erg i a) +(defun geruest-anzahlen->tiles (mengen teile / erg i a) (setq erg nil i 0) (foreach m mengen - (setq a (nth i *geruest-anbauteile*)) + (setq a (nth i teile)) (setq erg (append erg (list (if m (cons "1" (itoa m)) @@ -652,46 +840,65 @@ erg ) -(defun geruest-dlg-lesen ( / i n) - (setq *geruest-dlg-variante* (get_tile "variante")) +;; Tile-Zustand einer Spalte lesen: ((haken . menge) ...) je Teil. +;; prefix = "b"/"s" (Tile-Keys i und mi). +(defun geruest-dlg-spalte-lesen (prefix teile / i n erg) + (setq n (length teile) i 0 erg nil) + (while (< i n) + (setq erg (append erg + (list (cons (get_tile (strcat prefix (itoa i))) + (get_tile (strcat prefix "m" (itoa i))))))) + (setq i (1+ i)) + ) + erg +) + +(defun geruest-dlg-spalte-schreiben (prefix zustand / i) + (setq i 0) + (foreach paar zustand + (set_tile (strcat prefix (itoa i)) (car paar)) + (set_tile (strcat prefix "m" (itoa i)) (cdr paar)) + (setq i (1+ i)) + ) +) + +;; Tile-Keys einer Spalte (Haken und Mengenfeld je Teil) fuer action_tile. +(defun geruest-dlg-spalten-keys (prefix teile / i erg) + (setq i 0 erg nil) + (foreach a teile + (setq erg (append erg (list (strcat prefix (itoa i)) + (strcat prefix "m" (itoa i))))) + (setq i (1+ i)) + ) + erg +) + +(defun geruest-dlg-lesen ( / ) + ;; radio_column liefert den Key des gewaehlten Buttons ("v"); der + ;; Zustand fuehrt weiter den Index als String. + (setq *geruest-dlg-variante* + (itoa (geruest-radio-index (get_tile "variante")))) + (setq *geruest-dlg-winkel* (get_tile "winkel")) + (if (= *geruest-dlg-winkel* "") (setq *geruest-dlg-winkel* "0")) (setq *geruest-dlg-laenge* (get_tile "laenge")) (setq *geruest-dlg-farbe* (get_tile "farbe")) (setq *geruest-dlg-frei* (get_tile "farbe_frei")) (setq *geruest-dlg-konfig* (get_tile "konfig")) - (setq *geruest-dlg-bereich* (get_tile "bereich")) - (setq n (length *geruest-anbauteile*) i 0) - (setq *geruest-dlg-oben* nil *geruest-dlg-unten* nil) - (while (< i n) - (setq *geruest-dlg-oben* - (append *geruest-dlg-oben* - (list (cons (get_tile (strcat "o" (itoa i))) - (get_tile (strcat "om" (itoa i))))))) - (setq *geruest-dlg-unten* - (append *geruest-dlg-unten* - (list (cons (get_tile (strcat "u" (itoa i))) - (get_tile (strcat "um" (itoa i))))))) - (setq i (1+ i)) - ) + (setq *geruest-dlg-bef* (geruest-dlg-spalte-lesen "b" *geruest-anbauteile*)) + (setq *geruest-dlg-sonst* (geruest-dlg-spalte-lesen "s" *geruest-sonstiges*)) (princ) ) -(defun geruest-dlg-schreiben ( / i n paar) - (set_tile "variante" *geruest-dlg-variante*) +(defun geruest-dlg-schreiben ( / ) + (set_tile "variante" (geruest-radio-key (atoi *geruest-dlg-variante*))) (set_tile "laenge" *geruest-dlg-laenge*) ;; Nur setzen, wenn die Liste ueberhaupt gefuellt ist - ein Index auf eine ;; leere popup_list ist nicht definiert (Baugruppen ohne attribute-Block). (if *geruest-farb-liste* (set_tile "farbe" *geruest-dlg-farbe*)) (set_tile "farbe_frei" *geruest-dlg-frei*) - (setq n (length *geruest-anbauteile*) i 0) - (while (< i n) - (setq paar (nth i *geruest-dlg-oben*)) - (set_tile (strcat "o" (itoa i)) (car paar)) - (set_tile (strcat "om" (itoa i)) (cdr paar)) - (setq paar (nth i *geruest-dlg-unten*)) - (set_tile (strcat "u" (itoa i)) (car paar)) - (set_tile (strcat "um" (itoa i)) (cdr paar)) - (setq i (1+ i)) - ) + (set_tile "winkel" *geruest-dlg-winkel*) + (geruest-dlg-spalte-schreiben "b" *geruest-dlg-bef*) + (geruest-dlg-spalte-schreiben "s" *geruest-dlg-sonst*) (princ) ) @@ -736,12 +943,15 @@ ;; Konfiguration anwenden und die Tiles nachziehen. Wird direkt aus dem ;; popup_list-Rueckruf aufgerufen - set_tile aendert die Anzeige im laufenden ;; Dialog, ein Neuaufbau ist nicht noetig. Index 0 = "(keine)". +;; Danach wird der Stand als Vergleichsbasis gemerkt +;; (*geruest-dlg-konfig-basis*), damit eine spaetere Aenderung erkennbar ist. (defun geruest-dlg-konfig-waehlen (idx / k vidx farbe fidx) (setq *geruest-dlg-konfig* (itoa idx)) (if (<= idx 0) (progn - (setq *geruest-dlg-oben* (geruest-dlg-standard)) - (setq *geruest-dlg-unten* (geruest-dlg-standard)) + (setq *geruest-dlg-winkel* "0") + (setq *geruest-dlg-bef* (geruest-dlg-standard *geruest-anbauteile*)) + (setq *geruest-dlg-sonst* (geruest-dlg-standard *geruest-sonstiges*)) ) (progn (setq k (nth (1- idx) *geruest-konfig-liste*)) @@ -750,11 +960,17 @@ (setq k (cdr k)) (setq vidx (geruest-name-index (ssg-json-get k "variante") *geruest-varianten*)) - (if vidx - (setq *geruest-dlg-variante* (itoa vidx)) - (princ (ssg-textf "gr-konfig-variante-unbekannt" - (list (ssg-json-get k "variante") - (ssg-json-get k "name")))) + (cond + ((null vidx) + (princ (ssg-textf "gr-konfig-variante-unbekannt" + (list (ssg-json-get k "variante") + (ssg-json-get k "name"))))) + ;; gesperrte Variante: Auswahl bleibt, wie sie ist + ((geruest-variante-gesperrt-p (nth vidx *geruest-varianten*)) + (princ (ssg-textf "gr-konfig-variante-gesperrt" + (list (ssg-json-get k "variante") + (ssg-json-get k "name"))))) + (T (setq *geruest-dlg-variante* (itoa vidx))) ) (setq *geruest-dlg-laenge* (geruest-zahl-string (ssg-json-get k "laenge"))) @@ -769,12 +985,17 @@ (setq *geruest-dlg-farbe* (itoa *geruest-frei-idx*) *geruest-dlg-frei* farbe)) ) - (setq *geruest-dlg-oben* + (setq *geruest-dlg-bef* (geruest-anzahlen->tiles - (geruest-konfig-position k "oben" *geruest-anbauteile*))) - (setq *geruest-dlg-unten* + (geruest-konfig-befestigung k *geruest-anbauteile* *geruest-sonstiges*) + *geruest-anbauteile*)) + (setq *geruest-dlg-sonst* (geruest-anzahlen->tiles - (geruest-konfig-position k "unten" *geruest-anbauteile*))) + (geruest-konfig-sonstiges k *geruest-sonstiges* *geruest-anbauteile*) + *geruest-sonstiges*)) + ;; Fehlt in aelteren Konfigurationen -> 0 Grad + (setq *geruest-dlg-winkel* + (geruest-winkel-index (ssg-json-get k "winkel_platte"))) ) ) ) @@ -782,9 +1003,70 @@ (geruest-dlg-schreiben) (mode_tile "farbe_frei" (if (= (atoi *geruest-dlg-farbe*) *geruest-frei-idx*) 0 1)) + ;; Erst NACH dem Schreiben lesen: der Vergleichsstand soll genau das sein, + ;; was die Tiles zeigen (z.B. ein vom Dialog normalisiertes Mengenfeld). + (geruest-dlg-lesen) + (setq *geruest-dlg-konfig-basis* + (if (> idx 0) (geruest-dlg-record ""))) + (geruest-dlg-konfig-anzeigen) (princ) ) +;; Zwei Konfigurations-Records ohne Beachtung des Namens vergleichen. +(defun geruest-record-ohne-name (r) + (vl-remove-if '(lambda (e) (equal (car e) "name")) r) +) + +(defun geruest-record-gleich-p (a b) + (equal (geruest-record-ohne-name a) (geruest-record-ohne-name b)) +) + +;; T, wenn eine Konfiguration gewaehlt ist und der aktuelle Stand von ihr +;; abweicht. Bewusst ein Vergleich und kein "geaendert"-Flag: wer eine +;; Aenderung zuruecknimmt, hat wieder den Stand der Konfiguration. +(defun geruest-dlg-geaendert-p ( / ) + (and *geruest-dlg-konfig-basis* + (> (atoi *geruest-dlg-konfig*) 0) + (not (geruest-record-gleich-p *geruest-dlg-konfig-basis* + (geruest-dlg-record "")))) +) + +;; Konfig-Liste und Statuszeile nachziehen: der gewaehlte Eintrag bekommt bei +;; Abweichung den Zusatz "(geaendert)", die Statuszeile sagt, was Speichern +;; tut (eigene Konfiguration -> ueberschreiben, Bibliothek -> neuer Name). +(defun geruest-dlg-konfig-anzeigen ( / idx i k geaendert) + (setq idx (atoi *geruest-dlg-konfig*)) + (setq geaendert (geruest-dlg-geaendert-p)) + (start_list "konfig") + (add_list (ssg-text "gr-konfig-keine")) + (setq i 1) + (foreach k *geruest-konfig-liste* + (add_list (if (and geaendert (= i idx)) + (ssg-textf "gr-konfig-geaendert" (list (geruest-konfig-name k))) + (geruest-konfig-name k))) + (setq i (1+ i)) + ) + (end_list) + (set_tile "konfig" *geruest-dlg-konfig*) + (setq k (if (> idx 0) (nth (1- idx) *geruest-konfig-liste*))) + (set_tile "kstatus" + (cond + ((not geaendert) "") + ((car k) (ssg-textf "gr-konfig-status-geaendert" + (list (ssg-json-get (cdr k) "name")))) + (T (ssg-textf "gr-konfig-status-bibliothek" + (list (ssg-json-get (cdr k) "name")))) + ) + ) + (princ) +) + +;; Rueckruf aller Eingabe-Tiles: Stand lesen und Kennzeichnung nachziehen. +(defun geruest-dlg-aenderung-pruefen ( / ) + (geruest-dlg-lesen) + (geruest-dlg-konfig-anzeigen) +) + (defun geruest-name-farbindex (wert / i idx) (setq i 0 idx nil) (foreach f *geruest-farb-liste* @@ -798,10 +1080,10 @@ ;; Rueckgabe: (T . ((index . anzahl) ...)) oder nil bei ungueltigem Mengenfeld. ;; Das fuehrende T ist noetig, weil "nichts ausgewaehlt" ein gueltiges ;; Ergebnis ist und sich sonst nicht von einem Fehler unterscheiden liesse. -(defun geruest-anzahlen-lesen (zustand / erg i a m ok) +(defun geruest-anzahlen-lesen (zustand teile / erg i a m ok) (setq erg nil i 0 ok T) (foreach paar zustand - (setq a (nth i *geruest-anbauteile*)) + (setq a (nth i teile)) (if (and ok (= (car paar) "1")) (progn (setq m (geruest-anzahl-wert (cdr paar) (geruest-anzahl-vorgabe a))) @@ -827,15 +1109,16 @@ (nth (atoi *geruest-dlg-variante*) *geruest-varianten*))) (cons "laenge" *geruest-dlg-laenge*) (cons "teilefarbe" (geruest-dlg-farbwert)) - (cons "oben" (geruest-dlg-teile *geruest-dlg-oben*)) - (cons "unten" (geruest-dlg-teile *geruest-dlg-unten*)) + (cons "befestigung" (geruest-dlg-teile *geruest-dlg-bef* *geruest-anbauteile*)) + (cons "sonstiges" (geruest-dlg-teile *geruest-dlg-sonst* *geruest-sonstiges*)) + (cons "winkel_platte" (geruest-winkel-aus-index *geruest-dlg-winkel*)) ) ) -(defun geruest-dlg-teile (zustand / erg i a m) +(defun geruest-dlg-teile (zustand teile / erg i a m) (setq erg nil i 0) (foreach paar zustand - (setq a (nth i *geruest-anbauteile*)) + (setq a (nth i teile)) (if (= (car paar) "1") (progn (setq m (geruest-anzahl-wert (cdr paar) (geruest-anzahl-vorgabe a))) @@ -891,11 +1174,14 @@ (ssg-json-get k "laenge"))) "\",") f) (write-line (strcat " \"teilefarbe\": \"" (ssg-json-escape (ssg-json-get k "teilefarbe")) "\",") f) - (write-line " \"oben\": [" f) - (geruest-teile-schreiben f (ssg-json-get k "oben")) + (write-line (strcat " \"winkel_platte\": " + (itoa (fix (if (numberp (ssg-json-get k "winkel_platte")) + (ssg-json-get k "winkel_platte") 0))) ",") f) + (write-line " \"befestigung\": [" f) + (geruest-teile-schreiben f (ssg-json-get k "befestigung")) (write-line " ]," f) - (write-line " \"unten\": [" f) - (geruest-teile-schreiben f (ssg-json-get k "unten")) + (write-line " \"sonstiges\": [" f) + (geruest-teile-schreiben f (ssg-json-get k "sonstiges")) (write-line " ]" f) (write-line (if (< i n) " }," " }") f) ) @@ -983,45 +1269,22 @@ ) ) -;; Dialogzustand eines Bereichs sichern bzw. zurueckholen, damit ein -;; Bereichswechsel die Eingaben nicht verwirft. -(defun geruest-zustand-sichern (id) - (setq *geruest-zustand* - (geruest-alist-setzen *geruest-zustand* id - (list *geruest-dlg-variante* *geruest-dlg-laenge* *geruest-dlg-farbe* - *geruest-dlg-frei* *geruest-dlg-konfig* - *geruest-dlg-oben* *geruest-dlg-unten*))) -) - -;; Rueckgabe T, wenn ein passender Zustand gefunden und gesetzt wurde. Die -;; Laengenpruefung faengt den Fall ab, dass die Datendatei zwischen zwei -;; Aufrufen geaendert wurde und die Teilezahl nicht mehr passt. -(defun geruest-zustand-laden (id / z) - (setq z (cdr (assoc id *geruest-zustand*))) - (if (and z (= (length (nth 5 z)) (length *geruest-anbauteile*))) - (progn - (setq *geruest-dlg-variante* (nth 0 z) - *geruest-dlg-laenge* (nth 1 z) - *geruest-dlg-farbe* (nth 2 z) - *geruest-dlg-frei* (nth 3 z) - *geruest-dlg-konfig* (nth 4 z) - *geruest-dlg-oben* (nth 5 z) - *geruest-dlg-unten* (nth 6 z)) - T - ) - ) -) - ;; Dialog fuer einen Bereich zeigen. Rueckgabe: -;; ("OK" variante-index ((idx . anzahl) ...) ((idx . anzahl) ...) laenge farbe) -;; - drittes Element = Befestigung oben, viertes = unten -;; ("WECHSEL" bereich-index) - Nutzer hat den Bereich umgestellt +;; ("OK" variante-index befestigung laenge farbe sonstiges winkel) +;; - befestigung/sonstiges je ((idx . anzahl) ...) in +;; anbaugruppen.befestigung bzw. anbaugruppen.sonstiges; die Anzahl der +;; Befestigung ist die GESAMTanzahl (oben und unten zusammen). +;; - winkel = "Winkel Platte" in Grad (0/90) fuer die Anbauteile. ;; nil - abgebrochen -(defun geruest-dialog (bg bereich-idx bereiche / dcl-pfad dat attr laenge-def +;; Jeder Bereich hat seinen eigenen Menuebefehl; eine Umschaltung im Dialog +;; gibt es nicht (DCL kennt keine Reiter). Der Dialogstand beginnt je Aufruf frisch. +(defun geruest-dialog (bg / dcl-pfad dat attr laenge-def farb-opts min-l max-l fertig rueckgabe - ergebnis wert-l oben-m unten-m name neu-idx) + ergebnis wert-l bef-m sonst-m name + vorgabe tile) (setq *geruest-varianten* (ssg-json-get bg "geometrie_varianten")) - (setq *geruest-anbauteile* (ssg-json-get bg "anbaugruppen")) + (setq *geruest-anbauteile* (geruest-anbau-liste bg "befestigung")) + (setq *geruest-sonstiges* (geruest-anbau-liste bg "sonstiges")) (setq attr (ssg-json-get bg "attribute")) (setq laenge-def (if attr (ssg-json-get attr "LAENGE"))) (setq farb-opts (if attr (ssg-json-get attr "TEILEFARBE"))) @@ -1031,22 +1294,21 @@ (geruest-farb-liste-setzen farb-opts) (setq *geruest-konfig-liste* (geruest-konfigs bg)) - ;; Frueheren Stand dieses Bereichs wiederherstellen, sonst Ausgangszustand - (if (null (geruest-zustand-laden (ssg-json-get bg "id"))) - (progn - (setq *geruest-dlg-variante* "0" *geruest-dlg-laenge* "" - *geruest-dlg-farbe* "0" *geruest-dlg-frei* "" - *geruest-dlg-konfig* "0") - (setq *geruest-dlg-oben* (geruest-dlg-standard)) - (setq *geruest-dlg-unten* (geruest-dlg-standard)) - ) - ) + ;; Ausgangszustand + (setq *geruest-dlg-variante* (itoa (geruest-erste-freie-variante *geruest-varianten*)) + *geruest-dlg-laenge* "" + *geruest-dlg-farbe* "0" *geruest-dlg-frei* "" + *geruest-dlg-konfig* "0" *geruest-dlg-winkel* "0" + *geruest-dlg-konfig-basis* nil) + (setq *geruest-dlg-bef* (geruest-dlg-standard *geruest-anbauteile*)) + (setq *geruest-dlg-sonst* (geruest-dlg-standard *geruest-sonstiges*)) (setq fertig nil rueckgabe nil) - ;; Die Dialogdefinition haengt nur an der Teileliste, nicht am Zustand - - ;; einmal erzeugen und erst nach der Schleife loeschen (unload_dialog muss - ;; vorher gelaufen sein). - (setq dcl-pfad (geruest-dcl-schreiben *geruest-anbauteile*)) + ;; Die Dialogdefinition haengt nur an Varianten und Teilelisten, nicht am + ;; Zustand - einmal aus der Vorlage fuellen und erst nach der Schleife + ;; loeschen (unload_dialog muss vorher gelaufen sein). + (setq dcl-pfad (geruest-dcl-schreiben (geruest-titel bg) *geruest-anbauteile* + *geruest-sonstiges* *geruest-varianten*)) ;; Schleife: ungueltige Eingaben, Speichern und Loeschen zeigen den Dialog ;; mit dem bisherigen Stand erneut (Projektmuster, vgl. vf_linienzug). @@ -1058,23 +1320,6 @@ (setq fertig T) ) (progn - (start_list "bereich") - (foreach b bereiche (add_list (geruest-titel (cdr b)))) - (end_list) - (set_tile "bereich" (itoa bereich-idx)) - - (set_tile "kopf" (ssg-textf "gr-dlg-kopf" (list (geruest-titel bg)))) - - (start_list "konfig") - (add_list (ssg-text "gr-konfig-keine")) - (foreach k *geruest-konfig-liste* (add_list (geruest-konfig-name k))) - (end_list) - (set_tile "konfig" *geruest-dlg-konfig*) - - (start_list "variante") - (foreach v *geruest-varianten* (add_list (geruest-eintrag-name v))) - (end_list) - (if *geruest-farb-liste* (progn (start_list "farbe") @@ -1083,8 +1328,20 @@ ) ) + (start_list "winkel") + (foreach w *geruest-winkel-werte* + (add_list (ssg-textf "gr-winkel-grad" (list (itoa w) (chr 176))))) + (end_list) + ;; Alle Tiles aus dem Zustand fuellen (auch Haken und Mengenfelder) (geruest-dlg-schreiben) + (geruest-varianten-sperren *geruest-varianten*) + ;; Konfig-Liste inkl. "(geaendert)"-Kennzeichnung und Statuszeile - + ;; auch nach Speichern/Loeschen/Fehler-Neuaufbau aktuell + (geruest-dlg-konfig-anzeigen) + ;; Der Winkel wirkt nur auf Anbauteile + (if (and (null *geruest-anbauteile*) (null *geruest-sonstiges*)) + (mode_tile "winkel" 1)) ;; Laenge/Farbe nur bei Baugruppen mit "attribute"-Block (if (null laenge-def) (mode_tile "laenge" 1)) @@ -1093,7 +1350,8 @@ (mode_tile "farbe_frei" (if (= (atoi *geruest-dlg-farbe*) *geruest-frei-idx*) 0 1)) (action_tile "farbe" - "(mode_tile \"farbe_frei\" (if (= (atoi $value) *geruest-frei-idx*) 0 1))") + (strcat "(mode_tile \"farbe_frei\" (if (= (atoi $value) *geruest-frei-idx*) 0 1))" + " (geruest-dlg-aenderung-pruefen)")) ) (progn (mode_tile "farbe" 1) @@ -1102,9 +1360,12 @@ ) (action_tile "konfig" "(geruest-dlg-konfig-waehlen (atoi $value))") - ;; Bereichswechsel: Dialog schliessen, die Schleife in c:GERUEST baut - ;; ihn mit dem neuen Bereich neu auf. - (action_tile "bereich" "(geruest-dlg-lesen) (done_dialog 4)") + ;; Jede Eingabe prueft, ob der Stand noch der gewaehlten + ;; Konfiguration entspricht (Edit-Boxen melden sich beim Verlassen). + (foreach tile (append '("variante" "laenge" "farbe_frei" "winkel") + (geruest-dlg-spalten-keys "b" *geruest-anbauteile*) + (geruest-dlg-spalten-keys "s" *geruest-sonstiges*)) + (action_tile tile "(geruest-dlg-aenderung-pruefen)")) (action_tile "accept" "(geruest-dlg-lesen) (done_dialog 1)") (action_tile "kspeichern" "(geruest-dlg-lesen) (done_dialog 2)") (action_tile "kloeschen" "(geruest-dlg-lesen) (done_dialog 3)") @@ -1115,25 +1376,18 @@ (cond ((= ergebnis 0) (setq fertig T)) - ;; Bereichswechsel: Stand dieses Bereichs sichern und an den - ;; Aufrufer zurueckmelden, damit er den neuen Bereich oeffnet. - ((= ergebnis 4) - (setq neu-idx (atoi *geruest-dlg-bereich*)) - (geruest-zustand-sichern (ssg-json-get bg "id")) - (if (= neu-idx bereich-idx) - nil - (progn - (setq rueckgabe (list "WECHSEL" neu-idx)) - (setq fertig T) - ) - ) - ) - ;; Speichern: der Name wird NACH dem Schliessen abgefragt - ;; getstring funktioniert aus einem action_tile-Rueckruf heraus ;; nicht (dasselbe Muster wie die Punktwahl im VF-Assistenten). ((= ergebnis 2) - (setq name (getstring T (ssg-text "gr-konfig-name"))) + ;; Enter uebernimmt den Namen der gewaehlten eigenen + ;; Konfiguration und ueberschreibt sie damit. + (setq vorgabe (geruest-konfig-name-vorgabe (atoi *geruest-dlg-konfig*))) + (setq name (getstring T (if vorgabe + (ssg-textf "gr-konfig-name-vorgabe" (list vorgabe)) + (ssg-text "gr-konfig-name")))) + (if (and vorgabe (or (null name) (= (ssg-cfg-trim name) ""))) + (setq name vorgabe)) (if (and name (/= (ssg-cfg-trim name) "")) (progn (setq name (ssg-cfg-trim name)) @@ -1143,6 +1397,8 @@ ;; angezeigter Stand zusammenpassen (Index 0 = ""). (setq *geruest-dlg-konfig* (itoa (geruest-konfig-index name))) + ;; Gespeicherter Stand = neue Vergleichsbasis + (setq *geruest-dlg-konfig-basis* (geruest-dlg-record name)) ) (progn (princ (ssg-text "gr-abgebrochen")) @@ -1154,6 +1410,7 @@ ((= ergebnis 3) (geruest-konfig-entfernen bg) (setq *geruest-konfig-liste* (geruest-konfigs bg)) + (if (= *geruest-dlg-konfig* "0") (setq *geruest-dlg-konfig-basis* nil)) ) ;; Laenge pruefen - Bereichspruefung erfolgt im Projekt immer nach @@ -1170,18 +1427,19 @@ ) (T - (setq oben-m (geruest-anzahlen-lesen *geruest-dlg-oben*)) - (setq unten-m (geruest-anzahlen-lesen *geruest-dlg-unten*)) - (if (or (null oben-m) (null unten-m)) + (setq bef-m (geruest-anzahlen-lesen *geruest-dlg-bef* *geruest-anbauteile*)) + (setq sonst-m (geruest-anzahlen-lesen *geruest-dlg-sonst* *geruest-sonstiges*)) + (if (or (null bef-m) (null sonst-m)) (alert (ssg-text "gr-alert-menge")) (progn (setq rueckgabe (list "OK" (atoi *geruest-dlg-variante*) - (cdr oben-m) - (cdr unten-m) + (cdr bef-m) (if laenge-def *geruest-dlg-laenge* "") - (geruest-dlg-farbwert))) + (geruest-dlg-farbwert) + (cdr sonst-m) + (geruest-winkel-aus-index *geruest-dlg-winkel*))) (setq fertig T) ) ) @@ -1215,11 +1473,12 @@ ;; Dummy-Geometrie + eigene ATTDEFs zu einem Block zusammenfassen und am ;; gewaehlten Punkt einfuegen. werte = alist der berechneten Attributwerte, ;; variante = gewaehlte Geometrie-Variante (liefert ggf. eine eigene DWG). -;; teile-dwgs = Pfade der Teile-DWGs (geruest-teile-dwgs), die zusaetzlich -;; als reine Geometrie bei 0,0,0 mit in den Block wandern. +;; teile-dwgs = ((pfad . rot) ...) der Teile-DWGs (geruest-teile-dwgs-rot), +;; die zusaetzlich als reine Geometrie bei 0,0,0 mit in den Block wandern, +;; um rot Grad um Z gedreht ("Winkel Platte" der Anbauteile). ;; Rueckgabe: (blockname . entity) oder nil. (defun geruest-block-bauen (bg variante werte pt teile-dwgs / datei dummy lastEnt dummyEnt - dummy-attribs attribs) + dummy-attribs attribs winkel-vars) ;; Eine Variante darf eine eigene Dummy-DWG mitbringen; sonst (oder wenn ;; deren Datei fehlt) gilt die der Baugruppe. (setq datei (geruest-dummy-wahl variante bg)) @@ -1252,9 +1511,19 @@ ;; einfuegen - erst NACH dem Lesen des Dummys, damit dummyEnt auf den ;; Dummy zeigt. Nur Geometrie: die Sammelschleife unten nimmt die ;; INSERTs mit in den Block, das Attribut-Schema bleibt unberuehrt. + ;; Drehwinkel in Grad, gegen den Uhrzeigersinn ab +X - dafuer die + ;; Winkel-Systemvariablen nur fuer diese Einfuegungen auf 0 stellen. + ;; Die interaktive Drehung des fertigen Blocks danach soll wieder in den + ;; Einheiten des Benutzers laufen. + (setq winkel-vars (mapcar '(lambda (v) (cons v (getvar v))) + '("ANGBASE" "ANGDIR" "AUNITS"))) + (setvar "ANGBASE" 0.0) + (setvar "ANGDIR" 0) + (setvar "AUNITS" 0) (foreach teil teile-dwgs - (command "_.INSERT" teil (list 0.0 0.0 0.0) 1 1 0) + (command "_.INSERT" (car teil) (list 0.0 0.0 0.0) 1 1 (cdr teil)) ) + (foreach v winkel-vars (setvar (car v) (cdr v))) ;; Unser Schema gewinnt an Struktur, die Dummy-Werte an Inhalt: ;; ssg-attrib-merge legt alle Tags aus *geruest-attrib-defs* an und @@ -1346,24 +1615,27 @@ ) ;; Ausgewaehlte Konfiguration einfuegen. -;; wahl = (variante-index oben unten laenge farbe) - die Dialog-Rueckgabe ohne -;; das fuehrende "OK". -(defun geruest-einfuegen (bg wahl / varianten anbauteile variante teileart - paare artnr bezeichnung teile-namen werte pt ergebnis) +;; wahl = (variante-index befestigung laenge farbe sonstiges winkel) - die +;; Dialog-Rueckgabe ohne das fuehrende "OK". +(defun geruest-einfuegen (bg wahl / varianten anbauteile sonstiges variante teileart + paare artnr basis-nr bezeichnung teile-namen werte pt + ergebnis winkel) (setq varianten (ssg-json-get bg "geometrie_varianten")) - (setq anbauteile (ssg-json-get bg "anbaugruppen")) + (setq anbauteile (geruest-anbau-liste bg "befestigung")) + (setq sonstiges (geruest-anbau-liste bg "sonstiges")) (setq variante (nth (car wahl) varianten)) ;; TEILEART kann die Variante vorgeben (Saeule 1 Zoll vs. 2 Zoll) - ;; sonst gilt der Wert der Baugruppe. (setq teileart (geruest-variante-wert variante bg "teileart")) ;; ARTINR: jede Sivas-ID so oft wie die gewaehlte Stueckzahl, erst die - ;; Basis, dann Befestigung oben, dann unten. Dasselbe Teil an beiden - ;; Positionen erscheint entsprechend mehrfach. Die Paare tragen zusaetzlich - ;; das farbig-Flag je Teil fuer die TEILEFARBE-Liste (gleiche Reihenfolge). + ;; Basis, dann Befestigung (Gesamtanzahl oben + unten), dann Sonstiges. + ;; Die Paare tragen zusaetzlich das farbig-Flag je Teil fuer die + ;; TEILEFARBE-Liste (gleiche Reihenfolge). (setq paare (geruest-teile-paare variante nil)) + (setq basis-nr (mapcar 'car paare)) (setq paare (append paare (geruest-auswahl-paare (cadr wahl) anbauteile))) - (setq paare (append paare (geruest-auswahl-paare (caddr wahl) anbauteile))) + (setq paare (append paare (geruest-auswahl-paare (nth 4 wahl) sonstiges))) (setq artnr (mapcar 'car paare)) ;; BEZEICHNUNG: mit " + " verketten - die Artikelbezeichnungen enthalten @@ -1371,30 +1643,36 @@ (setq teile-namen (list teileart (geruest-eintrag-name variante))) (setq teile-namen (append teile-namen (geruest-auswahl-namen (cadr wahl) anbauteile - (ssg-text "gr-position-oben")))) + (ssg-text "gr-position-befestigung")))) (setq teile-namen (append teile-namen - (geruest-auswahl-namen (caddr wahl) anbauteile - (ssg-text "gr-position-unten")))) + (geruest-auswahl-namen (nth 4 wahl) sonstiges + (ssg-text "gr-position-sonstiges")))) (setq bezeichnung (ssg-join teile-namen " + ")) (setq werte (list (cons "ARTINR" (ssg-join artnr ",")) (cons "BEZEICHNUNG" bezeichnung) (cons "TEILEART" teileart))) - (if (/= (nth 3 wahl) "") - (setq werte (append werte (list (cons "LAENGE" (nth 3 wahl)))))) + (if (/= (nth 2 wahl) "") + (setq werte (append werte (list (cons "LAENGE" (nth 2 wahl)))))) ;; TEILEFARBE: je ARTINR-Eintrag die gewaehlte Farbe (farbiges Teil) oder ;; "" (z.B. ",,RAL7030,,RAL7030") - fuer den Sivas-Export je Artikelnummer. - (if (/= (nth 4 wahl) "") + (if (/= (nth 3 wahl) "") (setq werte (append werte (list (cons "TEILEFARBE" - (ssg-join (geruest-farbliste paare (nth 4 wahl)) ",")))))) + (ssg-join (geruest-farbliste paare (nth 3 wahl)) ",")))))) (setq pt (getpoint (ssg-text "gr-prompt-einfuegepunkt"))) (if (null pt) (princ (ssg-text "gr-abgebrochen")) (progn (ssg-start "Geruest" '(("OSMODE") ("ATTREQ") ("ATTDIA"))) + ;; Basis-Teile ungedreht, Anbauteile im "Winkel Platte" + (setq winkel (nth 5 wahl)) + (if (not (numberp winkel)) (setq winkel 0)) (setq ergebnis (geruest-block-bauen bg variante werte pt - (geruest-teile-dwgs artnr))) + (geruest-teile-dwgs-rot + (geruest-teile-dwgs basis-nr) + (geruest-teile-dwgs (geruest-rest-liste artnr (length basis-nr))) + winkel))) (ssg-end) (if ergebnis (princ (ssg-textf "gr-fertig" (list teileart (car ergebnis)))) @@ -1405,59 +1683,27 @@ ) -;; Index eines Bereichs ueber das ASCII-Feld "id" (nil, wenn unbekannt). -(defun geruest-bereich-index (id bereiche / i idx) - (setq i 0 idx nil) - (foreach b bereiche - (if (and (null idx) (equal (car b) id)) (setq idx i)) - (setq i (1+ i)) - ) - idx -) - -;; Ein Dialog fuer alle Geruest-Bereiche. Der Bereichswechsel laeuft ueber -;; diese Schleife, weil der Dialog dafuer neu aufgebaut werden muss. -;; start-id = "id" des Bereichs, mit dem der Dialog oeffnet (nil oder -;; unbekannt -> erster Bereich). Der Wechsel per Dropdown bleibt moeglich. -(defun geruest-starten (start-id / bereiche idx bg erg weiter) - (setq *geruest-zustand* nil) - (setq bereiche (geruest-baugruppen-liste)) - (if (null bereiche) - (princ (ssg-text "gr-fehler-keine-baugruppen")) - (progn - (setq idx (if start-id (geruest-bereich-index start-id bereiche))) - (if (null idx) (setq idx 0)) - (setq weiter T) - (while weiter - (setq bg (cdr (nth idx bereiche))) - (cond - ((null (ssg-json-get bg "geometrie_varianten")) - (princ (ssg-textf "gr-fehler-keine-varianten" - (list (ssg-json-get bg "id")))) - (setq weiter nil) - ) - (T - (setq erg (geruest-dialog bg idx bereiche)) - (cond - ((null erg) - (princ (ssg-text "gr-abgebrochen")) - (setq weiter nil)) - ((equal (car erg) "WECHSEL") (setq idx (cadr erg))) - (T - (setq weiter nil) - (geruest-einfuegen bg (cdr erg))) - ) - ) - ) - ) - ) +;; Dialog fuer genau einen Bereich (id = ASCII-Feld "id" der Baugruppe) +;; zeigen und das Ergebnis einfuegen. Jeder Bereich hat seinen eigenen +;; Menuebefehl - eine Umschaltung im Dialog gibt es nicht. +(defun geruest-starten (id / bg erg) + (setq bg (if (geruest-daten) (geruest-baugruppe id (geruest-daten)))) + (cond + ((null (geruest-daten)) (princ (ssg-text "gr-fehler-keine-baugruppen"))) + ((null bg) (princ (ssg-textf "gr-fehler-baugruppe" (list id)))) + ((null (ssg-json-get bg "geometrie_varianten")) + (princ (ssg-textf "gr-fehler-keine-varianten" (list id)))) + ((null (setq erg (geruest-dialog bg))) + (princ (ssg-text "gr-abgebrochen"))) + (T (geruest-einfuegen bg (cdr erg))) ) (princ) ) -(defun c:GERUEST ( / ) (geruest-starten nil)) +;; Ohne Bereich kein Dialog - die Bereiche oeffnen nur ihre eigenen Befehle. +(defun c:GERUEST ( / ) (princ (ssg-text "gr-bereich-waehlen")) (princ)) -;; Menue-Einstiege je Bereich - oeffnen denselben Dialog im passenden Bereich. +;; Menue-Einstiege je Bereich (defun c:GERUEST_SAEULEN ( / ) (geruest-starten "Saeulen")) (defun c:GERUEST_ROHRABHAENGER ( / ) (geruest-starten "Rohrabhaenger")) (defun c:GERUEST_WANDBEFESTIGUNG ( / ) (geruest-starten "Wandbefestigung")) @@ -1628,7 +1874,9 @@ ;; Querstreben-Konfiguration (Variante vor Baugruppe) als ;; (dummy laenge querlinie abstand rand-min rand-max) oder nil, wenn keine -;; "querstrebe" definiert ist. +;; "querstrebe" definiert ist oder die Variante kein "mit_querstrebe": true +;; traegt. Das Flag steht bewusst ausdruecklich je Variante (wie "mit_muffe"), +;; ein 1"-Rohr hat z.B. keine Querstreben. ;; dummy = DWG unter data/geruest (Basispunkt Strebenmitte, 30 mm laengs ;; X) oder nil ;; laenge/querlinie = nur fuer den Rueckfall ohne Dummy-DWG: zwei Querlinien @@ -1636,7 +1884,7 @@ ;; Fehlende Zahlenwerte -> Standard 30/25/500/100/250. (defun geruest-traeger-strebe-cfg (variante bg / q w d) (setq q (geruest-variante-wert variante bg "querstrebe")) - (if (and q (listp q)) + (if (and variante (ssg-json-get variante "mit_querstrebe") q (listp q)) (progn (setq d (ssg-json-get q "dummy")) (cons (if (and d (= (type d) 'STR) (/= d "")) d) @@ -1683,16 +1931,11 @@ (ssg-join teile " + ") ) -(defun geruest-traeger-dcl-pfad ( / basis) - (setq basis (cond ((getenv "DXFM_DCL")) - ((getenv "DXFMAKRO") (strcat (getenv "DXFMAKRO") "/dcl")))) - (if basis - (strcat (vl-string-translate "\\" "/" basis) "/geruest_traeger.dcl") - ) -) - ;; --- Dialogzustand (Globals, siehe Abschnitt DIALOGZUSTAND oben) --- -;; Bleibt zwischen zwei GERUEST_TRAEGER-Aufrufen erhalten. +;; Bleibt zwischen zwei Aufrufen derselben Baugruppe erhalten. +;; *geruest-tr-variante* = Index der Variante in geometrie_varianten (String). +;; Jede Variante - auch die mit Muffe - hat ihren eigenen Radiobutton, damit +;; ihre Artikelnummer im Dialog sichtbar ist. ;; Abzug-Vorgaben (aktiv + Wert) der Variante idx in den Zustand laden. (defun geruest-tr-vorgaben-laden (idx / v) @@ -1716,15 +1959,15 @@ (mode_tile "abzug_e_w" (if (= *geruest-tr-abzug-e* "1") 0 1)) ) -;; Variantenwechsel im Dialog: Abzug-Vorgaben der neuen Variante uebernehmen. -(defun geruest-tr-variante-gewaehlt (wert / ) - (setq *geruest-tr-variante* wert) - (geruest-tr-vorgaben-laden (atoi wert)) +;; Variantenwechsel: Abzug-Vorgaben der neuen Variante uebernehmen. +(defun geruest-tr-variante-gewaehlt (key / ) + (setq *geruest-tr-variante* (itoa (geruest-radio-index key))) + (geruest-tr-vorgaben-laden (atoi *geruest-tr-variante*)) (geruest-tr-abzug-schreiben) ) (defun geruest-tr-dlg-lesen ( / ) - (setq *geruest-tr-variante* (get_tile "variante")) + (setq *geruest-tr-variante* (itoa (geruest-radio-index (get_tile "variante")))) (setq *geruest-tr-farbe* (get_tile "farbe")) (setq *geruest-tr-frei* (get_tile "farbe_frei")) (setq *geruest-tr-abzug-a* (get_tile "abzug_a")) @@ -1739,44 +1982,60 @@ (if (= aktiv "1") (geruest-abzug-wert wert) 0.0) ) -;; Traeger-Dialog. Rueckgabe: +;; Dialog fuer Linien-Baugruppen (Rohr-Geruest-Traeger, Omniflo-Fahrstrecke). +;; dcl-datei = Vorlage unter dcl/ (z.B. "geruest_traeger.dcl"), dlg-name = +;; Dialogname darin. Rueckgabe: ;; (variante-index farbe abzug-anfang abzug-ende beschriften-p) oder nil bei -;; Abbruch. -(defun geruest-traeger-dialog (bg / varianten dcl-pfad dat fertig rueckgabe - ergebnis aw ew) +;; Abbruch. variante-index = Index in geometrie_varianten. +(defun geruest-traeger-dialog (bg dcl-datei dlg-name / varianten dcl-pfad dat + fertig rueckgabe ergebnis aw ew) (setq varianten (ssg-json-get bg "geometrie_varianten")) (setq *geruest-tr-bg* bg) + ;; Der Dialogstand bleibt zwischen zwei Aufrufen erhalten - aber nur fuer + ;; dieselbe Baugruppe: ein Varianten-Index des Traegers passt nicht zur + ;; Fahrstrecke. + (if (not (equal (ssg-json-get bg "id") *geruest-tr-id*)) + (setq *geruest-tr-id* (ssg-json-get bg "id") + *geruest-tr-variante* nil)) (geruest-farb-liste-setzen (ssg-json-get (ssg-json-get bg "attribute") "TEILEFARBE")) ;; Ausgangszustand beim ersten Aufruf bzw. wenn der gemerkte Index nach - ;; einer JSON-Aenderung nicht mehr passt. + ;; einer JSON-Aenderung nicht mehr passt oder die Variante gesperrt wurde. (if (or (null *geruest-tr-variante*) - (>= (atoi *geruest-tr-variante*) (length varianten))) + (/= (atoi *geruest-tr-variante*) + (geruest-variante-waehlbar varianten (atoi *geruest-tr-variante*)))) (progn - (setq *geruest-tr-variante* "0" *geruest-tr-farbe* "0" *geruest-tr-frei* "") - (geruest-tr-vorgaben-laden 0) + (setq *geruest-tr-variante* (itoa (geruest-erste-freie-variante varianten)) + *geruest-tr-farbe* "0" *geruest-tr-frei* "") + (geruest-tr-vorgaben-laden (atoi *geruest-tr-variante*)) ) ) ;; Beschriftung standardmaessig an; der Haken bleibt zwischen Aufrufen (if (null *geruest-tr-beschriftung*) (setq *geruest-tr-beschriftung* "1")) - (setq dcl-pfad (geruest-traeger-dcl-pfad)) + ;; Vorlage einmal fuellen (ein Radiobutton je Variante), nach der + ;; Schleife loeschen. + (setq dcl-pfad + (ssg-dcl-vorlage-fuellen (geruest-dcl-vorlage-pfad dcl-datei) + "grlinie" + (list (cons "VARIANTEN" + (geruest-dcl-varianten-zeilen varianten + (geruest-indizes (length varianten))))))) (setq fertig nil rueckgabe nil) ;; Schleife: ungueltige Eingaben zeigen den Dialog mit dem bisherigen ;; Stand erneut - DCL kann Zahlen nicht selbst pruefen. (while (not fertig) - (setq dat (if (and dcl-pfad (findfile dcl-pfad)) (load_dialog dcl-pfad) -1)) - (if (or (< dat 0) (not (new_dialog "geruest_traeger" dat))) + (setq dat (if dcl-pfad (load_dialog dcl-pfad) -1)) + (if (or (< dat 0) (not (new_dialog dlg-name dat))) (progn (alert (ssg-textf "gr-tr-fehler-dcl" - (list (if dcl-pfad dcl-pfad "geruest_traeger.dcl")))) + (list (cond ((geruest-dcl-vorlage-pfad dcl-datei)) + (dcl-datei))))) (setq fertig T) ) (progn - (start_list "variante") - (foreach v varianten (add_list (geruest-eintrag-name v))) - (end_list) - (set_tile "variante" *geruest-tr-variante*) + (set_tile "variante" (geruest-radio-key (atoi *geruest-tr-variante*))) + (geruest-varianten-sperren varianten) (if *geruest-farb-liste* (progn @@ -1827,6 +2086,7 @@ ) ) ) + (if dcl-pfad (vl-file-delete dcl-pfad)) rueckgabe ) @@ -1925,8 +2185,10 @@ abzug-a abzug-e min-l max-l bez werte-basis werte weiter p1 eingabe strecke winkel netto ergebnis anzahl strebe strebe-pfad muffe-pfad - beschriften) + beschriften titel) (setq variante (nth (car wahl) (ssg-json-get bg "geometrie_varianten"))) + ;; Bauteilname fuer die Meldungen ("Traeger", "Fahrstrecke") + (setq titel (geruest-titel bg)) (setq farbe (cadr wahl) abzug-a (caddr wahl) abzug-e (cadddr wahl) @@ -1965,7 +2227,7 @@ (setq weiter T anzahl 0) (while weiter (setq strecke nil) - (setq p1 (getpoint (ssg-text "gr-tr-prompt-start"))) + (setq p1 (getpoint (ssg-textf "gr-tr-prompt-start" (list titel)))) (if (null p1) (setq weiter nil) (progn @@ -2000,12 +2262,12 @@ ((null netto) (princ (ssg-textf "gr-tr-laenge-null" (list (geruest-mm-string strecke) - (geruest-mm-string (+ abzug-a abzug-e)))))) + (geruest-mm-string (+ abzug-a abzug-e)) titel)))) ((not (geruest-traeger-pruefen netto min-l max-l)) (princ (ssg-textf "gr-tr-laenge-bereich" (list (geruest-mm-string netto) (if min-l (geruest-mm-string min-l) "0") - (if max-l (geruest-mm-string max-l) "-"))))) + (if max-l (geruest-mm-string max-l) "-") titel)))) (T ;; Streben-Rand ausserhalb der Grenzen: informieren, aber trotzdem ;; einfuegen (der Abstand zwischen den Streben bleibt immer exakt) @@ -2019,13 +2281,13 @@ ;; Beschriftung aus dem fertigen Block ableiten (dieselbe Funktion ;; wie GERUEST_TRAEGER_BESCHRIFTEN) (if (and ergebnis beschriften) - (geruest-traeger-beschriften (cdr ergebnis))) + (geruest-traeger-beschriften (cdr ergebnis) bg)) (ssg-end) (if ergebnis (progn (setq anzahl (1+ anzahl)) (princ (ssg-textf "gr-tr-fertig" - (list (geruest-mm-string netto) (car ergebnis)))) + (list (geruest-mm-string netto) (car ergebnis) titel))) ) ) ) @@ -2033,7 +2295,7 @@ ) ) ) - (princ (ssg-textf "gr-tr-ende" (list (itoa anzahl)))) + (princ (ssg-textf "gr-tr-ende" (list (itoa anzahl) titel))) (princ) ) @@ -2185,14 +2447,15 @@ ) ) -;; Einen Traeger-Block beschriften (eine evtl. vorhandene Beschriftung wird -;; ersetzt). Rueckgabe: "ok", "ersatz" (Block ohne bekannte VARIANTE, mit den -;; Vorgaben der Baugruppe beschriftet) oder nil (nicht beschriftbar). -(defun geruest-traeger-beschriften (blockEnt / ed attribs bg vname idx variante +;; Einen Linien-Block (Traeger, Fahrstrecke) beschriften (eine evtl. +;; vorhandene Beschriftung wird ersetzt). bg = Baugruppe, aus deren JSON die +;; Formatierung kommt. Rueckgabe: "ok", "ersatz" (Block ohne bekannte +;; VARIANTE, mit den Vorgaben der Baugruppe beschriftet) oder nil (nicht +;; beschriftbar). +(defun geruest-traeger-beschriften (blockEnt bg / ed attribs vname idx variante cfg laenge lage lay handle code erg) (setq ed (entget blockEnt)) (setq attribs (ssg-attrib-read blockEnt)) - (setq bg (geruest-baugruppe "Traeger" (geruest-traeger-daten))) (setq laenge (atof (cond ((cdr (assoc "LAENGE" attribs))) ("0")))) (if (and bg (> laenge 0.0)) (progn @@ -2241,11 +2504,15 @@ erg ) -;; Alle Traeger der Zeichnung (neu) beschriften und Beschriftungen, deren -;; Block nicht mehr existiert, entfernen - unabhaengig von der Checkbox im -;; Einfuegedialog. -(defun c:GERUEST_TRAEGER_BESCHRIFTEN ( / ss i n-ok n-ersatz n-fehl n-weg e h ziel erg) +;; Alle Linien-Bloecke einer Baugruppe (Blockname GR__*) neu beschriften +;; und Beschriftungen, deren Block nicht mehr existiert, entfernen - +;; unabhaengig von der Checkbox im Einfuegedialog. Verwaiste Texte werden +;; unabhaengig vom Typ entfernt (am Text ist nicht erkennbar, zu welchem +;; Typ der geloeschte Block gehoerte). +(defun geruest-linien-beschriften-alle (bg / ss i n-ok n-ersatz n-fehl n-weg e h + ziel erg titel) (setq *geruest-beschr-gemeldet* nil) + (setq titel (geruest-titel bg)) (setq n-ok 0 n-ersatz 0 n-fehl 0 n-weg 0) (ssg-start nil nil) ;; Verwaiste Beschriftungen zuerst entfernen @@ -2264,38 +2531,73 @@ ) ) ) - (if (setq ss (ssget "_X" '((0 . "INSERT") (2 . "GR_Traeger_*")))) + (if (setq ss (ssget "_X" (list '(0 . "INSERT") + (cons 2 (strcat "GR_" (ssg-json-get bg "id") "_*"))))) (progn (setq i 0) (repeat (sslength ss) - (setq erg (geruest-traeger-beschriften (ssname ss i))) + (setq erg (geruest-traeger-beschriften (ssname ss i) bg)) (cond ((= erg "ok") (setq n-ok (1+ n-ok))) ((= erg "ersatz") (setq n-ersatz (1+ n-ersatz))) (T (setq n-fehl (1+ n-fehl)))) (setq i (1+ i)) ) (princ (ssg-textf "gr-tr-beschr-ergebnis" - (list (itoa (+ n-ok n-ersatz)) (itoa n-ersatz) (itoa n-fehl) (itoa n-weg)))) + (list (itoa (+ n-ok n-ersatz)) (itoa n-ersatz) (itoa n-fehl) (itoa n-weg) + titel))) ) - (princ (ssg-text "gr-tr-beschr-keine")) + (princ (ssg-textf "gr-tr-beschr-keine" (list titel))) ) (ssg-end) (princ) ) -(defun c:GERUEST_TRAEGER ( / bg wahl) - (setq bg (geruest-baugruppe "Traeger" (geruest-traeger-daten))) +;; Linien-Baugruppe aus ihrer Datendatei holen, Dialog zeigen, einfuegen. +;; id = "id" der Baugruppe, daten = geparste JSON, dcl-datei/dlg-name siehe +;; geruest-traeger-dialog. +(defun geruest-linien-starten (id daten dcl-datei dlg-name / bg wahl) + (setq bg (geruest-baugruppe id daten)) (cond ((null bg) - (princ (ssg-textf "gr-fehler-baugruppe" (list "Traeger")))) + (princ (ssg-textf "gr-fehler-baugruppe" (list id)))) ((null (ssg-json-get bg "geometrie_varianten")) - (princ (ssg-textf "gr-fehler-keine-varianten" (list "Traeger")))) - ((null (setq wahl (geruest-traeger-dialog bg))) + (princ (ssg-textf "gr-fehler-keine-varianten" (list id)))) + ((null (setq wahl (geruest-traeger-dialog bg dcl-datei dlg-name))) (princ (ssg-text "gr-abgebrochen"))) (T (geruest-traeger-einfuegen bg wahl)) ) (princ) ) -(princ "\nGeruestInsert.lsp geladen. Befehle: GERUEST, GERUEST_SAEULEN, GERUEST_ROHRABHAENGER, GERUEST_WANDBEFESTIGUNG, GERUEST_TRAEGER, GERUEST_TRAEGER_BESCHRIFTEN") +;; Beschriftung aller Bloecke einer Linien-Baugruppe (siehe +;; geruest-linien-beschriften-alle). +(defun geruest-linien-beschriften (id daten / bg) + (if (setq bg (geruest-baugruppe id daten)) + (geruest-linien-beschriften-alle bg) + (princ (ssg-textf "gr-fehler-baugruppe" (list id))) + ) + (princ) +) + +(defun c:GERUEST_TRAEGER ( / ) + (geruest-linien-starten "Traeger" (geruest-traeger-daten) + "geruest_traeger.dcl" "geruest_traeger") +) + +(defun c:GERUEST_TRAEGER_BESCHRIFTEN ( / ) + (geruest-linien-beschriften "Traeger" (geruest-traeger-daten)) +) + +;; Omniflo-Fahrstrecke: dieselbe Linien-Logik, Daten aus omniflo_fahrstrecke.json, +;; eigener Dialog dcl/fahrstrecke.dcl. +(defun c:OMNI_FAHRSTRECKE ( / ) + (geruest-linien-starten "Fahrstrecke" (geruest-fahrstrecke-daten) + "fahrstrecke.dcl" "fahrstrecke") +) + +(defun c:OMNI_FAHRSTRECKE_BESCHRIFTEN ( / ) + (geruest-linien-beschriften "Fahrstrecke" (geruest-fahrstrecke-daten)) +) + +(princ "\nGeruestInsert.lsp geladen. Befehle: GERUEST, GERUEST_SAEULEN, GERUEST_ROHRABHAENGER, GERUEST_WANDBEFESTIGUNG, GERUEST_TRAEGER, GERUEST_TRAEGER_BESCHRIFTEN, OMNI_FAHRSTRECKE, OMNI_FAHRSTRECKE_BESCHRIFTEN") (princ) diff --git a/Lisp/OmniModulInsert.lsp b/Lisp/OmniModulInsert.lsp index 5588753..181f136 100644 --- a/Lisp/OmniModulInsert.lsp +++ b/Lisp/OmniModulInsert.lsp @@ -1479,6 +1479,27 @@ (princ) ) +;; --- Omniflo / Türlösungen Schwenkschienen --- +;; Feste TEF-Bauteile ohne Sivas-Auswahl: Datei liegt direkt unter DXFM_OMNIFLO, +;; wird per omni:insert-dxf am gewaehlten Einfuegepunkt ohne Drehung eingefuegt. +(defun c:OMNI_SCHW_400_R () + (omni:insert-dxf "824604002" nil nil) + (princ) +) +(defun c:OMNI_SCHW_400_L () + (omni:insert-dxf "824604001" nil nil) + (princ) +) +(defun c:OMNI_SCHW_400_R_SENSORIK () + (omni:insert-dxf "824604012" nil nil) + (princ) +) +(defun c:OMNI_SCHW_400_L_SENSORIK () + (omni:insert-dxf "824604011" nil nil) + (princ) +) + + ;; --- Omniflo / TEF Elemente --- diff --git a/Lisp/ssg_core.lsp b/Lisp/ssg_core.lsp index cfe95c8..d344015 100644 --- a/Lisp/ssg_core.lsp +++ b/Lisp/ssg_core.lsp @@ -1643,10 +1643,9 @@ ;; Schreibt eine Liste von Textzeilen als temporaere DCL-Datei und liefert ;; deren Pfad zurueck (oder nil bei Fehler, z.B. wenn open scheitert). Der ;; Aufrufer ist fuer load_dialog/unload_dialog UND das Loeschen der Datei -;; (vl-file-delete) danach selbst verantwortlich - analog zum bestehenden -;; Muster in GeruestInsert.lsp (geruest-dcl-schreiben), hier nur als -;; generischer Baustein fuer WEITERE Aufrufer (GeruestInsert.lsp selbst -;; bleibt unveraendert, um dessen Code nicht anzufassen). +;; (vl-file-delete) danach selbst verantwortlich. Fuer Dialoge mit fester +;; Grundstruktur und nur einzelnen datenabhaengigen Bloecken siehe +;; ssg-dcl-vorlage-fuellen. (defun ssg-dcl-temp-schreiben (praefix zeilen / pfad f) (setq pfad (vl-filename-mktemp praefix nil ".dcl")) (if (setq f (open pfad "w")) @@ -1659,6 +1658,46 @@ ) ) +;; DCL-Vorlagen mit Platzhaltern: DCL kann Tiles weder zur Laufzeit erzeugen +;; noch ausblenden, und Labels von radio_button/toggle lassen sich per +;; set_tile nicht aendern. Datenabhaengige Teile (z.B. ein Radiobutton je +;; Variante) werden darum in eine statische .dcl-Vorlage eingesetzt: jede +;; Zeile, die getrimmt genau "//@NAME@" lautet, wird durch die Zeilen aus +;; ersetzungen (("NAME" . (zeile ...)) ...) ersetzt. Eine leere Liste +;; entfernt die Markerzeile; ein unbekannter Marker bleibt als DCL-Kommentar +;; stehen (harmlos). Das Layout bleibt so eine normale, lesbare .dcl-Datei. +(defun ssg-dcl-zeilen-ersetzen (zeilen ersetzungen / erg t1 name e) + (setq erg nil) + (foreach z zeilen + (setq t1 (vl-string-trim " \t" z)) + (setq name (if (and (> (strlen t1) 4) + (= (substr t1 1 3) "//@") + (= (substr t1 (strlen t1) 1) "@")) + (substr t1 4 (- (strlen t1) 4)))) + (if (and name (setq e (assoc name ersetzungen))) + (setq erg (append erg (cdr e))) + (setq erg (append erg (list z))) + ) + ) + erg +) + +;; Vorlage lesen, Platzhalter ersetzen (ssg-dcl-zeilen-ersetzen) und als +;; temporaere DCL-Datei schreiben. Rueckgabe: Pfad oder nil (Vorlage fehlt / +;; nicht lesbar / nicht schreibbar). Laden und Loeschen wie bei +;; ssg-dcl-temp-schreiben durch den Aufrufer. +(defun ssg-dcl-vorlage-fuellen (vorlage-pfad praefix ersetzungen / f z zeilen) + (if (and vorlage-pfad (findfile vorlage-pfad) (setq f (open vorlage-pfad "r"))) + (progn + (setq zeilen nil) + (while (setq z (read-line f)) (setq zeilen (cons z zeilen))) + (close f) + (ssg-dcl-temp-schreiben praefix + (ssg-dcl-zeilen-ersetzen (reverse zeilen) ersetzungen)) + ) + ) +) + ;; ------------------------------------------------------------ ;; REKURSIVER JSON-PARSER diff --git a/Lisp/ssg_stueckliste.lsp b/Lisp/ssg_stueckliste.lsp index 2960799..1843f6b 100644 --- a/Lisp/ssg_stueckliste.lsp +++ b/Lisp/ssg_stueckliste.lsp @@ -163,6 +163,10 @@ (cons "ils_kreisel" (ssg-text "sl-erk-kreisel"))) ((or (wcmatch b "VF_*") (wcmatch b "GF_*")) (cons "ils_strecke" (ssg-text "sl-erk-strecke"))) + ;; Fahrstrecke (OMNI_FAHRSTRECKE) entsteht ueber den Geruest-Baukasten und + ;; traegt darum ebenfalls das GR_-Praefix - VOR dem allgemeinen GR_-Zweig. + ((wcmatch b "GR_FAHRSTRECKE_*") + (cons "fahrstrecke" (ssg-text "sl-erk-fahrstrecke"))) ((wcmatch b "GR_*") (cons "geruest" (ssg-text "sl-erk-geruest"))) ((wcmatch b "AP60*") diff --git a/data/json/geruest.json b/data/json/geruest.json index d19f920..a8aa434 100644 --- a/data/json/geruest.json +++ b/data/json/geruest.json @@ -83,137 +83,99 @@ ] } ], - "anbaugruppen": [ - { - "artikel": "SPANNPRATZE ST - KH 8-11 KPL.SELBSTSICHERND", - "sivas_id": 821004120, - "farbig": false, - "stueckzahl": 1, - "anzahl_vorgabe": 1 - }, - { - "artikel": "SPANNPRATZE SELBSTSICHERND KPL.", - "sivas_id": 821004058, - "farbig": false, - "stueckzahl": 1, - "anzahl_vorgabe": 1 - }, - { - "name": "Schraubenset", - "anzahl_vorgabe": 1, - "teile": [ - { - "artikel": "Scheibe DIN 125 - A 10,5 - 140 HV - St", - "sivas_id": 913011010, - "farbig": false, - "stueckzahl": 1 - }, - { - "artikel": "Sechskantmutter DIN 934 - M10 - 8", - "sivas_id": 912011010, - "farbig": false, - "stueckzahl": 2 - }, - { - "artikel": "Sechskantschraube DIN 933 - M10 x 30 - 8.8", - "sivas_id": 911011008, - "farbig": false, - "stueckzahl": 1 - } - ] - }, - { - "artikel": "U-BÜGEL M7 41X49 FÜR PROFILGERÜST - BG", - "sivas_id": 825004049, - "farbig": false, - "stueckzahl": 1, - "anzahl_vorgabe": 1 - }, - { - "artikel": "ROHRKLAMMER 1\" KPL. VERTIKAL", - "sivas_id": 825004040, - "farbig": false, - "stueckzahl": 1, - "anzahl_vorgabe": 2 - }, - { - "artikel": "WINKEL 60X60X6X300", - "sivas_id": 821006043, - "farbig": false, - "stueckzahl": 1, - "anzahl_vorgabe": 1 - }, - { - "artikel": "WINKEL 60X60X6X60", - "sivas_id": 821006042, - "farbig": false, - "stueckzahl": 1, - "anzahl_vorgabe": 1 - }, - { - "artikel": "ROHRKLAMMER 1\" T-VERBINDUNG KPL.", - "sivas_id": 825004030, - "farbig": false, - "stueckzahl": 1, - "anzahl_vorgabe": 1 - }, - { - "artikel": "ROHRKLAMMER 1\" FLACH UND LANG, KPL.", - "sivas_id": 825002021, - "farbig": false, - "stueckzahl": 1, - "anzahl_vorgabe": 1 - }, - { - "artikel": "DURCHSTECKANKER HST M12X115X20", - "sivas_id": 922021003, - "farbig": false, - "stueckzahl": 1, - "anzahl_vorgabe": 1 - } - ], - "konfigurationen": [ - { - "name": "Abhaengung Spannpratze / Rohrklammer", - "variante": "ROHR R 1\" 33,7 x 2,6", - "laenge": 2000, - "teilefarbe": "RAL7035", - "oben": [ - { - "artikel": "SPANNPRATZE SELBSTSICHERND KPL.", - "anzahl": 1 - }, - { - "artikel": "Schraubenset", - "anzahl": 1 - } - ], - "unten": [ - { - "artikel": "ROHRKLAMMER 1\" KPL. VERTIKAL", - "anzahl": 2 - } - ] - }, - { - "name": "Abhaengung Duebel / T-Verbindung", - "variante": "ROHR R 1\" 33,7 x 2,6 einseitig gequetscht", - "laenge": 1500, - "teilefarbe": "RAL7035", - "oben": [ - { - "artikel": "DURCHSTECKANKER HST M12X115X20", - "anzahl": 2 - } - ], - "unten": [ - { - "artikel": "ROHRKLAMMER 1\" T-VERBINDUNG KPL.", - "anzahl": 1 - } - ] - } - ] + "anbaugruppen": { + "befestigung": [ + { + "artikel": "SPANNPRATZE ST - KH 8-11 KPL.SELBSTSICHERND", + "sivas_id": 821004120, + "farbig": false, + "stueckzahl": 1, + "anzahl_vorgabe": 1 + }, + { + "artikel": "SPANNPRATZE SELBSTSICHERND KPL.", + "sivas_id": 821004058, + "farbig": false, + "stueckzahl": 1, + "anzahl_vorgabe": 1 + }, + { + "name": "Schraubenset", + "anzahl_vorgabe": 1, + "teile": [ + { + "artikel": "Scheibe DIN 125 - A 10,5 - 140 HV - St", + "sivas_id": 913011010, + "farbig": false, + "stueckzahl": 1 + }, + { + "artikel": "Sechskantmutter DIN 934 - M10 - 8", + "sivas_id": 912011010, + "farbig": false, + "stueckzahl": 2 + }, + { + "artikel": "Sechskantschraube DIN 933 - M10 x 30 - 8.8", + "sivas_id": 911011008, + "farbig": false, + "stueckzahl": 1 + } + ] + }, + { + "artikel": "U-BÜGEL M7 41X49 FÜR PROFILGERÜST - BG", + "sivas_id": 825004049, + "farbig": false, + "stueckzahl": 1, + "anzahl_vorgabe": 1 + }, + { + "artikel": "ROHRKLAMMER 1\" KPL. VERTIKAL", + "sivas_id": 825004040, + "farbig": false, + "stueckzahl": 1, + "anzahl_vorgabe": 2 + }, + { + "artikel": "WINKEL 60X60X6X300", + "sivas_id": 821006043, + "farbig": false, + "stueckzahl": 1, + "anzahl_vorgabe": 1 + }, + { + "artikel": "WINKEL 60X60X6X60", + "sivas_id": 821006042, + "farbig": false, + "stueckzahl": 1, + "anzahl_vorgabe": 1 + }, + { + "artikel": "ROHRKLAMMER 1\" T-VERBINDUNG KPL.", + "sivas_id": 825004030, + "farbig": false, + "stueckzahl": 1, + "anzahl_vorgabe": 1 + }, + { + "artikel": "ROHRKLAMMER 1\" FLACH UND LANG, KPL.", + "sivas_id": 825002021, + "farbig": false, + "stueckzahl": 1, + "anzahl_vorgabe": 1 + }, + { + "artikel": "DURCHSTECKANKER HST M12X115X20", + "sivas_id": 922021003, + "farbig": false, + "stueckzahl": 1, + "anzahl_vorgabe": 1 + } + ], + "sonstiges": [] + }, + "konfigurationen": [] }, "Säulen": { "id": "Saeulen", @@ -273,126 +235,90 @@ ] } ], - "anbaugruppen": [ - { - "artikel": "KLEMMRING MIT MUFFE EINFACH KPL.", - "sivas_id": 825002019, - "farbig": false, - "stueckzahl": 1, - "anzahl_vorgabe": 2 - }, - { - "artikel": "KLEMMRING MIT MUFFE DOPPELT 90 Grad, KPL.", - "sivas_id": 825002009, - "farbig": false, - "stueckzahl": 1, - "anzahl_vorgabe": 2 - }, - { - "artikel": "KLEMMRING MIT MUFFE DOPPELT 180 Grad, KPL.", - "sivas_id": 825002008, - "farbig": false, - "stueckzahl": 1, - "anzahl_vorgabe": 2 - }, - { - "artikel": "KLEMMRING M. MUFFE DREIFACH 90 Grad/180 Grad KPL.", - "sivas_id": 825002007, - "farbig": false, - "stueckzahl": 1, - "anzahl_vorgabe": 2 - }, - { - "artikel": "KLEMMRING MIT LASCHE KPL. ZUSAMMENBAUZEICHNUNG", - "sivas_id": 825002020, - "farbig": false, - "stueckzahl": 1, - "anzahl_vorgabe": 2 - }, - { - "artikel": "QUERSCHELLE F. 1\" UND 2\" ROHR GESCHW./VZ. M. 4X M10X30 KPL.", - "sivas_id": 825002022, - "farbig": false, - "stueckzahl": 1, - "anzahl_vorgabe": 2 - }, - { - "artikel": "KREUZSCHELLE F. 2\" UND 1\" ROHR SCHWENKBAR 360 Grad", - "sivas_id": 922083009, - "farbig": false, - "stueckzahl": 1, - "anzahl_vorgabe": 2 - }, - { - "artikel": "HALTEARM FÜR BODENSÄULE R 2\" 1-ARMIG KPL.", - "sivas_id": 821004051, - "farbig": true, - "stueckzahl": 1, - "anzahl_vorgabe": 1 - }, - { - "artikel": "HALTEARM FÜR BODENSÄULE R 2\" 2-ARMIG 90 Grad KPL.", - "sivas_id": 821004054, - "farbig": true, - "stueckzahl": 1, - "anzahl_vorgabe": 1 - }, - { - "artikel": "HALTEARM FÜR BODENSÄULE R 2\" 2-ARMIG 180 Grad KPL.", - "sivas_id": 821004052, - "farbig": true, - "stueckzahl": 1, - "anzahl_vorgabe": 1 - }, - { - "artikel": "HALTEARM FÜR BODENSÄULE R 2\" 3-ARMIG KPL.", - "sivas_id": 821004053, - "farbig": true, - "stueckzahl": 1, - "anzahl_vorgabe": 1 - } - ], - "konfigurationen": [ - { - "name": "Bodensaeule 1 Zoll, Standardhoehe", - "variante": "R 1\"", - "laenge": 1000, - "teilefarbe": "RAL7035", - "oben": [], - "unten": [] - }, - { - "name": "Bodensaeule 2 Zoll, Haltearm 1-armig", - "variante": "R 2\" Haltearm 1-ARMIG", - "laenge": 1200, - "teilefarbe": "RAL7035", - "oben": [ - { - "artikel": "KLEMMRING MIT MUFFE EINFACH KPL.", - "anzahl": 2 - } - ], - "unten": [] - }, - { - "name": "Bodensaeule 2 Zoll, Haltearm 2-armig 90 Grad", - "variante": "R 2\" Haltearm 2-ARMIG 90 Grad", - "laenge": 1200, - "teilefarbe": "RAL7035", - "oben": [ - { - "artikel": "KLEMMRING MIT MUFFE DOPPELT 90 Grad, KPL.", - "anzahl": 2 - } - ], - "unten": [ - { - "artikel": "QUERSCHELLE F. 1\" UND 2\" ROHR GESCHW./VZ. M. 4X M10X30 KPL.", - "anzahl": 2 - } - ] - } - ] + "anbaugruppen": { + "befestigung": [ + { + "artikel": "KLEMMRING MIT MUFFE EINFACH KPL.", + "sivas_id": 825002019, + "farbig": false, + "stueckzahl": 1, + "anzahl_vorgabe": 2 + }, + { + "artikel": "KLEMMRING MIT MUFFE DOPPELT 90 Grad, KPL.", + "sivas_id": 825002009, + "farbig": false, + "stueckzahl": 1, + "anzahl_vorgabe": 2 + }, + { + "artikel": "KLEMMRING MIT MUFFE DOPPELT 180 Grad, KPL.", + "sivas_id": 825002008, + "farbig": false, + "stueckzahl": 1, + "anzahl_vorgabe": 2 + }, + { + "artikel": "KLEMMRING M. MUFFE DREIFACH 90 Grad/180 Grad KPL.", + "sivas_id": 825002007, + "farbig": false, + "stueckzahl": 1, + "anzahl_vorgabe": 2 + }, + { + "artikel": "KLEMMRING MIT LASCHE KPL. ZUSAMMENBAUZEICHNUNG", + "sivas_id": 825002020, + "farbig": false, + "stueckzahl": 1, + "anzahl_vorgabe": 2 + }, + { + "artikel": "QUERSCHELLE F. 1\" UND 2\" ROHR GESCHW./VZ. M. 4X M10X30 KPL.", + "sivas_id": 825002022, + "farbig": false, + "stueckzahl": 1, + "anzahl_vorgabe": 2 + }, + { + "artikel": "KREUZSCHELLE F. 2\" UND 1\" ROHR SCHWENKBAR 360 Grad", + "sivas_id": 922083009, + "farbig": false, + "stueckzahl": 1, + "anzahl_vorgabe": 2 + } + ], + "sonstiges": [ + { + "artikel": "HALTEARM FÜR BODENSÄULE R 2\" 1-ARMIG KPL.", + "sivas_id": 821004051, + "farbig": true, + "stueckzahl": 1, + "anzahl_vorgabe": 1 + }, + { + "artikel": "HALTEARM FÜR BODENSÄULE R 2\" 2-ARMIG 90 Grad KPL.", + "sivas_id": 821004054, + "farbig": true, + "stueckzahl": 1, + "anzahl_vorgabe": 1 + }, + { + "artikel": "HALTEARM FÜR BODENSÄULE R 2\" 2-ARMIG 180 Grad KPL.", + "sivas_id": 821004052, + "farbig": true, + "stueckzahl": 1, + "anzahl_vorgabe": 1 + }, + { + "artikel": "HALTEARM FÜR BODENSÄULE R 2\" 3-ARMIG KPL.", + "sivas_id": 821004053, + "farbig": true, + "stueckzahl": 1, + "anzahl_vorgabe": 1 + } + ] + }, + "konfigurationen": [] }, "Wandbefestigung": { "id": "Wandbefestigung", @@ -449,61 +375,41 @@ ] } ], - "anbaugruppen": [ - { - "name": "Nylondübel 12x60 inkl. Holzschrauben", - "anzahl_vorgabe": 2, - "teile": [ - { - "artikel": "HOLZSCHRAUB,10X70, 6KT DIN 571 VZ", - "sivas_id": 911271027, - "farbig": false, - "stueckzahl": 1 - }, - { - "artikel": "NYLON - DUEBEL 12X60 (TYP S)", - "sivas_id": 922013003, - "farbig": false, - "stueckzahl": 1 - } - ] - }, - { - "name": "HST M12X115X20", - "anzahl_vorgabe": 2, - "teile": [ - { - "artikel": "DURCHSTECKANKER HST M12X115X20 WANDABH.", - "sivas_id": 922021003, - "farbig": false, - "stueckzahl": 1 - } - ] - } - ], - "konfigurationen": [ - { - "name": "Wandflansch mit Duebeln", - "variante": "WANDFLANSCH EINZELTEIL", - "oben": [ - { - "artikel": "Nylondübel 12x60 inkl. Holzschrauben", - "anzahl": 2 - } - ], - "unten": [] - }, - { - "name": "Winkel 300 mit Schwerlastanker", - "variante": "WINKEL 60X60X6X300", - "oben": [ - { - "artikel": "HST M12X115X20", - "anzahl": 2 - } - ], - "unten": [] - } - ] + "anbaugruppen": { + "befestigung": [ + { + "name": "Nylondübel 12x60 inkl. Holzschrauben", + "anzahl_vorgabe": 2, + "teile": [ + { + "artikel": "HOLZSCHRAUB,10X70, 6KT DIN 571 VZ", + "sivas_id": 911271027, + "farbig": false, + "stueckzahl": 1 + }, + { + "artikel": "NYLON - DUEBEL 12X60 (TYP S)", + "sivas_id": 922013003, + "farbig": false, + "stueckzahl": 1 + } + ] + }, + { + "name": "HST M12X115X20", + "anzahl_vorgabe": 2, + "teile": [ + { + "artikel": "DURCHSTECKANKER HST M12X115X20 WANDABH.", + "sivas_id": 922021003, + "farbig": false, + "stueckzahl": 1 + } + ] + } + ], + "sonstiges": [] + }, + "konfigurationen": [] } } \ No newline at end of file diff --git a/data/json/geruest_traeger.json b/data/json/geruest_traeger.json index 19f0da3..8a6275d 100644 --- a/data/json/geruest_traeger.json +++ b/data/json/geruest_traeger.json @@ -89,6 +89,7 @@ "text": "DRT 80", "layer": "D-1-BEM" }, + "mit_querstrebe": true, "teileart": "Geruest Traeger", "layer": "D-1", "teile": [ @@ -107,6 +108,7 @@ "layer": "D-1-BEM" }, "mit_muffe": true, + "mit_querstrebe": true, "teileart": "Geruest Traeger", "layer": "D-1", "teile": [ @@ -124,6 +126,7 @@ "text": "DRT 114", "layer": "D-3-BEM" }, + "mit_querstrebe": true, "teileart": "Geruest Traeger", "layer": "D-3", "teile": [ @@ -142,6 +145,7 @@ "layer": "D-3-BEM" }, "mit_muffe": true, + "mit_querstrebe": true, "teileart": "Geruest Traeger", "layer": "D-3", "teile": [ @@ -159,6 +163,7 @@ "text": "RT 80/80", "layer": "D-5-BEM" }, + "mit_querstrebe": true, "teileart": "Geruest Traeger", "layer": "D-5", "teile": [ @@ -177,6 +182,7 @@ "layer": "D-5-BEM" }, "mit_muffe": true, + "mit_querstrebe": true, "teileart": "Geruest Traeger", "layer": "D-5", "teile": [ diff --git a/data/json/omniflo_fahrstrecke.json b/data/json/omniflo_fahrstrecke.json new file mode 100644 index 0000000..4cedcbf --- /dev/null +++ b/data/json/omniflo_fahrstrecke.json @@ -0,0 +1,157 @@ +{ + "Fahrstrecke": { + "id": "Fahrstrecke", + "titel": "Fahrstrecke", + "teileart": "Omniflo Fahrstrecke", + "muffe": { + "dummy": "dummy_Muffe_1zoll.dwg" + }, + "beschriftung": { + "format": "%1 L=%2", + "stil": "Lan", + "ausrichtung": "BL", + "hoehe": 100 + }, + "attribute": { + "LAENGE": { + "typ": "number", + "min": 0, + "max": 6000, + "einheit": "mm" + }, + "TEILEFARBE": { + "typ": "auswahl", + "optionen": [ + "RAL7035", + "RAL7030" + ], + "frei_erlaubt": true, + "frei_option": "Individuell" + } + }, + "geometrie_varianten": [ + { + "name": "AP 110", + "beschriftung": { + "text": "AP 110", + "layer": "A-7-BEM" + }, + "teileart": "Omniflo Fahrstrecke", + "layer": "A-7", + "teile": [ + { + "artikel": "AP 110", + "sivas_id": 821106001, + "stueckzahl": 1 + } + ] + }, + { + "name": "APG 110", + "beschriftung": { + "text": "APG 110", + "layer": "A-2-BEM" + }, + "teileart": "Omniflo Fahrstrecke", + "layer": "A-2", + "teile": [ + { + "artikel": "APG 110", + "sivas_id": 821106002, + "stueckzahl": 1 + } + ] + }, + { + "name": "AP 60", + "beschriftung": { + "text": "AP 60", + "layer": "A-4-BEM" + }, + "teileart": "Omniflo Fahrstrecke", + "layer": "A-4", + "teile": [ + { + "artikel": "AP 60", + "sivas_id": 821096001, + "stueckzahl": 1 + } + ] + }, + { + "name": "ST", + "beschriftung": { + "text": "ST", + "layer": "L-2-BEM" + }, + "mit_muffe": false, + "teileart": "Omniflo Fahrstrecke", + "layer": "L-2", + "teile": [ + { + "artikel": "ST", + "sivas_id": 821084000, + "farbig": true, + "stueckzahl": 1 + } + ] + }, + { + "name": "ST mit Muffen", + "disabled": true, + "beschriftung": { + "text": "ST", + "layer": "L-2-BEM" + }, + "mit_muffe": true, + "teileart": "Omniflo Fahrstrecke", + "layer": "L-2", + "teile": [ + { + "artikel": "ST mit Muffen", + "sivas_id": 821084007, + "farbig": true, + "stueckzahl": 1 + } + ] + }, + { + "name": "STL", + "beschriftung": { + "text": "STL", + "layer": "L-2-BEM" + }, + "mit_muffe": false, + "teileart": "Omniflo Fahrstrecke", + "layer": "L-2", + "teile": [ + { + "artikel": "STL", + "sivas_id": 821084050, + "farbig": true, + "stueckzahl": 1 + } + ] + }, + { + "name": "STL mit Muffen", + "disabled": true, + "beschriftung": { + "text": "STL", + "layer": "L-2-BEM" + }, + "mit_muffe": true, + "teileart": "Omniflo Fahrstrecke", + "layer": "L-2", + "teile": [ + { + "artikel": "STL mit Muffen", + "sivas_id": 821084057, + "farbig": true, + "stueckzahl": 1 + } + ] + } + ] + } +} \ No newline at end of file diff --git a/data/json/omniflo_ladeschleifen.json b/data/json/omniflo_ladeschleifen.json new file mode 100644 index 0000000..12128b1 --- /dev/null +++ b/data/json/omniflo_ladeschleifen.json @@ -0,0 +1,10 @@ +[ + { + "Sivasnr": 824331125, + "Beschreibung": "Ladeschleife - 6300, stufenlos ausziehbar, kpl.", + "Laenge": 6300, + "ProfilTyp": "AP 110", + "Stuetzfuß": 0, + "Antriebsart": 0 + } +] diff --git a/data/json/omniflo_weichen.json b/data/json/omniflo_weichen.json index a2be83d..03f2adb 100644 --- a/data/json/omniflo_weichen.json +++ b/data/json/omniflo_weichen.json @@ -1,76 +1,4 @@ [ - { - "Sivasnr": 834372001, - "ProfilTyp": "WEICHE S 45-L-350/700, KPL. MIT M", - "WeichenTyp": "Einzelweiche", - "KurvenWinkel": 45, - "Schaltungstyp": "M", - "Breite": 350, - "Länge": 700, - "KurvenRichtung": 1, - "SivasnrTEF": null, - "WeichenkörperLänge": 360 - }, - { - "Sivasnr": 834372002, - "ProfilTyp": "WEICHE S 45-L-350/700, KPL. MIT P", - "WeichenTyp": "Einzelweiche", - "KurvenWinkel": 45, - "Schaltungstyp": "P", - "Breite": 350, - "Länge": 700, - "KurvenRichtung": 1, - "SivasnrTEF": null, - "WeichenkörperLänge": 360 - }, - { - "Sivasnr": "834372002+0_BG090090", - "ProfilTyp": "WEICHE S 45-L-350/700, KPL. MIT P mit TEF Innen", - "WeichenTyp": "Einzelweiche", - "KurvenWinkel": 45, - "Schaltungstyp": "P", - "Breite": 350, - "Länge": 700, - "KurvenRichtung": 1, - "SivasnrTEF": "0_B10090+0_B10090", - "WeichenkörperLänge": 360 - }, - { - "Sivasnr": 834372004, - "ProfilTyp": "WEICHE S 45-R-350/700, KPL. MIT M", - "WeichenTyp": "Einzelweiche", - "KurvenWinkel": 45, - "Schaltungstyp": "M", - "Breite": 350, - "Länge": 700, - "KurvenRichtung": 2, - "SivasnrTEF": null, - "WeichenkörperLänge": 360 - }, - { - "Sivasnr": 834372005, - "ProfilTyp": "WEICHE S 45-R-350/700, KPL. MIT P", - "WeichenTyp": "Einzelweiche", - "KurvenWinkel": 45, - "Schaltungstyp": "P", - "Breite": 350, - "Länge": 700, - "KurvenRichtung": 2, - "SivasnrTEF": null, - "WeichenkörperLänge": 360 - }, - { - "Sivasnr": "834372005+0_BG090090", - "ProfilTyp": "WEICHE S 45-R-350/700, KPL. MIT P mit TEF Innen", - "WeichenTyp": "Einzelweiche", - "KurvenWinkel": 45, - "Schaltungstyp": "P", - "Breite": 350, - "Länge": 700, - "KurvenRichtung": 2, - "SivasnrTEF": "0_B10090+0_B10090", - "WeichenkörperLänge": 360 - }, { "Sivasnr": 834372007, "ProfilTyp": "WEICHE S 45-L-400/750, KPL. MIT M", @@ -144,53 +72,77 @@ "WeichenkörperLänge": 360 }, { - "Sivasnr": 834372021, - "ProfilTyp": "WEICHE S 90-L-500/600, KPL. MIT M", + "Sivasnr": 834372001, + "ProfilTyp": "WEICHE S 45-L-350/700, KPL. MIT M", "WeichenTyp": "Einzelweiche", - "KurvenWinkel": 90, + "KurvenWinkel": 45, "Schaltungstyp": "M", - "Breite": 500, - "Länge": 600, + "Breite": 350, + "Länge": 700, "KurvenRichtung": 1, "SivasnrTEF": null, "WeichenkörperLänge": 360 }, { - "Sivasnr": 834372022, - "ProfilTyp": "WEICHE S 90-L-500/600, KPL. MIT P", + "Sivasnr": 834372002, + "ProfilTyp": "WEICHE S 45-L-350/700, KPL. MIT P", "WeichenTyp": "Einzelweiche", - "KurvenWinkel": 90, + "KurvenWinkel": 45, "Schaltungstyp": "P", - "Breite": 500, - "Länge": 600, + "Breite": 350, + "Länge": 700, "KurvenRichtung": 1, "SivasnrTEF": null, "WeichenkörperLänge": 360 }, { - "Sivasnr": 834372024, - "ProfilTyp": "WEICHE S 90-R-500/600, KPL. MIT M", + "Sivasnr": "834372002+0_BG090090", + "ProfilTyp": "WEICHE S 45-L-350/700, KPL. MIT P mit TEF Innen", "WeichenTyp": "Einzelweiche", - "KurvenWinkel": 90, + "KurvenWinkel": 45, + "Schaltungstyp": "P", + "Breite": 350, + "Länge": 700, + "KurvenRichtung": 1, + "SivasnrTEF": "0_B10090+0_B10090", + "WeichenkörperLänge": 360 + }, + { + "Sivasnr": 834372004, + "ProfilTyp": "WEICHE S 45-R-350/700, KPL. MIT M", + "WeichenTyp": "Einzelweiche", + "KurvenWinkel": 45, "Schaltungstyp": "M", - "Breite": 500, - "Länge": 600, + "Breite": 350, + "Länge": 700, "KurvenRichtung": 2, "SivasnrTEF": null, "WeichenkörperLänge": 360 }, { - "Sivasnr": 834372025, - "ProfilTyp": "WEICHE S 90-R-500/600, KPL. MIT P", + "Sivasnr": 834372005, + "ProfilTyp": "WEICHE S 45-R-350/700, KPL. MIT P", "WeichenTyp": "Einzelweiche", - "KurvenWinkel": 90, + "KurvenWinkel": 45, "Schaltungstyp": "P", - "Breite": 500, - "Länge": 600, + "Breite": 350, + "Länge": 700, "KurvenRichtung": 2, "SivasnrTEF": null, "WeichenkörperLänge": 360 }, + { + "Sivasnr": "834372005+0_BG090090", + "ProfilTyp": "WEICHE S 45-R-350/700, KPL. MIT P mit TEF Innen", + "WeichenTyp": "Einzelweiche", + "KurvenWinkel": 45, + "Schaltungstyp": "P", + "Breite": 350, + "Länge": 700, + "KurvenRichtung": 2, + "SivasnrTEF": "0_B10090+0_B10090", + "WeichenkörperLänge": 360 + }, { "Sivasnr": 834372027, "ProfilTyp": "WEICHE S 90-L-700/700, KPL. MIT M", @@ -263,6 +215,54 @@ "SivasnrTEF": "0_B10080+0_B10090", "WeichenkörperLänge": 360 }, + { + "Sivasnr": 834372021, + "ProfilTyp": "WEICHE S 90-L-500/600, KPL. MIT M", + "WeichenTyp": "Einzelweiche", + "KurvenWinkel": 90, + "Schaltungstyp": "M", + "Breite": 500, + "Länge": 600, + "KurvenRichtung": 1, + "SivasnrTEF": null, + "WeichenkörperLänge": 360 + }, + { + "Sivasnr": 834372022, + "ProfilTyp": "WEICHE S 90-L-500/600, KPL. MIT P", + "WeichenTyp": "Einzelweiche", + "KurvenWinkel": 90, + "Schaltungstyp": "P", + "Breite": 500, + "Länge": 600, + "KurvenRichtung": 1, + "SivasnrTEF": null, + "WeichenkörperLänge": 360 + }, + { + "Sivasnr": 834372024, + "ProfilTyp": "WEICHE S 90-R-500/600, KPL. MIT M", + "WeichenTyp": "Einzelweiche", + "KurvenWinkel": 90, + "Schaltungstyp": "M", + "Breite": 500, + "Länge": 600, + "KurvenRichtung": 2, + "SivasnrTEF": null, + "WeichenkörperLänge": 360 + }, + { + "Sivasnr": 834372025, + "ProfilTyp": "WEICHE S 90-R-500/600, KPL. MIT P", + "WeichenTyp": "Einzelweiche", + "KurvenWinkel": 90, + "Schaltungstyp": "P", + "Breite": 500, + "Länge": 600, + "KurvenRichtung": 2, + "SivasnrTEF": null, + "WeichenkörperLänge": 360 + }, { "Sivasnr": 834372047, "ProfilTyp": "WEICHE S PARALLEL-L-200/750, KPL. MIT M", @@ -311,61 +311,6 @@ "SivasnrTEF": null, "WeichenkörperLänge": 360 }, - { - "Sivasnr": 834372100, - "ProfilTyp": "WEICHE S D 45-350/700, KPL. MIT M", - "WeichenTyp": "Doppelweiche", - "KurvenWinkel": 45, - "Schaltungstyp": "M", - "Breite": 350, - "Länge": 700, - "KurvenRichtung": 3, - "SivasnrTEF": null - }, - { - "Sivasnr": 834372101, - "ProfilTyp": "WEICHE S D 45-350/700, KPL. MIT P", - "WeichenTyp": "Doppelweiche", - "KurvenWinkel": 45, - "Schaltungstyp": "P", - "Breite": 350, - "Länge": 700, - "KurvenRichtung": 3, - "SivasnrTEF": null - }, - { - "Sivasnr": "0_BG090090+834372101", - "ProfilTyp": "WEICHE S D 45-350/700, KPL. MIT P mit TEF links", - "WeichenTyp": "Doppelweiche", - "KurvenWinkel": 45, - "Schaltungstyp": "P", - "Breite": 350, - "Länge": 700, - "KurvenRichtung": 3, - "SivasnrTEF": "0_B10090+0_B10090" - }, - { - "Sivasnr": "834372101+0_BG090090", - "ProfilTyp": "WEICHE S D 45-350/700, KPL. MIT P mit TEF rechts", - "WeichenTyp": "Doppelweiche", - "KurvenWinkel": 45, - "Schaltungstyp": "P", - "Breite": 350, - "Länge": 700, - "KurvenRichtung": 3, - "SivasnrTEF": "0_B10090+0_B10090" - }, - { - "Sivasnr": "0_BG090090+834372101+0_BG090090", - "ProfilTyp": "WEICHE S D 45-350/700, KPL. MIT P mit TEF beideseitig", - "WeichenTyp": "Doppelweiche", - "KurvenWinkel": 45, - "Schaltungstyp": "P", - "Breite": 350, - "Länge": 700, - "KurvenRichtung": 3, - "SivasnrTEF": "0_B10090+0_B10090+0_B10090+0_B10090" - }, { "Sivasnr": 834372103, "ProfilTyp": "WEICHE S D 45-400/750, KPL. MIT M", @@ -422,27 +367,60 @@ "SivasnrTEF": "0_B10090+0_B10090+0_B10090+0_B10090" }, { - "Sivasnr": 834372106, - "ProfilTyp": "WEICHE S D 90-500/600, KPL. MIT M", + "Sivasnr": 834372100, + "ProfilTyp": "WEICHE S D 45-350/700, KPL. MIT M", "WeichenTyp": "Doppelweiche", - "KurvenWinkel": 90, + "KurvenWinkel": 45, "Schaltungstyp": "M", - "Breite": 500, - "Länge": 600, + "Breite": 350, + "Länge": 700, "KurvenRichtung": 3, "SivasnrTEF": null }, { - "Sivasnr": 834372107, - "ProfilTyp": "WEICHE S D 90-500/600, KPL. MIT P", + "Sivasnr": 834372101, + "ProfilTyp": "WEICHE S D 45-350/700, KPL. MIT P", "WeichenTyp": "Doppelweiche", - "KurvenWinkel": 90, + "KurvenWinkel": 45, "Schaltungstyp": "P", - "Breite": 500, - "Länge": 600, + "Breite": 350, + "Länge": 700, "KurvenRichtung": 3, "SivasnrTEF": null }, + { + "Sivasnr": "0_BG090090+834372101", + "ProfilTyp": "WEICHE S D 45-350/700, KPL. MIT P mit TEF links", + "WeichenTyp": "Doppelweiche", + "KurvenWinkel": 45, + "Schaltungstyp": "P", + "Breite": 350, + "Länge": 700, + "KurvenRichtung": 3, + "SivasnrTEF": "0_B10090+0_B10090" + }, + { + "Sivasnr": "834372101+0_BG090090", + "ProfilTyp": "WEICHE S D 45-350/700, KPL. MIT P mit TEF rechts", + "WeichenTyp": "Doppelweiche", + "KurvenWinkel": 45, + "Schaltungstyp": "P", + "Breite": 350, + "Länge": 700, + "KurvenRichtung": 3, + "SivasnrTEF": "0_B10090+0_B10090" + }, + { + "Sivasnr": "0_BG090090+834372101+0_BG090090", + "ProfilTyp": "WEICHE S D 45-350/700, KPL. MIT P mit TEF beideseitig", + "WeichenTyp": "Doppelweiche", + "KurvenWinkel": 45, + "Schaltungstyp": "P", + "Breite": 350, + "Länge": 700, + "KurvenRichtung": 3, + "SivasnrTEF": "0_B10090+0_B10090+0_B10090+0_B10090" + }, { "Sivasnr": 834372109, "ProfilTyp": "WEICHE S D 90-700/700, KPL. MIT M", @@ -498,6 +476,28 @@ "KurvenRichtung": 3, "SivasnrTEF": "0_B10080+0_B10090+0_B10080+0_B10090" }, + { + "Sivasnr": 834372106, + "ProfilTyp": "WEICHE S D 90-500/600, KPL. MIT M", + "WeichenTyp": "Doppelweiche", + "KurvenWinkel": 90, + "Schaltungstyp": "M", + "Breite": 500, + "Länge": 600, + "KurvenRichtung": 3, + "SivasnrTEF": null + }, + { + "Sivasnr": 834372107, + "ProfilTyp": "WEICHE S D 90-500/600, KPL. MIT P", + "WeichenTyp": "Doppelweiche", + "KurvenWinkel": 90, + "Schaltungstyp": "P", + "Breite": 500, + "Länge": 600, + "KurvenRichtung": 3, + "SivasnrTEF": null + }, { "Sivasnr": 834372115, "ProfilTyp": "WEICHE S D PARALLEL-200/750, KPL. MIT M", @@ -520,61 +520,6 @@ "KurvenRichtung": 3, "SivasnrTEF": null }, - { - "Sivasnr": 834372200, - "ProfilTyp": "WEICHE S T 45-350/700, KPL. MIT M", - "WeichenTyp": "Dreiwegeweiche", - "KurvenWinkel": 45, - "Schaltungstyp": "M", - "Breite": 350, - "Länge": 700, - "KurvenRichtung": 7, - "SivasnrTEF": null - }, - { - "Sivasnr": 834372201, - "ProfilTyp": "WEICHE S T 45-350/700, KPL. MIT P", - "WeichenTyp": "Dreiwegeweiche", - "KurvenWinkel": 45, - "Schaltungstyp": "P", - "Breite": 350, - "Länge": 700, - "KurvenRichtung": 7, - "SivasnrTEF": null - }, - { - "Sivasnr": "0_BG090090+834372201", - "ProfilTyp": "WEICHE S T 45-350/700, KPL. MIT P mit TEF links", - "WeichenTyp": "Dreiwegeweiche", - "KurvenWinkel": 45, - "Schaltungstyp": "P", - "Breite": 350, - "Länge": 700, - "KurvenRichtung": 7, - "SivasnrTEF": "0_B10090+0_B10090" - }, - { - "Sivasnr": "834372201+0_BG090090", - "ProfilTyp": "WEICHE S T 45-350/700, KPL. MIT P mit TEF rechts", - "WeichenTyp": "Dreiwegeweiche", - "KurvenWinkel": 45, - "Schaltungstyp": "P", - "Breite": 350, - "Länge": 700, - "KurvenRichtung": 7, - "SivasnrTEF": "0_B10090+0_B10090" - }, - { - "Sivasnr": "0_BG090090+834372201+0_BG090090", - "ProfilTyp": "WEICHE S T 45-350/700, KPL. MIT P mit TEF beideseitig", - "WeichenTyp": "Dreiwegeweiche", - "KurvenWinkel": 45, - "Schaltungstyp": "P", - "Breite": 350, - "Länge": 700, - "KurvenRichtung": 7, - "SivasnrTEF": "0_B10090+0_B10090+0_B10090+0_B10090" - }, { "Sivasnr": 834372203, "ProfilTyp": "WEICHE S T 45-400/750, KPL. MIT M", @@ -631,27 +576,60 @@ "SivasnrTEF": "0_B10090+0_B10090+0_B10090+0_B10090" }, { - "Sivasnr": 834372206, - "ProfilTyp": "WEICHE S T 90-500/600, KPL. MIT M", + "Sivasnr": 834372200, + "ProfilTyp": "WEICHE S T 45-350/700, KPL. MIT M", "WeichenTyp": "Dreiwegeweiche", - "KurvenWinkel": 90, + "KurvenWinkel": 45, "Schaltungstyp": "M", - "Breite": 500, - "Länge": 600, + "Breite": 350, + "Länge": 700, "KurvenRichtung": 7, "SivasnrTEF": null }, { - "Sivasnr": 834372207, - "ProfilTyp": "WEICHE S T 90-500/600, KPL. MIT P", + "Sivasnr": 834372201, + "ProfilTyp": "WEICHE S T 45-350/700, KPL. MIT P", "WeichenTyp": "Dreiwegeweiche", - "KurvenWinkel": 90, + "KurvenWinkel": 45, "Schaltungstyp": "P", - "Breite": 500, - "Länge": 600, + "Breite": 350, + "Länge": 700, "KurvenRichtung": 7, "SivasnrTEF": null }, + { + "Sivasnr": "0_BG090090+834372201", + "ProfilTyp": "WEICHE S T 45-350/700, KPL. MIT P mit TEF links", + "WeichenTyp": "Dreiwegeweiche", + "KurvenWinkel": 45, + "Schaltungstyp": "P", + "Breite": 350, + "Länge": 700, + "KurvenRichtung": 7, + "SivasnrTEF": "0_B10090+0_B10090" + }, + { + "Sivasnr": "834372201+0_BG090090", + "ProfilTyp": "WEICHE S T 45-350/700, KPL. MIT P mit TEF rechts", + "WeichenTyp": "Dreiwegeweiche", + "KurvenWinkel": 45, + "Schaltungstyp": "P", + "Breite": 350, + "Länge": 700, + "KurvenRichtung": 7, + "SivasnrTEF": "0_B10090+0_B10090" + }, + { + "Sivasnr": "0_BG090090+834372201+0_BG090090", + "ProfilTyp": "WEICHE S T 45-350/700, KPL. MIT P mit TEF beideseitig", + "WeichenTyp": "Dreiwegeweiche", + "KurvenWinkel": 45, + "Schaltungstyp": "P", + "Breite": 350, + "Länge": 700, + "KurvenRichtung": 7, + "SivasnrTEF": "0_B10090+0_B10090+0_B10090+0_B10090" + }, { "Sivasnr": 834372209, "ProfilTyp": "WEICHE S T 90-700/700, KPL. MIT M", @@ -707,6 +685,28 @@ "KurvenRichtung": 7, "SivasnrTEF": "0_B10080+0_B10090+0_B10080+0_B10090" }, + { + "Sivasnr": 834372206, + "ProfilTyp": "WEICHE S T 90-500/600, KPL. MIT M", + "WeichenTyp": "Dreiwegeweiche", + "KurvenWinkel": 90, + "Schaltungstyp": "M", + "Breite": 500, + "Länge": 600, + "KurvenRichtung": 7, + "SivasnrTEF": null + }, + { + "Sivasnr": 834372207, + "ProfilTyp": "WEICHE S T 90-500/600, KPL. MIT P", + "WeichenTyp": "Dreiwegeweiche", + "KurvenWinkel": 90, + "Schaltungstyp": "P", + "Breite": 500, + "Länge": 600, + "KurvenRichtung": 7, + "SivasnrTEF": null + }, { "Sivasnr": 834372215, "ProfilTyp": "WEICHE S T PARALLEL-200/750, KPL. MIT M", @@ -729,30 +729,6 @@ "KurvenRichtung": 7, "SivasnrTEF": null }, - { - "Sivasnr": 834372400, - "ProfilTyp": "WEICHE S C DELTA 1400/700, KPL. M", - "WeichenTyp": "Deltaweiche", - "KurvenWinkel": 90, - "Schaltungstyp": "M", - "Breite": 1400, - "Länge": 700, - "KurvenRichtung": 3, - "SivasnrTEF": null, - "WeichenkörperLänge": 1400.4619 - }, - { - "Sivasnr": 834372401, - "ProfilTyp": "WEICHE S C DELTA 1400/700, KPL. P", - "WeichenTyp": "Deltaweiche", - "KurvenWinkel": 90, - "Schaltungstyp": "P", - "Breite": 1400, - "Länge": 700, - "KurvenRichtung": 7, - "SivasnrTEF": null, - "WeichenkörperLänge": 1400.4619 - }, { "Sivasnr": 834372403, "ProfilTyp": "WEICHE S C DELTA 1600/800, KPL. M", @@ -812,6 +788,30 @@ "KurvenRichtung": 3, "SivasnrTEF": "0_B10090+0_B10090+0_B10071", "WeichenkörperLänge": 1600.3844 + }, + { + "Sivasnr": 834372400, + "ProfilTyp": "WEICHE S C DELTA 1400/700, KPL. M", + "WeichenTyp": "Deltaweiche", + "KurvenWinkel": 90, + "Schaltungstyp": "M", + "Breite": 1400, + "Länge": 700, + "KurvenRichtung": 3, + "SivasnrTEF": null, + "WeichenkörperLänge": 1400.4619 + }, + { + "Sivasnr": 834372401, + "ProfilTyp": "WEICHE S C DELTA 1400/700, KPL. P", + "WeichenTyp": "Deltaweiche", + "KurvenWinkel": 90, + "Schaltungstyp": "P", + "Breite": 1400, + "Länge": 700, + "KurvenRichtung": 7, + "SivasnrTEF": null, + "WeichenkörperLänge": 1400.4619 }, { "Sivasnr": 834372420, @@ -927,4 +927,4 @@ "KurvenRichtung": 7, "SivasnrTEF": null } -] +] \ No newline at end of file diff --git a/data/omniflo/2D/824604001.dwg b/data/omniflo/2D/824604001.dwg index 5b691cb..3113bfd 100644 Binary files a/data/omniflo/2D/824604001.dwg and b/data/omniflo/2D/824604001.dwg differ diff --git a/data/omniflo/2D/824604002.dwg b/data/omniflo/2D/824604002.dwg new file mode 100644 index 0000000..258db6f Binary files /dev/null and b/data/omniflo/2D/824604002.dwg differ diff --git a/data/omniflo/2D/824604011.dwg b/data/omniflo/2D/824604011.dwg new file mode 100644 index 0000000..03c515f Binary files /dev/null and b/data/omniflo/2D/824604011.dwg differ diff --git a/data/omniflo/2D/824604012.dwg b/data/omniflo/2D/824604012.dwg new file mode 100644 index 0000000..c6258c4 Binary files /dev/null and b/data/omniflo/2D/824604012.dwg differ diff --git a/dcl/fahrstrecke.dcl b/dcl/fahrstrecke.dcl new file mode 100644 index 0000000..84b8006 --- /dev/null +++ b/dcl/fahrstrecke.dcl @@ -0,0 +1,56 @@ +// ============================================================ +// fahrstrecke.dcl - Omniflo-Fahrstrecke konfigurieren (VORLAGE) +// Verwendet von: OMNI_FAHRSTRECKE (GeruestInsert.lsp, geruest-traeger-dialog) +// Daten: data/json/omniflo_fahrstrecke.json +// +// Gleicher Aufbau wie geruest_traeger.dcl - dieselben Tile-Keys, denn beide +// Dialoge laufen ueber dieselben Funktionen (geruest-traeger-dialog). +// +// Diese Datei wird NICHT direkt geladen: //@VARIANTEN@ ist ein Platzhalter, +// den GeruestInsert.lsp zur Laufzeit durch einen radio_button je +// Variante (key v, i = Index in geometrie_varianten) ersetzt +// (ssg-dcl-vorlage-fuellen, ssg_core.lsp). Das Ergebnis wird als Temp-Datei +// geladen. +// +// Jede Variante (auch die mit Muffe) hat einen eigenen Radiobutton, damit +// ihre Artikelnummer sichtbar ist. +// +// Die Laenge steht bewusst NICHT im Dialog - sie wird nach dem Dialog in der +// Zeichnung per Start-/Endpunkt (oder getippter Laenge) bestimmt. +// ============================================================ + +fahrstrecke : dialog { + label = "Fahrstrecke konfigurieren"; + + : boxed_column { + label = "Basis"; + : radio_column { + key = "variante"; + label = "Variante:"; + alignment = left; + //@VARIANTEN@ + } + : row { + : popup_list { key = "farbe"; label = "Farbe:"; width = 25; } + : edit_box { key = "farbe_frei"; label = "eigene:"; edit_width = 12; } + } + } + + : boxed_column { + label = "Längenabzug"; + : row { + : toggle { key = "abzug_a"; label = "Längenabzug Anfang"; width = 24; fixed_width = true; } + : edit_box { key = "abzug_a_w"; label = "mm:"; edit_width = 8; fixed_width = true; } + } + : row { + : toggle { key = "abzug_e"; label = "Längenabzug Ende"; width = 24; fixed_width = true; } + : edit_box { key = "abzug_e_w"; label = "mm:"; edit_width = 8; fixed_width = true; } + } + } + + : toggle { key = "beschriftung"; label = "Beschriftung einfügen"; } + + : text { key = "hinweis"; label = ""; width = 56; } + + ok_cancel; +} diff --git a/dcl/geruest.dcl b/dcl/geruest.dcl new file mode 100644 index 0000000..70034df --- /dev/null +++ b/dcl/geruest.dcl @@ -0,0 +1,55 @@ +// ============================================================ +// geruest.dcl - Geruest-Baugruppe konfigurieren (VORLAGE) +// Verwendet von: GERUEST_SAEULEN, GERUEST_ROHRABHAENGER, +// GERUEST_WANDBEFESTIGUNG (GeruestInsert.lsp, geruest-dialog) +// +// Diese Datei wird NICHT direkt geladen: Zeilen der Form //@NAME@ sind +// Platzhalter, die GeruestInsert.lsp zur Laufzeit durch datenabhaengige +// Bloecke ersetzt (ssg-dcl-vorlage-fuellen, ssg_core.lsp) - DCL kann Tiles +// weder zur Laufzeit erzeugen noch ausblenden, und Radiobutton-Labels lassen +// sich per set_tile nicht aendern. Das Ergebnis wird als Temp-Datei geladen. +// +// //@TITEL@ label-Zeile des Dialogs (Bereichsname) +// //@VARIANTEN@ ein radio_button je Geometrie-Variante (key v) +// //@BEFESTIGUNG@ Spalte "Befestigung oben und unten" (Tile-Keys b/bm, +// entfaellt ohne Teile - ein leerer Cluster ist in DCL +// unzulaessig) +// //@SONSTIGES@ Spalte "Sonstiges" (s/sm, entfaellt ohne Teile) +// Je Teil: Mengenfeld, Ankreuzfeld und darunter "Art.-Nr. ..." (sivas_id). +// ============================================================ + +geruest : dialog { + //@TITEL@ + : row { + : popup_list { key = "konfig"; label = "Konfiguration:"; width = 40; } + : button { key = "kspeichern"; label = "Speichern..."; fixed_width = true; } + : button { key = "kloeschen"; label = "Löschen"; fixed_width = true; } + } + // Zeigt an, ob der Stand noch der gewaehlten Konfiguration entspricht + // (geruest-dlg-aenderung-pruefen). + : text { key = "kstatus"; label = ""; width = 64; } + + : boxed_column { + label = "Basis"; + // Radiobuttons statt Liste: alle Varianten sichtbar, Einfachauswahl, + // Beschriftung in voller Breite. + : radio_column { + key = "variante"; + label = "Variante:"; + alignment = left; + //@VARIANTEN@ + } + : row { + : edit_box { key = "laenge"; label = "Laenge (mm):"; edit_width = 10; } + : popup_list { key = "farbe"; label = "Farbe:"; width = 25; } + : edit_box { key = "farbe_frei"; label = "eigene:"; edit_width = 12; } + } + // Ausrichtung, in der die Anbauteile mit der Basis zusammengebaut werden + : popup_list { key = "winkel"; label = "Winkel Platte:"; width = 22; fixed_width = true; } + } + + //@BEFESTIGUNG@ + //@SONSTIGES@ + + ok_cancel; +} diff --git a/dcl/geruest_traeger.dcl b/dcl/geruest_traeger.dcl index c33cfe1..e12ce11 100644 --- a/dcl/geruest_traeger.dcl +++ b/dcl/geruest_traeger.dcl @@ -1,18 +1,32 @@ // ============================================================ -// geruest_traeger.dcl - Rohr-Geruest-Traeger konfigurieren +// geruest_traeger.dcl - Rohr-Geruest-Traeger konfigurieren (VORLAGE) // Verwendet von: GERUEST_TRAEGER (GeruestInsert.lsp, geruest-traeger-dialog) // +// Diese Datei wird NICHT direkt geladen: //@VARIANTEN@ ist ein Platzhalter, +// den GeruestInsert.lsp zur Laufzeit durch einen radio_button je +// Variante (key v, i = Index in geometrie_varianten) ersetzt +// (ssg-dcl-vorlage-fuellen, ssg_core.lsp) - Radiobutton-Labels lassen sich +// per set_tile nicht aendern. Das Ergebnis wird als Temp-Datei geladen. +// +// Jede Variante (auch die mit Muffe) hat einen eigenen Radiobutton, damit +// ihre Artikelnummer sichtbar ist. +// // Die Laenge steht bewusst NICHT im Dialog - sie wird nach dem Dialog in der // Zeichnung per Start-/Endpunkt (oder getippter Laenge) bestimmt. Aktive // Laengenabzuege ruecken die Linie am Anfang bzw. Ende ein. // ============================================================ geruest_traeger : dialog { - label = "Rohr-Geruest-Traeger konfigurieren"; + label = "Rohr-Gerüst-Träger konfigurieren"; : boxed_column { label = "Basis"; - : popup_list { key = "variante"; label = "Variante:"; width = 56; } + : radio_column { + key = "variante"; + label = "Variante:"; + alignment = left; + //@VARIANTEN@ + } : row { : popup_list { key = "farbe"; label = "Farbe:"; width = 25; } : edit_box { key = "farbe_frei"; label = "eigene:"; edit_width = 12; } @@ -20,18 +34,18 @@ geruest_traeger : dialog { } : boxed_column { - label = "Laengenabzug"; + label = "Längenabzug"; : row { - : toggle { key = "abzug_a"; label = "Laengenabzug Anfang"; width = 24; fixed_width = true; } + : toggle { key = "abzug_a"; label = "Längenabzug Anfang"; width = 24; fixed_width = true; } : edit_box { key = "abzug_a_w"; label = "mm:"; edit_width = 8; fixed_width = true; } } : row { - : toggle { key = "abzug_e"; label = "Laengenabzug Ende"; width = 24; fixed_width = true; } + : toggle { key = "abzug_e"; label = "Längenabzug Ende"; width = 24; fixed_width = true; } : edit_box { key = "abzug_e_w"; label = "mm:"; edit_width = 8; fixed_width = true; } } } - : toggle { key = "beschriftung"; label = "Beschriftung einfuegen"; } + : toggle { key = "beschriftung"; label = "Beschriftung einfügen"; } : text { key = "hinweis"; label = ""; width = 56; } diff --git a/lang/de_DE.json b/lang/de_DE.json index c58221b..948709b 100644 --- a/lang/de_DE.json +++ b/lang/de_DE.json @@ -973,6 +973,7 @@ "gr-fehler-json-lesbar": "\nGeruest: Datendatei nicht lesbar: %1", "gr-fehler-baugruppe": "\nGeruest: Baugruppe '%1' steht nicht in der Datendatei.", "gr-fehler-keine-varianten": "\nGeruest: Baugruppe '%1' hat keine Geometrie-Varianten.", + "gr-bereich-waehlen": "\nGeruest: bitte einen Bereich ueber das Menue waehlen (GERUEST_SAEULEN, GERUEST_ROHRABHAENGER, GERUEST_WANDBEFESTIGUNG).", "gr-fehler-dummy": "\nGeruest: Dummy-Baugruppe nicht gefunden: %1", "gr-fehler-dummy-variante": "\nGeruest: Dummy der Variante nicht gefunden: %1 - verwende Dummy der Baugruppe (%2)", "gr-fehler-dcl": "Dialog geruest.dcl konnte nicht geladen werden.", @@ -982,10 +983,15 @@ "gr-abgebrochen": "\nAbgebrochen.", "gr-fertig": "\nGeruest-Baugruppe '%1' eingefuegt (Block %2).", "gr-alert-menge": "Ungueltige Anzahl. Erlaubt ist eine ganze Zahl ab 1; ein leeres Feld uebernimmt den Vorgabewert.", - "gr-position-oben": "oben", - "gr-position-unten": "unten", + "gr-position-befestigung": "Befestigung", + "gr-position-sonstiges": "sonstiges", "gr-konfig-keine": "", "gr-konfig-name": "\nName der Konfiguration: ", + "gr-konfig-name-vorgabe": "\nName der Konfiguration <%1>: ", + "gr-konfig-geaendert": "%1 (geaendert)", + "gr-konfig-status-geaendert": "Geaendert gegenueber '%1' - Speichern (Enter beim Namen) ueberschreibt sie.", + "gr-konfig-status-bibliothek": "Geaendert gegenueber '%1' (Bibliothek, schreibgeschuetzt) - zum Speichern einen neuen Namen vergeben.", + "gr-winkel-grad": "%1%2", "gr-konfig-gespeichert": "\nKonfiguration '%1' gespeichert.", "gr-konfig-geloescht": "\nKonfiguration '%1' geloescht.", "gr-konfig-loeschen-frage": "\nKonfiguration '%1' wirklich loeschen? [Ja/Nein] : ", @@ -993,25 +999,26 @@ "gr-konfig-bibliothek-fest": "\nKonfigurationen der Bibliothek koennen nicht geloescht werden - nur eigene (mit * markiert).", "gr-konfig-teil-unbekannt": "\nGeruest: Anbauteil '%1' aus Konfiguration '%2' ist bei dieser Baugruppe unbekannt - uebersprungen.", "gr-konfig-variante-unbekannt": "\nGeruest: Variante '%1' aus Konfiguration '%2' ist bei dieser Baugruppe unbekannt - Auswahl unveraendert.", + "gr-konfig-variante-gesperrt": "\nKonfiguration '%2': Variante '%1' ist gesperrt - Auswahl bleibt unveraendert.", "gr-fehler-schreiben": "\nGeruest: Datei konnte nicht geschrieben werden: %1", "gr-fehler-keine-baugruppen": "\nGeruest: Die Datendatei enthaelt keine Baugruppen.", "gr-tr-fehler-dcl": "Dialog %1 konnte nicht geladen werden.", "gr-tr-hinweis": "Die Laenge wird nach OK in der Zeichnung bestimmt.", "gr-tr-alert-abzug": "Laengenabzug ungueltig. Erlaubt ist eine Zahl ab 0 (mm); ein leeres Feld gilt als 0.", - "gr-tr-prompt-start": "\nStartpunkt des Traegers waehlen : ", + "gr-tr-prompt-start": "\nStartpunkt (%1) waehlen : ", "gr-tr-prompt-ende": "\nEndpunkt waehlen oder Laenge (mm) eingeben: ", "gr-tr-prompt-richtung": "\nRichtung angeben <0>: ", "gr-tr-eingabe-ungueltig": "\nEingabe '%1' ist weder Punkt noch Laenge.", - "gr-tr-laenge-null": "\nStrecke %1 mm ist nicht laenger als die Abzuege (%2 mm) - kein Traeger eingefuegt.", - "gr-tr-laenge-bereich": "\nTraegerlaenge %1 mm ausserhalb des erlaubten Bereichs %2 bis %3 mm - kein Traeger eingefuegt.", - "gr-tr-fertig": "\nTraeger %1 mm eingefuegt (Block %2).", - "gr-tr-ende": "\n%1 Traeger eingefuegt.", + "gr-tr-laenge-null": "\nStrecke %1 mm ist nicht laenger als die Abzuege (%2 mm) - nichts eingefuegt (%3).", + "gr-tr-laenge-bereich": "\n%4: Laenge %1 mm ausserhalb des erlaubten Bereichs %2 bis %3 mm - nichts eingefuegt.", + "gr-tr-fertig": "\n%3 %1 mm eingefuegt (Block %2).", + "gr-tr-ende": "\n%1x %2 eingefuegt.", "gr-tr-bez-abzug-anfang": "Abzug Anfang %1 mm", "gr-tr-bez-abzug-ende": "Abzug Ende %1 mm", "gr-tr-beschr-stil-fehlt": "\nTextstil %1 fehlt in der Zeichnung - Beschriftung mit aktuellem Stil %2.", "gr-tr-beschr-ausrichtung": "\nUnbekannte Ausrichtung %1 fuer die Traeger-Beschriftung - verwende BC.", - "gr-tr-beschr-ergebnis": "\n%1 Traeger beschriftet (davon %2 ohne bekannte Variante), %3 nicht beschriftbar, %4 verwaiste Beschriftungen entfernt.", - "gr-tr-beschr-keine": "\nKeine Rohr-Geruest-Traeger in der Zeichnung.", + "gr-tr-beschr-ergebnis": "\n%5: %1 beschriftet (davon %2 ohne bekannte Variante), %3 nicht beschriftbar, %4 verwaiste Beschriftungen entfernt.", + "gr-tr-beschr-keine": "\nKeine Bloecke vom Typ %1 in der Zeichnung.", "gr-tr-strebe-rand": "Traeger %1 mm: Der Randabstand der Querstreben betraegt %2 mm und liegt ausserhalb des erlaubten Bereichs %3 bis %4 mm (Strebenabstand %5 mm, %6 Streben). Der Traeger wird trotzdem eingefuegt.", "in-yesno-keys": "Ja Nein", "in-keys-bereich": "Alle Auswahl", @@ -1092,6 +1099,7 @@ "sl-erk-kreisel": "ILS Kreisel/Eckrad", "sl-erk-strecke": "ILS Streckengruppe (VarioFoerderer/Gefaellestrecke)", "sl-erk-geruest": "Rohrgeruest", + "sl-erk-fahrstrecke": "Omniflo Fahrstrecke", "sl-erk-ap60": "Omniflo Gerade AP60", "sl-erk-ap110": "Omniflo Gerade AP110", "sl-erk-apg110": "Omniflo Gerade APG110" diff --git a/lang/en_GB.json b/lang/en_GB.json index 3a8395b..ce4950c 100644 --- a/lang/en_GB.json +++ b/lang/en_GB.json @@ -973,6 +973,7 @@ "gr-fehler-json-lesbar": "\nScaffold: data file not readable: %1", "gr-fehler-baugruppe": "\nScaffold: assembly '%1' is not in the data file.", "gr-fehler-keine-varianten": "\nScaffold: assembly '%1' has no geometry variants.", + "gr-bereich-waehlen": "\nScaffold: please choose an area from the menu (GERUEST_SAEULEN, GERUEST_ROHRABHAENGER, GERUEST_WANDBEFESTIGUNG).", "gr-fehler-dummy": "\nScaffold: dummy assembly not found: %1", "gr-fehler-dummy-variante": "\nScaffold: dummy of the variant not found: %1 - using dummy of the assembly (%2)", "gr-fehler-dcl": "Dialog geruest.dcl could not be loaded.", @@ -982,10 +983,15 @@ "gr-abgebrochen": "\nCancelled.", "gr-fertig": "\nScaffold assembly '%1' inserted (block %2).", "gr-alert-menge": "Invalid quantity. Enter a whole number of 1 or more; an empty field uses the default.", - "gr-position-oben": "top", - "gr-position-unten": "bottom", + "gr-position-befestigung": "mounting", + "gr-position-sonstiges": "other", "gr-konfig-keine": "", "gr-konfig-name": "\nConfiguration name: ", + "gr-konfig-name-vorgabe": "\nConfiguration name <%1>: ", + "gr-konfig-geaendert": "%1 (modified)", + "gr-konfig-status-geaendert": "Modified compared to '%1' - Save (Enter at the name prompt) overwrites it.", + "gr-konfig-status-bibliothek": "Modified compared to '%1' (library, read-only) - enter a new name to save.", + "gr-winkel-grad": "%1%2", "gr-konfig-gespeichert": "\nConfiguration '%1' saved.", "gr-konfig-geloescht": "\nConfiguration '%1' deleted.", "gr-konfig-loeschen-frage": "\nReally delete configuration '%1'? [Ja/Nein] : ", @@ -993,25 +999,26 @@ "gr-konfig-bibliothek-fest": "\nLibrary configurations cannot be deleted - only your own (marked with *).", "gr-konfig-teil-unbekannt": "\nScaffold: add-on part '%1' from configuration '%2' is unknown for this assembly - skipped.", "gr-konfig-variante-unbekannt": "\nScaffold: variant '%1' from configuration '%2' is unknown for this assembly - selection unchanged.", + "gr-konfig-variante-gesperrt": "\nConfiguration '%2': variant '%1' is disabled - selection left unchanged.", "gr-fehler-schreiben": "\nScaffold: could not write file: %1", "gr-fehler-keine-baugruppen": "\nScaffold: the data file contains no assemblies.", "gr-tr-fehler-dcl": "Dialog %1 could not be loaded.", "gr-tr-hinweis": "The length is defined in the drawing after OK.", "gr-tr-alert-abzug": "Invalid length deduction. Allowed is a number from 0 (mm); an empty field counts as 0.", - "gr-tr-prompt-start": "\nSelect start point of the beam : ", + "gr-tr-prompt-start": "\nSelect start point (%1) : ", "gr-tr-prompt-ende": "\nSelect end point or enter length (mm): ", "gr-tr-prompt-richtung": "\nSpecify direction <0>: ", "gr-tr-eingabe-ungueltig": "\nInput '%1' is neither a point nor a length.", - "gr-tr-laenge-null": "\nDistance %1 mm is not longer than the deductions (%2 mm) - no beam inserted.", - "gr-tr-laenge-bereich": "\nBeam length %1 mm outside the allowed range %2 to %3 mm - no beam inserted.", - "gr-tr-fertig": "\nBeam %1 mm inserted (block %2).", - "gr-tr-ende": "\n%1 beam(s) inserted.", + "gr-tr-laenge-null": "\nDistance %1 mm is not longer than the deductions (%2 mm) - nothing inserted (%3).", + "gr-tr-laenge-bereich": "\n%4: length %1 mm outside the allowed range %2 to %3 mm - nothing inserted.", + "gr-tr-fertig": "\n%3 %1 mm inserted (block %2).", + "gr-tr-ende": "\n%1x %2 inserted.", "gr-tr-bez-abzug-anfang": "Deduction start %1 mm", "gr-tr-bez-abzug-ende": "Deduction end %1 mm", "gr-tr-beschr-stil-fehlt": "\nText style %1 missing in drawing - labelling with current style %2.", "gr-tr-beschr-ausrichtung": "\nUnknown justification %1 for beam label - using BC.", - "gr-tr-beschr-ergebnis": "\n%1 beam(s) labelled (%2 without known variant), %3 not labellable, %4 orphaned label(s) removed.", - "gr-tr-beschr-keine": "\nNo pipe scaffold beams in the drawing.", + "gr-tr-beschr-ergebnis": "\n%5: %1 labelled (%2 without known variant), %3 not labellable, %4 orphaned label(s) removed.", + "gr-tr-beschr-keine": "\nNo blocks of type %1 in the drawing.", "gr-tr-strebe-rand": "Beam %1 mm: the edge distance of the cross braces is %2 mm, outside the allowed range %3 to %4 mm (brace spacing %5 mm, %6 braces). The beam is inserted anyway.", "in-yesno-keys": "Yes No", "in-keys-bereich": "All Selection", @@ -1092,6 +1099,7 @@ "sl-erk-kreisel": "ILS roundabout/corner wheel", "sl-erk-strecke": "ILS conveyor section (VarioFoerderer/gravity conveyor)", "sl-erk-geruest": "Pipe scaffold", + "sl-erk-fahrstrecke": "Omniflo track", "sl-erk-ap60": "Omniflo straight AP60", "sl-erk-ap110": "Omniflo straight AP110", "sl-erk-apg110": "Omniflo straight APG110" diff --git a/menu/SSG_LIB.cui b/menu/SSG_LIB.cui index d4708bf..745d3c3 100644 --- a/menu/SSG_LIB.cui +++ b/menu/SSG_LIB.cui @@ -152,721 +152,757 @@ ^C^C(ssg-ensure "VarioFoerderer") QcLinieMitGfUForm + + + Fahrstrecke + ^C^C(ssg-ensure "GeruestInsert") OMNI_FAHRSTRECKE + + + + Fahrstrecken beschriften + ^C^C(ssg-ensure "GeruestInsert") OMNI_FAHRSTRECKE_BESCHRIFTEN + + + 90 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APB_630_90 - + 67.5 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APB_550_675 - + 45 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APB_630_45 - + 22.5 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APB_550_225 - + 180 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APB_650_180 - + 90 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APB60_90 - + AP 60 ^C^C(ssg-ensure "OmniModulInsert") OMNI_AP60 - + AP 110 ^C^C(ssg-ensure "OmniModulInsert") OMNI_AP110 - + APG 110 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APG110 - + - Einfach 90 700/700 links M + Einfach 90 ^C^C(ssg-ensure "OmniModulInsert") OMNI_W90_Einfach - - - Doppel 90 700/700 M - ^C^C(ssg-ensure "OmniModulInsert") OMNI_W90_Doppel - - - - - Dreiwege 90 700/700 M - ^C^C(ssg-ensure "OmniModulInsert") OMNI_W90_Dreiwege - - - Einfach 45 350/700 links M - ^C^C(ssg-ensure "OmniModulInsert") OMNI_W45_Einfach + Doppel 90 + ^C^C(ssg-ensure "OmniModulInsert") OMNI_W90_Doppel - Doppel 45 350/700 M - ^C^C(ssg-ensure "OmniModulInsert") OMNI_W45_Doppel + Dreiwege 90 + ^C^C(ssg-ensure "OmniModulInsert") OMNI_W90_Dreiwege - + - Dreiwege 45 350/700 M - ^C^C(ssg-ensure "OmniModulInsert") OMNI_W45_Dreiwege + Einfach 45 + ^C^C(ssg-ensure "OmniModulInsert") OMNI_W45_Einfach - Einfach Parallel 200/750 links M - ^C^C(ssg-ensure "OmniModulInsert") OMNI_WP_Einfach + Doppel 45 + ^C^C(ssg-ensure "OmniModulInsert") OMNI_W45_Doppel - Doppel Parallel 200/750 M - ^C^C(ssg-ensure "OmniModulInsert") OMNI_WP_Doppel + Dreiwege 45 + ^C^C(ssg-ensure "OmniModulInsert") OMNI_W45_Dreiwege - + - Dreiwege Parallel 200/750 M - ^C^C(ssg-ensure "OmniModulInsert") OMNI_WP_Dreiwege + Einfach Parallel + ^C^C(ssg-ensure "OmniModulInsert") OMNI_WP_Einfach - Einfach 22.5 links M - ^C^C(ssg-ensure "OmniModulInsert") OMNI_WK_Einfach + Doppel Parallel + ^C^C(ssg-ensure "OmniModulInsert") OMNI_WP_Doppel - Doppel 22.5 M - ^C^C(ssg-ensure "OmniModulInsert") OMNI_WK_Doppel + Dreiwege Parallel + ^C^C(ssg-ensure "OmniModulInsert") OMNI_WP_Dreiwege - + - Dreiwege 22.5 M - ^C^C(ssg-ensure "OmniModulInsert") OMNI_WK_Dreiwege + Einfach 22.5 + ^C^C(ssg-ensure "OmniModulInsert") OMNI_WK_Einfach - Delta 1400/700 M - ^C^C(ssg-ensure "OmniModulInsert") OMNI_WKomb_Delta_1400 + Doppel 22.5 + ^C^C(ssg-ensure "OmniModulInsert") OMNI_WK_Doppel - Delta 1600/800 M + Dreiwege 22.5 + ^C^C(ssg-ensure "OmniModulInsert") OMNI_WK_Dreiwege + + + + + Delta 1600/800 ^C^C(ssg-ensure "OmniModulInsert") OMNI_WKomb_Delta_1600 - + - Star 1400/1400 M + Delta 1400/700 + ^C^C(ssg-ensure "OmniModulInsert") OMNI_WKomb_Delta_1400 + + + + + Star 1400/1400 ^C^C(ssg-ensure "OmniModulInsert") OMNI_WKomb_Star - + TEF Antriebst. rechts ^C^C(ssg-ensure "OmniModulInsert") OMNI_TEF_AntriebR - + TEF Umlenkspannst. rechts ^C^C(ssg-ensure "OmniModulInsert") OMNI_TEF_UmlenkR - + TEF Antriebst. links ^C^C(ssg-ensure "OmniModulInsert") OMNI_TEF_AntriebL - + TEF Umlenkspannst. links ^C^C(ssg-ensure "OmniModulInsert") OMNI_TEF_UmlenkL - + TEF Gerade auf Linie ^C^C(ssg-ensure "TEFInsert") TEF_FOERDERER_LINIE - + TEF Gerade ^C^C(ssg-ensure "OmniModulInsert") OMNI_TEF_Gerade - + Stopper AP ^C^C(ssg-ensure "OmniModulInsert") OMNI_STOPPER - + Scanner ^C^C(ssg-ensure "OmniModulInsert") OMNI_SCANNER - + Bürstenbremse ^C^C(ssg-ensure "OmniModulInsert") OMNI_BUERSTENBREMSE - + + + Schwenkschiene Schiebetür L + ^C^C(ssg-ensure "OmniModulInsert") OMNI_SCHW_400_L + + + + + Schwenkschiene Schiebetür R + ^C^C(ssg-ensure "OmniModulInsert") OMNI_SCHW_400_R + + + + + Schwenkschiene Schiebetür L mit Sensorik + ^C^C(ssg-ensure "OmniModulInsert") OMNI_SCHW_400_L_SENSORIK + + + + + Schwenkschiene Schiebetür R mit Sensorik + ^C^C(ssg-ensure "OmniModulInsert") OMNI_SCHW_400_R_SENSORIK + + + KettenFoerderer ^C^C(ssg-ensure "OmniModulInsert") OMNI_KettenFoerderer - + Ladeschleifen ^C^C(ssg-ensure "OmniModulInsert") OMNI_LADESCHLEIFE_AP110 - + TV W-W kpl ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_W - + TV W-AP110 kpl ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_AP110 - + TV W-AP60 oben kpl. ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_AP60 - + TV W-AP110-W kpl ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_AP110_W - + TV W-AP oben kpl ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_AP - + TV 80 ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_80 - + TV 50 ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_50 - + Endplatte Al-Profil AP schraubbar ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_ENDPLATTE - + Anschlag AP-Ende fuer Spulenzug ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_ANSCHLAG - + TV-A fuer AP110/AP60 kpl ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_A_AP110_AP60 - + TV-A fuer AP60/ST ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_A_AP60_ST - + TV-A fuer AP110/ST kpl ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_A_AP110_ST - + TV-SW II fuer SW-SW ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_II_SW_SW - + TV-SW III fuer SW-AP110-SW ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_III_AP110_SW - + TV-SW III fuer SW-AP110 ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_III_AP110 - + TV-SW IV fuer Anschluss SW-AP60 ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_IV_AP60 - + TV-SW IV fuer SW-ST ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_IV_ST - + Muffe ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_MUFFE - + APB 110 R400/45 140 nur fuer Delta ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R400_45_140 - + APB 110 R550/45 194 nur fuer Delta ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_45_194 - + APBW 110 R550/22,5 360x248,5 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_225_360 - + APBW 110 R550/22,5 410x298,5 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_225_410A - + APBW 110 R550/22,5 410x78,5 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_225_410B - + APBW 110 R550/22,5 410x98,5 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_225_410C - + APBW 110 R550/67,5 360x598,5 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_675_360 - + APBW 110 R400/67,5 260x398,5 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R400_675_260 - + APBW 110 R550/45 77x160 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_45_77 - + APBW 110 R550/67,5 125x83,5 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_675_125 - + APBW 110 R750/90 200x290 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R750_90_200 - + APBW 110 R650/90 300x190 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R650_90_300 - + APBW 110 R550/67,5 208x347 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_675_208 - + APBW 110 R550/67,5 58x497 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_675_58 - + Element bearbeiten ^C^C(ssg-ensure "OmniModulInsert") OMNI_EDIT - + - Rohr-Geruest-Traeger + Rohr-Gerüst-Traeger ^C^C(ssg-ensure "GeruestInsert") GERUEST_TRAEGER - + - Saeulen + Säulen ^C^C(ssg-ensure "GeruestInsert") GERUEST_SAEULEN - + - Rohrabhaenger + Rohrabhänger ^C^C(ssg-ensure "GeruestInsert") GERUEST_ROHRABHAENGER - + Wandbefestigung ^C^C(ssg-ensure "GeruestInsert") GERUEST_WANDBEFESTIGUNG - + - Gattertraeger + Gatterträger ^C^C(ssg-ensure "GeruestInsert") GERUEST - + Traeger beschriften ^C^C(ssg-ensure "GeruestInsert") GERUEST_TRAEGER_BESCHRIFTEN - + Marker einfuegen ^C^C(ssg-ensure "Tro_Edit") TRO_INSERT - + Marker bearbeiten ^C^C(ssg-ensure "Tro_Edit") TRO_EDIT - + Bearbeiten (Auto) ^C^C(ssg-ensure "SSG_LIB_Commands") SSG_BLOCKEDIT - + Verbindung einfuegen ^C^C(ssg-ensure "Connection_Edit") CONNECTION_INSERT - + Verbindung bearbeiten ^C^C(ssg-ensure "Connection_Edit") CONNECTION_EDIT - + Eingang ^C^C(ssg-ensure "SSG_LIB_Commands") ILS_EINGANG_INSERT - + Ausgang ^C^C(ssg-ensure "SSG_LIB_Commands") ILS_AUSGANG_INSERT - + SPS Schliessen ^C^C - + Export Sivas ^C^C(ssg-ensure "export") EXPORTSIVAS - + Export CSV ^C^C(ssg-ensure "export") EXPORTCSV - + Umschalten 2D und 3D ^C^C(ssg-ensure "SSG_LIB_Commands") SSG_DIM_SWITCH - + Alle Bloecke auf 2D ^C^C(ssg-ensure "SSG_LIB_Commands") SSG_DIM_ALL_2D - + Alle Bloecke auf 3D ^C^C(ssg-ensure "SSG_LIB_Commands") SSG_DIM_ALL_3D - + Sprache ^C^C(ssg-ensure "SSG_LIB_Commands") SSG_SPRACHE - + Planquadrate an/aus ^C^C(ssg-ensure "DrawPlanquadrate") PLANQUADRATE_TOGGLE - + CSV-Export ^C^C(ssg-ensure "export") CSV_EXPORT_KONFIG - + Bloecke zaehlen ^C^C(ssg-ensure "ssg_blocktools") SSG_BLOCK_COUNT - + Bloecke loeschen ^C^C(ssg-ensure "ssg_blocktools") SSG_BLOCK_DELETE - + Attribute ersetzen ^C^C(ssg-ensure "ssg_blocktools") SSG_ATTR_ERSETZEN - + Text ersetzen ^C^C(ssg-ensure "ssg_texttools") SSG_TEXT_ERSETZEN - + Text parallel beschriften ^C^C(ssg-ensure "ssg_texttools") SSG_TEXT_PARALLEL - + Texthoehe aendern ^C^C(ssg-ensure "ssg_texttools") SSG_TEXT_HOEHE - + Textstil aendern ^C^C(ssg-ensure "ssg_texttools") SSG_TEXT_STIL - + Faehnchen + Stueckliste aus Zeichnung ^C^C(ssg-ensure "ssg_stueckliste") SSG_FAEHNCHEN_STUECKLISTE - + Din Formate ^C^C(ssg-ensure "DinFormate") DIN_FORMATE - + alle Tests ausfuehren und exportieren ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_run_all.lsp")) (c:SSG_RUN_ALL_TESTS_EXPORT) - + Tests ausfuehren und stehen lassen ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_run_all.lsp")) (c:SSG_RUN_ALL_TESTS_OFFEN) - + Export CSV/Sivas ALL ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_export_all.lsp")) (c:TEST_EXPORT_ALL) - + Kreisel ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_kreisel.lsp")) (c:TEST_KREISEL) - + Foerderer ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_foerderer.lsp")) (c:TEST_FOERDERER) - + Foerderer-Linienzug ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_linienzug.lsp")) (c:TEST_LINIENZUG) (c:TEST_LINIENZUG_STUFE2) - + Omniflo ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_omniflo.lsp")) (c:TEST_OMNIFLO) - + Omniflo Strecke ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_omniflo_strecke.lsp")) (c:TEST_OMNIFLO_STRECKE) - + Gefaellestrecke ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_gefaellestrecke.lsp")) (c:TEST_GEFAELLESTRECKE) - + Mubea Gesamtmodell ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_mubea.lsp")) (c:TEST_MUBEA) - + HundM05 Kreisel-Abschnitt ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_hundm05.lsp")) (c:TEST_HUNDM05) - + Dematic/Arvato Flowpuffer (Vorlage) ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_dematic_arvato.lsp")) (c:TEST_DEMATIC_ARVATO) - + ILS 3.0 Showroom (Vorlage) ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_showroom_ils.lsp")) (c:TEST_SHOWROOM_ILS) - + KS 2D/3D pruefen (CSV) ^C^C(load (strcat (getenv "DXFMAKRO") "/Lisp/ks_pruefung.lsp")) KS_PRUEFEN - + Kreisel bearbeiten (ssg-ensure "KreiselInsert") KreiselEdit - + Omniflo Element bearbeiten (ssg-ensure "OmniModulInsert") OMNI_EDIT - + Gefaellestrecke bearbeiten (ssg-ensure "Gefaellestrecke") GEFAELLESTRECKE_EDIT - + VarioFoerderer bearbeiten (ssg-ensure "VarioFoerderer") VARIOFOERDERER_EDIT - + TRO-Marker bearbeiten (ssg-ensure "Tro_Edit") TRO_EDIT - + Verbindung bearbeiten (ssg-ensure "Connection_Edit") CONNECTION_EDIT - + SSG Bearbeiten (Auto) (ssg-ensure "SSG_LIB_Commands") SSG_BLOCKEDIT @@ -883,12 +919,12 @@ SSG_LIB - - - - + + - + + + ILS @@ -1056,818 +1092,855 @@ Omniflo - - - - - - - - - - + + Fahrstrecke + + + + + + Fahrstrecken beschriften + + + + + + + + + + + + ~KettenFoerderer - + Ladeschleifen - + - - + + Element bearbeiten - + - + Boegen APB110 90 - - - - - - 67.5 - - - - - - 45 - - - - - - 22.5 - 180 + 67.5 - - - Boegen APB60 - 90 + 45 + + + + + + 22.5 + + 180 + + + + - + + Boegen APB60 + + 90 + + + + + + Aluprofil Gerade AP 60 - + AP 110 - + APG 110 - - - - - - - Weiche 90 Grad - - Einfach 90 700/700 links M - - - - - - Doppel 90 700/700 M + + + Weichen - Dreiwege 90 700/700 M + Einfach 90 - + - - - Weiche 45 Grad - Einfach 45 350/700 links M + Doppel 90 - Doppel 45 350/700 M + Dreiwege 90 + - Dreiwege 45 350/700 M + Einfach 45 - + - - - Weichen Parallel - Einfach Parallel 200/750 links M + Doppel 45 - Doppel Parallel 200/750 M + Dreiwege 45 + - Dreiwege Parallel 200/750 M + Einfach Parallel - + - - - Weichenkoerper - Einfach 22.5 links M + Doppel Parallel - Doppel 22.5 M + Dreiwege Parallel + - Dreiwege 22.5 M + Einfach 22.5 - + - - - Weichenkombinationen - Delta 1400/700 M + Doppel 22.5 - Delta 1600/800 M + Dreiwege 22.5 + - Star 1400/1400 M + Delta 1600/800 - + - - - TEF Elemente - TEF Antriebst. rechts + Delta 1400/700 - TEF Umlenkspannst. rechts + Star 1400/1400 - + + + TEF Elemente - TEF Antriebst. links + TEF Antriebst. rechts - TEF Umlenkspannst. links + TEF Umlenkspannst. rechts - TEF Gerade auf Linie + TEF Antriebst. links - TEF Gerade + TEF Umlenkspannst. links - - - Anbaugruppen + - Stopper AP + TEF Gerade auf Linie - Scanner + TEF Gerade + + + Anbaugruppen + + Stopper AP + + + + + + Scanner + + + + Bürstenbremse - + - - Verbinder + + Spez. Streckenelemente + + + + Türlösungen + + + + Schwenkschienen - ~TV W-W kpl - - - - - - ~TV W-AP110 kpl - - - - - - ~TV W-AP60 oben kpl. - - - - - - ~TV W-AP110-W kpl + Schwenkschiene Schiebetür L - ~TV W-AP oben kpl + Schwenkschiene Schiebetür R - ~TV 80 + Schwenkschiene Schiebetür L mit Sensorik - ~TV 50 + Schwenkschiene Schiebetür R mit Sensorik + + + Verbinder - ~Endplatte Al-Profil AP schraubbar - - - - - - ~Anschlag AP-Ende fuer Spulenzug - - - - - - ~TV-A fuer AP110/AP60 kpl - - - - - - ~TV-A fuer AP60/ST + ~TV W-W kpl - ~TV-A fuer AP110/ST kpl + ~TV W-AP110 kpl - ~TV-SW II fuer SW-SW + ~TV W-AP60 oben kpl. - ~TV-SW III fuer SW-AP110-SW + ~TV W-AP110-W kpl - ~TV-SW III fuer SW-AP110 + ~TV W-AP oben kpl - ~TV-SW IV fuer Anschluss SW-AP60 + ~TV 80 - ~TV-SW IV fuer SW-ST + ~TV 50 - ~Muffe + ~Endplatte Al-Profil AP schraubbar - - - Boegen fuer Weichen - ~APB 110 R400/45 140 nur fuer Delta + ~Anschlag AP-Ende fuer Spulenzug + + + + + + ~TV-A fuer AP110/AP60 kpl - ~APB 110 R550/45 194 nur fuer Delta + ~TV-A fuer AP60/ST - ~APBW 110 R550/22,5 360x248,5 + ~TV-A fuer AP110/ST kpl - ~APBW 110 R550/22,5 410x298,5 + ~TV-SW II fuer SW-SW - ~APBW 110 R550/22,5 410x78,5 + ~TV-SW III fuer SW-AP110-SW - ~APBW 110 R550/22,5 410x98,5 + ~TV-SW III fuer SW-AP110 - ~APBW 110 R550/67,5 360x598,5 + ~TV-SW IV fuer Anschluss SW-AP60 - ~APBW 110 R400/67,5 260x398,5 + ~TV-SW IV fuer SW-ST - ~APBW 110 R550/45 77x160 + ~Muffe + + + Boegen fuer Weichen - ~APBW 110 R550/67,5 125x83,5 - - - - - - ~APBW 110 R750/90 200x290 + ~APB 110 R400/45 140 nur fuer Delta - ~APBW 110 R650/90 300x190 + ~APB 110 R550/45 194 nur fuer Delta - ~APBW 110 R550/67,5 208x347 + ~APBW 110 R550/22,5 360x248,5 - ~APBW 110 R550/67,5 58x497 + ~APBW 110 R550/22,5 410x298,5 - - - Geruest - Rohr-Geruest-Traeger + ~APBW 110 R550/22,5 410x78,5 + + + + + + ~APBW 110 R550/22,5 410x98,5 + + + + + + ~APBW 110 R550/67,5 360x598,5 - Saeulen + ~APBW 110 R400/67,5 260x398,5 - Rohrabhaenger + ~APBW 110 R550/45 77x160 - Wandbefestigung + ~APBW 110 R550/67,5 125x83,5 - Gattertraeger + ~APBW 110 R750/90 200x290 - - - - Funktionen - Traeger beschriften + ~APBW 110 R650/90 300x190 + + + + + + ~APBW 110 R550/67,5 208x347 - - - SPS - - - Eingang + ~APBW 110 R550/67,5 58x497 - - - - - Ausgang - - - - - - SPS Schliessen - - + - - TRO + + Gerüst - Marker einfuegen - - - - - - Marker bearbeiten + Rohr-Gerüst-Traeger - Bearbeiten (Auto) + Säulen - - - Connections - Verbindung einfuegen + Rohrabhänger + + + + + + Wandbefestigung - Verbindung bearbeiten + Gatterträger + + + + Funktionen - Bearbeiten (Auto) + Traeger beschriften - + - - Export + + SPS + + - Export Sivas + Eingang + + + + + + Ausgang + + + + + + SPS Schliessen + + + + + + + TRO + + Marker einfuegen + + + + + + Marker bearbeiten - Export CSV + Bearbeiten (Auto) - Konfiguration + Connections - Umschalten 2D und 3D + Verbindung einfuegen - Alle Bloecke auf 2D + Verbindung bearbeiten - Alle Bloecke auf 3D + Bearbeiten (Auto) - - - - - Sprache - - - - - - Planquadrate an/aus - - - - - - CSV-Export - - + - Werkzeuge + Export - Bloecke zaehlen + Export Sivas - Bloecke loeschen + Export CSV + + + Konfiguration + + Umschalten 2D und 3D + + + + + + Alle Bloecke auf 2D + + + + + + Alle Bloecke auf 3D + + + + + + Sprache + + + + + + Planquadrate an/aus + + + + + + CSV-Export + + + + + + + Werkzeuge + + Bloecke zaehlen + + + + + + Bloecke loeschen + + + + Attribute ersetzen - + Text ersetzen - + Text parallel beschriften - + Texthoehe aendern - + Textstil aendern - + Faehnchen + Stueckliste aus Zeichnung - + Din Formate - + - + Tests alle Tests ausfuehren und exportieren - + Tests ausfuehren und stehen lassen - + Export CSV/Sivas ALL - + Kreisel - + Foerderer - + Foerderer-Linienzug - + Omniflo - + Omniflo Strecke - + Gefaellestrecke - + Mubea Gesamtmodell - + HundM05 Kreisel-Abschnitt - + Dematic/Arvato Flowpuffer (Vorlage) - + ILS 3.0 Showroom (Vorlage) - + KS 2D/3D pruefen (CSV) - + - + POP501 SSG_LIB Edit Context Kreisel bearbeiten - + Omniflo Element bearbeiten - + Gefaellestrecke bearbeiten - + VarioFoerderer bearbeiten - + TRO-Marker bearbeiten - + Verbindung bearbeiten - + SSG Bearbeiten (Auto) - + diff --git a/menu/SSG_LIB.mnu b/menu/SSG_LIB.mnu index 6f03637..023d66a 100644 --- a/menu/SSG_LIB.mnu +++ b/menu/SSG_LIB.mnu @@ -34,6 +34,9 @@ [QC Linie mit GF (automatische Auf-Ab-Berechnung)]^C^C(ssg-ensure "VarioFoerderer") QcLinieMitGf [<-<-QC Linie mit GF und U-Form]^C^C(ssg-ensure "VarioFoerderer") QcLinieMitGfUForm [->Omniflo] +[Fahrstrecke]^C^C(ssg-ensure "GeruestInsert") OMNI_FAHRSTRECKE +[Fahrstrecken beschriften]^C^C(ssg-ensure "GeruestInsert") OMNI_FAHRSTRECKE_BESCHRIFTEN +[--] [->Boegen APB110] [90]^C^C(ssg-ensure "OmniModulInsert") OMNI_APB_630_90 [67.5]^C^C(ssg-ensure "OmniModulInsert") OMNI_APB_550_675 @@ -46,26 +49,26 @@ [AP 60]^C^C(ssg-ensure "OmniModulInsert") OMNI_AP60 [AP 110]^C^C(ssg-ensure "OmniModulInsert") OMNI_AP110 [<-APG 110]^C^C(ssg-ensure "OmniModulInsert") OMNI_APG110 -[->Weiche 90 Grad] -[Einfach 90 700/700 links M]^C^C(ssg-ensure "OmniModulInsert") OMNI_W90_Einfach -[Doppel 90 700/700 M]^C^C(ssg-ensure "OmniModulInsert") OMNI_W90_Doppel -[<-Dreiwege 90 700/700 M]^C^C(ssg-ensure "OmniModulInsert") OMNI_W90_Dreiwege -[->Weiche 45 Grad] -[Einfach 45 350/700 links M]^C^C(ssg-ensure "OmniModulInsert") OMNI_W45_Einfach -[Doppel 45 350/700 M]^C^C(ssg-ensure "OmniModulInsert") OMNI_W45_Doppel -[<-Dreiwege 45 350/700 M]^C^C(ssg-ensure "OmniModulInsert") OMNI_W45_Dreiwege -[->Weichen Parallel] -[Einfach Parallel 200/750 links M]^C^C(ssg-ensure "OmniModulInsert") OMNI_WP_Einfach -[Doppel Parallel 200/750 M]^C^C(ssg-ensure "OmniModulInsert") OMNI_WP_Doppel -[<-Dreiwege Parallel 200/750 M]^C^C(ssg-ensure "OmniModulInsert") OMNI_WP_Dreiwege -[->Weichenkoerper] -[Einfach 22.5 links M]^C^C(ssg-ensure "OmniModulInsert") OMNI_WK_Einfach -[Doppel 22.5 M]^C^C(ssg-ensure "OmniModulInsert") OMNI_WK_Doppel -[<-Dreiwege 22.5 M]^C^C(ssg-ensure "OmniModulInsert") OMNI_WK_Dreiwege -[->Weichenkombinationen] -[Delta 1400/700 M]^C^C(ssg-ensure "OmniModulInsert") OMNI_WKomb_Delta_1400 -[Delta 1600/800 M]^C^C(ssg-ensure "OmniModulInsert") OMNI_WKomb_Delta_1600 -[<-Star 1400/1400 M]^C^C(ssg-ensure "OmniModulInsert") OMNI_WKomb_Star +[->Weichen] +[Einfach 90]^C^C(ssg-ensure "OmniModulInsert") OMNI_W90_Einfach +[Doppel 90]^C^C(ssg-ensure "OmniModulInsert") OMNI_W90_Doppel +[Dreiwege 90]^C^C(ssg-ensure "OmniModulInsert") OMNI_W90_Dreiwege +[--] +[Einfach 45]^C^C(ssg-ensure "OmniModulInsert") OMNI_W45_Einfach +[Doppel 45]^C^C(ssg-ensure "OmniModulInsert") OMNI_W45_Doppel +[Dreiwege 45]^C^C(ssg-ensure "OmniModulInsert") OMNI_W45_Dreiwege +[--] +[Einfach Parallel]^C^C(ssg-ensure "OmniModulInsert") OMNI_WP_Einfach +[Doppel Parallel]^C^C(ssg-ensure "OmniModulInsert") OMNI_WP_Doppel +[Dreiwege Parallel]^C^C(ssg-ensure "OmniModulInsert") OMNI_WP_Dreiwege +[--] +[Einfach 22.5]^C^C(ssg-ensure "OmniModulInsert") OMNI_WK_Einfach +[Doppel 22.5]^C^C(ssg-ensure "OmniModulInsert") OMNI_WK_Doppel +[Dreiwege 22.5]^C^C(ssg-ensure "OmniModulInsert") OMNI_WK_Dreiwege +[--] +[Delta 1600/800]^C^C(ssg-ensure "OmniModulInsert") OMNI_WKomb_Delta_1600 +[Delta 1400/700]^C^C(ssg-ensure "OmniModulInsert") OMNI_WKomb_Delta_1400 +[<-Star 1400/1400]^C^C(ssg-ensure "OmniModulInsert") OMNI_WKomb_Star [->TEF Elemente] [TEF Antriebst. rechts]^C^C(ssg-ensure "OmniModulInsert") OMNI_TEF_AntriebR [TEF Umlenkspannst. rechts]^C^C(ssg-ensure "OmniModulInsert") OMNI_TEF_UmlenkR @@ -79,6 +82,13 @@ [Stopper AP]^C^C(ssg-ensure "OmniModulInsert") OMNI_STOPPER [Scanner]^C^C(ssg-ensure "OmniModulInsert") OMNI_SCANNER [<-Bürstenbremse]^C^C(ssg-ensure "OmniModulInsert") OMNI_BUERSTENBREMSE +[->Spez. Streckenelemente] +[->Türlösungen] +[->Schwenkschienen] +[Schwenkschiene Schiebetür L]^C^C(ssg-ensure "OmniModulInsert") OMNI_SCHW_400_L +[Schwenkschiene Schiebetür R]^C^C(ssg-ensure "OmniModulInsert") OMNI_SCHW_400_R +[Schwenkschiene Schiebetür L mit Sensorik]^C^C(ssg-ensure "OmniModulInsert") OMNI_SCHW_400_L_SENSORIK +[<-<-<-Schwenkschiene Schiebetür R mit Sensorik]^C^C(ssg-ensure "OmniModulInsert") OMNI_SCHW_400_R_SENSORIK [~KettenFoerderer]^C^C(ssg-ensure "OmniModulInsert") OMNI_KettenFoerderer [Ladeschleifen]^C^C(ssg-ensure "OmniModulInsert") OMNI_LADESCHLEIFE_AP110 [->Verbinder] @@ -116,12 +126,12 @@ [~APBW 110 R550/67,5 208x347]^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_675_208 [<-~APBW 110 R550/67,5 58x497]^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_675_58 [<-Element bearbeiten]^C^C(ssg-ensure "OmniModulInsert") OMNI_EDIT -[->Geruest]^C^C(ssg-ensure "GeruestInsert") GERUEST -[Rohr-Geruest-Traeger]^C^C(ssg-ensure "GeruestInsert") GERUEST_TRAEGER -[Saeulen]^C^C(ssg-ensure "GeruestInsert") GERUEST_SAEULEN -[Rohrabhaenger]^C^C(ssg-ensure "GeruestInsert") GERUEST_ROHRABHAENGER +[->Gerüst]^C^C(ssg-ensure "GeruestInsert") GERUEST +[Rohr-Gerüst-Traeger]^C^C(ssg-ensure "GeruestInsert") GERUEST_TRAEGER +[Säulen]^C^C(ssg-ensure "GeruestInsert") GERUEST_SAEULEN +[Rohrabhänger]^C^C(ssg-ensure "GeruestInsert") GERUEST_ROHRABHAENGER [Wandbefestigung]^C^C(ssg-ensure "GeruestInsert") GERUEST_WANDBEFESTIGUNG -[Gattertraeger]^C^C(ssg-ensure "GeruestInsert") GERUEST +[Gatterträger]^C^C(ssg-ensure "GeruestInsert") GERUEST [->Funktionen] [<-<-Traeger beschriften]^C^C(ssg-ensure "GeruestInsert") GERUEST_TRAEGER_BESCHRIFTEN [->SPS] diff --git a/tests/test_export_geruest_merkmale.py b/tests/test_export_geruest_merkmale.py new file mode 100644 index 0000000..2f411dd --- /dev/null +++ b/tests/test_export_geruest_merkmale.py @@ -0,0 +1,39 @@ +"""Merkmale der GR_-Geruest-Bloecke im CSV-Export (build_geruest_merkmale). + +Prueft die Teilefarbe (Attribut TEILEFARBE - das frueher gelesene FARBE gibt +es im Schema nicht) und die Laengenabzuege, die nur der Rohr-Geruest-Traeger +traegt und die bei den anderen GR_-Bloecken nicht auftauchen duerfen. +""" + +import os +import sys + +sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib")) + +from export_csv import build_geruest_merkmale # noqa: E402 + + +def test_teilefarbe_aus_teilefarbe_attribut(): + block = {"attribs": {"TEILEART": "Geruest Saeule 1 Zoll", + "TEILEFARBE": ",RAL7030", "LAENGE": "2000", + "LAYER": "D-6"}} + m = build_geruest_merkmale(block) + assert m["Farbe"] == ",RAL7030" + assert m["Laenge"] == "2000" + assert m["Layer"] == "D-6" + + +def test_ohne_abzug_keine_abzugsmerkmale(): + m = build_geruest_merkmale({"attribs": {"TEILEART": "Geruest Rohrabhaenger"}}) + assert "LaengenabzugAnfang" not in m + assert "LaengenabzugEnde" not in m + + +def test_traeger_abzuege(): + block = {"attribs": {"TEILEART": "Geruest Traeger 1 Zoll", "LAENGE": "965", + "LAENGENABZUGANFANG": "0", + "LAENGENABZUGENDE": "35"}} + m = build_geruest_merkmale(block) + assert m["Laenge"] == "965" + assert m["LaengenabzugAnfang"] == "0" + assert m["LaengenabzugEnde"] == "35" diff --git a/tests/test_export_sivas_zusammenfassen.py b/tests/test_export_sivas_zusammenfassen.py new file mode 100644 index 0000000..1ec24a4 --- /dev/null +++ b/tests/test_export_sivas_zusammenfassen.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +test_export_sivas_zusammenfassen.py - zusammengefasste Sivas-Kopie +(_zusammengefasst.csv, export_sivas.items_zusammenfassen). +Laeuft komplett ohne BricsCAD (reine Python-Logik). +""" + +import os +import sys + +sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib")) + +import export_sivas # noqa: E402 + + +def _geruest(teileid, laenge="2500"): + return {"block_name": f"GR_{teileid}", "x": 0.0, "y": 0.0, "z": 0.0, + "rotation": 0.0, + "attribs": {"ID": teileid, "TEILEART": "Geruest Saeule 2 Zoll", + "ARTINR": "821006051,825002022,825002022", + "TEILEFARBE": "RAL7035,,", + "BEZEICHNUNG": "Saeule", "LAENGE": laenge}} + + +def test_gleiche_zeilen_werden_summiert(): + items, _ = export_sivas.process_blocks( + [_geruest("0001"), _geruest("0002"), _geruest("0003", laenge="2800")]) + assert len(items) == 6 + zus = export_sivas.items_zusammenfassen(items) + # Laenge gehoert zum Schluessel: 2500er und 2800er bleiben getrennt + assert len(zus) == 4 + assert [z["nr"] for z in zus] == [1, 2, 3, 4] + z = {(z["sivasnr"], z["laenge_mm"]): z for z in zus} + assert z[("825002022", "2500")]["anzahl"] == 4 + assert z[("825002022", "2500")]["ids"] == ["0001", "0002"] + assert z[("821006051", "2500")]["anzahl"] == 2 + assert z[("821006051", "2500")]["details"] == {export_sivas.MERKMAL_TEILEFARBE: "RAL7035"} + assert z[("825002022", "2800")]["anzahl"] == 2 + assert z[("825002022", "2800")]["ids"] == ["0003"] + + +def test_eingabe_bleibt_unveraendert(): + items, _ = export_sivas.process_blocks([_geruest("0001"), _geruest("0002")]) + vorher = [export_sivas.format_csv_line(it) for it in items] + export_sivas.items_zusammenfassen(items) + assert [export_sivas.format_csv_line(it) for it in items] == vorher + + +def test_dateiname(): + assert export_sivas.zusammengefasster_dateiname("x/500651_sivas.csv") == \ + "x/500651_sivas_zusammengefasst.csv" diff --git a/tests/test_lastent.lsp b/tests/test_lastent.lsp new file mode 100644 index 0000000..d65ec8c --- /dev/null +++ b/tests/test_lastent.lsp @@ -0,0 +1,129 @@ +;; ============================================================ +;; test_lastent.lsp - Szenario-Test fuer ssg-lastent-ohne-attribute (ssg_core) +;; +;; Stellt den realen Bug nach: ein Block MIT Attributen (z.B. eine per +;; Strg+C/V eingefuegte GR_-Kopie) ist das letzte Objekt der Zeichnung. +;; Ein Makro merkt sich die Startmarke, zeichnet neue Objekte, sammelt +;; "alles ab (entnext marke)" ein und wickelt es per _.-BLOCK zu einem Block. +;; Mit nacktem (entlast) als Marke landeten dabei die ATTRIBs des alten +;; Blocks im Auswahlsatz und wurden entfernt. +;; +;; Aufruf in BricsCAD: +;; (load (strcat (getenv "DXFMAKRO") "/tests/test_lastent.lsp")) +;; TEST_LASTENT +;; +;; Speichert tests/output/lastent_results.json (Konvention test_run_all). +;; ============================================================ + +(setq *tle-pass* 0 *tle-fail* 0 *tle-fails* '()) + +;; Ein Assert: erwartet-Wert gleich ist-Wert (equal). Loggt Pass/Fail. +(defun tle-eq (name erwartet ist) + (if (equal erwartet ist) + (progn (setq *tle-pass* (1+ *tle-pass*)) + (princ (strcat "\n [PASS] " name))) + (progn (setq *tle-fail* (1+ *tle-fail*)) + (setq *tle-fails* (cons name *tle-fails*)) + (princ (strcat "\n [FAIL] " name + "\n erwartet: " (vl-princ-to-string erwartet) + "\n ist: " (vl-princ-to-string ist)))))) + +;; Blockdefinition mit zwei ATTDEFs anlegen (falls noch nicht vorhanden). +(defun tle-blockdef (name) + (if (not (tblsearch "BLOCK" name)) + (progn + (entmake (list '(0 . "BLOCK") (cons 2 name) '(70 . 2) '(10 0.0 0.0 0.0))) + (entmake '((0 . "LINE") (8 . "0") (10 0.0 0.0 0.0) (11 100.0 0.0 0.0))) + (foreach tag '("ID" "ARTINR") + (entmake (list '(0 . "ATTDEF") '(8 . "0") '(10 0.0 0.0 0.0) + '(40 . 10.0) '(1 . "") (cons 2 tag) (cons 3 tag) + '(70 . 0)))) + (entmake '((0 . "ENDBLK"))))) + name) + +;; INSERT mit Attributen per entmake (INSERT 66=1, ATTRIBs, SEQEND). +;; Rueckgabe: ename des INSERT. +(defun tle-insert-mit-attributen (name pt werte / ins) + (entmake (list '(0 . "INSERT") (cons 2 name) (cons 10 pt) '(66 . 1))) + (setq ins (entlast)) + (foreach paar werte + (entmake (list '(0 . "ATTRIB") '(8 . "0") (cons 10 pt) '(40 . 10.0) + (cons 1 (cdr paar)) (cons 2 (car paar)) '(70 . 0)))) + (entmake '((0 . "SEQEND"))) + ins) + +(defun lastent:tests ( / bname werte ins marke line ss e neu anz) + (setvar "CMDECHO" 0) + (setq bname (tle-blockdef "TLE_ATT_BLOCK")) + (setq werte (list (cons "ID" "4711") (cons "ARTINR" "A1,A2"))) + (setq ins (tle-insert-mit-attributen bname '(0.0 0.0 0.0) werte)) + + ;; --- Vorbedingung: Attribute lesbar, INSERT ist (entlast) --- + (tle-eq "vorher: attribute lesbar" werte (ssg-attrib-read ins)) + (tle-eq "vorher: entlast = insert" ins (entlast)) + + ;; --- Marke steht auf dem SEQEND des Attribut-Blocks --- + (setq marke (ssg-lastent-ohne-attribute)) + (tle-eq "marke ist SEQEND" "SEQEND" (cdr (assoc 0 (entget marke)))) + + ;; --- Neues Objekt zeichnen: entnext der Marke ist genau dieses Objekt --- + (entmake '((0 . "LINE") (8 . "0") (10 0.0 50.0 0.0) (11 100.0 50.0 0.0))) + (setq line (entlast)) + (tle-eq "entnext marke = neues objekt" line (entnext marke)) + + ;; --- Einsammeln + _.-BLOCK wie geruest-block-bauen --- + (setq ss (ssadd) anz 0 e (entnext marke)) + (while e (ssadd e ss) (setq anz (1+ anz)) (setq e (entnext e))) + (tle-eq "genau 1 objekt eingesammelt" 1 anz) + (setq neu (strcat "TLE_NEU_" (ssg-timestamp))) + (command "_.-BLOCK" neu '(0.0 0.0 0.0) ss "") + + ;; --- Kern des Bugs: der alte Block behaelt seine Attribute --- + (tle-eq "nachher: attribute erhalten" werte (ssg-attrib-read ins)) + (tle-eq "nachher: neuer block existiert" T (if (tblsearch "BLOCK" neu) T nil)) + + ;; --- Leere Zeichnung wird hier nicht getestet (Testzeichnung ist nie leer); + ;; ohne Attribute liefert der Helfer (entlast) unveraendert --- + (entmake '((0 . "LINE") (8 . "0") (10 0.0 90.0 0.0) (11 10.0 90.0 0.0))) + (tle-eq "ohne attribute: marke = entlast" (entlast) (ssg-lastent-ohne-attribute)) + + ;; Aufraeumen + (entdel ins) + (entdel (entlast)) + (princ)) + + +(defun lastent:export-results (out-dir / f pfad) + (setq pfad (strcat out-dir "/lastent_results.json")) + (setq f (open pfad "w")) + (if f + (progn + (write-line "{" f) + (write-line (strcat " \"pass\": " (itoa *tle-pass*) ",") f) + (write-line (strcat " \"fail\": " (itoa *tle-fail*) ",") f) + (write-line (strcat " \"status\": \"" + (if (= *tle-fail* 0) "OK" "FEHLER") "\"") f) + (write-line "}" f) + (close f) + (princ (strcat "\n Ergebnis: " pfad)))) + (princ)) + + +(defun c:TEST_LASTENT ( / ) + (setq *tle-pass* 0 *tle-fail* 0 *tle-fails* '()) + (princ "\n================================================================") + (princ "\n TEST_LASTENT - ssg-lastent-ohne-attribute (ssg_core.lsp)") + (princ "\n================================================================") + (lastent:tests) + (princ "\n\n----------------------------------------------------------------") + (princ (strcat "\n Ergebnis: " (itoa *tle-pass*) " PASS, " + (itoa *tle-fail*) " FAIL")) + (if (> *tle-fail* 0) + (progn + (princ "\n Fehlgeschlagen:") + (foreach n (reverse *tle-fails*) (princ (strcat "\n - " n))))) + (princ "\n================================================================") + (princ)) + +(princ "\nTEST_LASTENT geladen. Aufruf: TEST_LASTENT") +(princ) diff --git a/tests/test_unit.lsp b/tests/test_unit.lsp index b8296dc..892fb75 100644 --- a/tests/test_unit.lsp +++ b/tests/test_unit.lsp @@ -217,6 +217,21 @@ (setq *ssg-ils-dim* _lay-dim-alt *ssg-layer-cfg* _lay-cfg-alt *ssg-layer-cfg-versucht* _lay-vers-alt) + + ;; --- DCL-Vorlagen: Platzhalterzeilen //@NAME@ ersetzen --- + (tu-eq "ssg-dcl-zeilen-ersetzen/ersetzt" + '("a {" " x;" " y;" "}") + (ssg-dcl-zeilen-ersetzen '("a {" " //@L@" "}") '(("L" " x;" " y;")))) + (tu-eq "ssg-dcl-zeilen-ersetzen/leer-entfernt" + '("a {" "}") + (ssg-dcl-zeilen-ersetzen '("a {" "\t//@L@ " "}") '(("L")))) + (tu-eq "ssg-dcl-zeilen-ersetzen/mehrere" + '("1" "2") + (ssg-dcl-zeilen-ersetzen '("//@A@" "//@B@") '(("A" "1") ("B" "2")))) + ;; unbekannter Marker und normaler Kommentar bleiben stehen + (tu-eq "ssg-dcl-zeilen-ersetzen/unbekannt" + '("//@X@" "// Kommentar") + (ssg-dcl-zeilen-ersetzen '("//@X@" "// Kommentar") '(("A" "1")))) ) @@ -849,7 +864,7 @@ ) (defun tu-tests-geruest ( / _eintrag _gruppe _teile _konfig _rec _pfad _f - _zurueck _bgtest _saeulen) + _zurueck _bgtest _saeulen _vmq _alt _fs) (princ "\n[GeruestInsert]") ;; GeruestInsert ist ein lazy Feature-Modul (nicht in der Core-Ladeliste). ;; Geladen wird es zentral in test_unit.scr auf .scr-Top-Level; hier nur @@ -917,10 +932,10 @@ "{\"artikel\": \"X\", \"sivas_id\": 7, \"stueckzahl\": 2, \"anzahl_vorgabe\": 5}") 2)) ;; Dummy, der zugleich Teile-DWG ist, faellt aus der Teileliste - (tu-eq "geruest-ohne-pfad/entfernt" '("b/2.dwg") - (geruest-ohne-pfad "A/1.DWG" '("a/1.dwg" "b/2.dwg"))) - (tu-eq "geruest-ohne-pfad/nil" '("a/1.dwg") - (geruest-ohne-pfad nil '("a/1.dwg"))) + (tu-eq "geruest-ohne-pfad/entfernt" '(("b/2.dwg" . 90.0)) + (geruest-ohne-pfad "A/1.DWG" '(("a/1.dwg" . 0.0) ("b/2.dwg" . 90.0)))) + (tu-eq "geruest-ohne-pfad/nil" '(("a/1.dwg" . 0.0)) + (geruest-ohne-pfad nil '(("a/1.dwg" . 0.0)))) ;; Dummy-Wahl: Variante gewinnt, fehlende Varianten-DWG -> Baugruppe (setq _pfad (geruest-dummy-pfad "821006036.dwg")) (if (and _pfad (findfile _pfad)) @@ -1015,7 +1030,148 @@ "{\"artikel\": \"Schraubenset\", \"anzahl\": 3}," "{\"artikel\": \"unbekannt\", \"anzahl\": 1}]}"))) (tu-eq "geruest-konfig-position" '(nil 3) - (geruest-konfig-position _konfig "oben" _teile)) + (geruest-konfig-position _konfig "oben" _teile nil)) + + ;; --- anbaugruppen: befestigung / sonstiges --- + (setq _bgtest (ssg-json-parse + (strcat "{\"anbaugruppen\": {\"befestigung\": [{\"artikel\": \"K\"}]," + " \"sonstiges\": [{\"artikel\": \"H1\"}, {\"artikel\": \"H2\"}]}}"))) + (tu-eq "geruest-anbau-liste/befestigung" 1 + (length (geruest-anbau-liste _bgtest "befestigung"))) + (tu-eq "geruest-anbau-liste/sonstiges" '("H1" "H2") + (mapcar 'geruest-eintrag-name (geruest-anbau-liste _bgtest "sonstiges"))) + ;; altes flaches Array gilt als befestigung + (setq _rec (ssg-json-parse "{\"anbaugruppen\": [{\"artikel\": \"A\"}, {\"artikel\": \"B\"}]}")) + (tu-eq "geruest-anbau-liste/flach" 2 (length (geruest-anbau-liste _rec "befestigung"))) + (tu-nil "geruest-anbau-liste/flach-sonstiges" (geruest-anbau-liste _rec "sonstiges")) + (tu-nil "geruest-anbau-liste/leer" + (geruest-anbau-liste + (ssg-json-parse "{\"anbaugruppen\": {\"befestigung\": [], \"sonstiges\": []}}") + "sonstiges")) + (tu-nil "geruest-anbau-liste/fehlt" + (geruest-anbau-liste (ssg-json-parse "{\"id\": \"X\"}") "befestigung")) + (tu-eq "geruest-dlg-standard/teile" '(("0" . "1") ("0" . "1")) + (geruest-dlg-standard (geruest-anbau-liste _bgtest "sonstiges"))) + (tu-eq "geruest-mengen-addieren" '(nil 3 2 5) + (geruest-mengen-addieren '(nil 1 nil 2) '(nil 2 2 3))) + ;; Alte Konfiguration mit Haltearm unter "oben": landet in sonstiges + ;; (Mengen addiert), oben meldet ihn nicht als unbekannt + (setq _konfig (ssg-json-parse + (strcat "{\"name\": \"Alt\"," + " \"oben\": [{\"artikel\": \"K\", \"anzahl\": 2}, {\"artikel\": \"H2\", \"anzahl\": 1}]," + " \"unten\": [{\"artikel\": \"H2\", \"anzahl\": 2}]," + " \"sonstiges\": [{\"artikel\": \"H1\", \"anzahl\": 4}]}"))) + (tu-eq "geruest-konfig-position/ausweich" '(2) + (geruest-konfig-position _konfig "oben" + (geruest-anbau-liste _bgtest "befestigung") + (geruest-anbau-liste _bgtest "sonstiges"))) + ;; --- Winkel Platte: Basis ungedreht, Anbauteile gedreht, kein Doppel --- + (tu-eq "geruest-teile-dwgs-rot/90" '(("b.dwg" . 0.0) ("a.dwg" . 90.0)) + (geruest-teile-dwgs-rot '("b.dwg") '("b.dwg" "a.dwg") 90)) + (tu-eq "geruest-teile-dwgs-rot/0" '(("a.dwg" . 0.0)) + (geruest-teile-dwgs-rot nil '("a.dwg") 0)) + (tu-eq "geruest-rest-liste" '(3 4) (geruest-rest-liste '(1 2 3 4) 2)) + (tu-eq "geruest-winkel-aus-index/90" 90 (geruest-winkel-aus-index "1")) + (tu-eq "geruest-winkel-aus-index/leer" 0 (geruest-winkel-aus-index "")) + (tu-eq "geruest-winkel-index/90" "1" (geruest-winkel-index 90)) + (tu-eq "geruest-winkel-index/fehlt" "0" (geruest-winkel-index nil)) + ;; --- Radiobuttons der Varianten: Key "v" <-> Index --- + (tu-eq "geruest-radio-key" "v3" (geruest-radio-key 3)) + (tu-eq "geruest-radio-index" 3 (geruest-radio-index "v3")) + (tu-eq "geruest-radio-index/leer" 0 (geruest-radio-index "")) + (tu-eq "geruest-radio-index/nil" 0 (geruest-radio-index nil)) + (tu-eq "geruest-indizes" '(0 1 2) (geruest-indizes 3)) + (tu-nil "geruest-indizes/0" (geruest-indizes 0)) + (tu-eq "geruest-dcl-varianten-zeilen" + '(" : radio_button { key = \"v1\"; label = \"B 1''\"; }") + (geruest-dcl-varianten-zeilen + (list '(("name" . "A")) '(("name" . "B 1\""))) '(1))) + ;; Variante mit Teilen: Artikelnummern in Klammern, jede nur einmal + (tu-eq "geruest-varianten-label/nummern" "R 2\" (111, 222)" + (geruest-varianten-label + (ssg-json-parse + (strcat "{\"name\": \"R 2\\\"\", \"teile\": [" + "{\"artikel\": \"A\", \"sivas_id\": 111}," + "{\"artikel\": \"B\", \"sivas_id\": 222, \"stueckzahl\": 2}]}")))) + (tu-eq "geruest-varianten-label/ohne" "A" + (geruest-varianten-label '(("name" . "A")))) + ;; --- Gesperrte Varianten ("disabled": true) --- + (setq _rec (list '(("name" . "A") ("disabled" . T)) + '(("name" . "B")) + '(("name" . "C") ("disabled" . T)))) + (tu-true "geruest-variante-gesperrt-p/ja" (geruest-variante-gesperrt-p (nth 0 _rec))) + (tu-nil "geruest-variante-gesperrt-p/nein" (geruest-variante-gesperrt-p (nth 1 _rec))) + (tu-eq "geruest-erste-freie-variante" 1 (geruest-erste-freie-variante _rec)) + (tu-eq "geruest-erste-freie-variante/alle-gesperrt" 0 + (geruest-erste-freie-variante (list '(("disabled" . T))))) + (tu-eq "geruest-variante-waehlbar/frei" 1 (geruest-variante-waehlbar _rec 1)) + (tu-eq "geruest-variante-waehlbar/gesperrt" 1 (geruest-variante-waehlbar _rec 2)) + (tu-eq "geruest-variante-waehlbar/zu-gross" 1 (geruest-variante-waehlbar _rec 7)) + ;; Ersetzungen: ohne Teile entfallen die Bloecke (leerer Cluster) + (setq _rec (geruest-dcl-ersetzungen "Saeulen" nil nil + (list '(("name" . "A"))))) + (tu-nil "geruest-dcl-ersetzungen/ohne-befestigung" + (cdr (assoc "BEFESTIGUNG" _rec))) + (tu-nil "geruest-dcl-ersetzungen/ohne-sonstiges" + (cdr (assoc "SONSTIGES" _rec))) + (tu-eq "geruest-dcl-ersetzungen/varianten" 1 + (length (cdr (assoc "VARIANTEN" _rec)))) + ;; --- Geaenderte Konfiguration: Vergleich ohne Namen --- + (tu-true "geruest-record-gleich-p/name" + (geruest-record-gleich-p '(("name" . "A") ("laenge" . "100")) + '(("name" . "B") ("laenge" . "100")))) + (tu-nil "geruest-record-gleich-p/geaendert" + (geruest-record-gleich-p '(("name" . "A") ("laenge" . "100")) + '(("name" . "A") ("laenge" . "200")))) + ;; Eigene Konfiguration gewinnt vor gleichnamiger Bibliothek; nur eine + ;; eigene liefert eine Namensvorgabe (Ueberspeichern) + (setq _alt *geruest-konfig-liste*) + (setq *geruest-konfig-liste* + (list (cons nil '(("name" . "K"))) (cons T '(("name" . "K"))) + (cons nil '(("name" . "L"))))) + (tu-eq "geruest-konfig-index/eigene-zuerst" 2 (geruest-konfig-index "K")) + (tu-eq "geruest-konfig-index/bibliothek" 3 (geruest-konfig-index "L")) + (tu-eq "geruest-konfig-name-vorgabe/eigene" "K" (geruest-konfig-name-vorgabe 2)) + (tu-nil "geruest-konfig-name-vorgabe/bibliothek" (geruest-konfig-name-vorgabe 1)) + (tu-nil "geruest-konfig-name-vorgabe/keine" (geruest-konfig-name-vorgabe 0)) + (setq *geruest-konfig-liste* _alt) + (tu-eq "geruest-konfig-sonstiges/umhaengen" '(4 3) + (geruest-konfig-sonstiges _konfig + (geruest-anbau-liste _bgtest "sonstiges") + (geruest-anbau-liste _bgtest "befestigung"))) + ;; Befestigung = Gesamtanzahl: neues Feld "befestigung", altes oben + + ;; unten summiert; der Haltearm unter "oben" wird hier still uebergangen + (tu-eq "geruest-konfig-befestigung/alt" '(2) + (geruest-konfig-befestigung _konfig + (geruest-anbau-liste _bgtest "befestigung") + (geruest-anbau-liste _bgtest "sonstiges"))) + (tu-eq "geruest-konfig-befestigung/oben-unten" '(5) + (geruest-konfig-befestigung + (ssg-json-parse + (strcat "{\"name\": \"A\", \"oben\": [{\"artikel\": \"K\", \"anzahl\": 2}]," + " \"unten\": [{\"artikel\": \"K\", \"anzahl\": 3}]}")) + (geruest-anbau-liste _bgtest "befestigung") + (geruest-anbau-liste _bgtest "sonstiges"))) + (tu-eq "geruest-konfig-befestigung/neu" '(4) + (geruest-konfig-befestigung + (ssg-json-parse + "{\"name\": \"N\", \"befestigung\": [{\"artikel\": \"K\", \"anzahl\": 4}]}") + (geruest-anbau-liste _bgtest "befestigung") + (geruest-anbau-liste _bgtest "sonstiges"))) + ;; Artikelnummer(n) fuer die Anzeige: Einzelteil bzw. Gruppe eindeutig + (tu-eq "geruest-artnr-anzeige/einzelteil" "825002019" + (geruest-artnr-anzeige _eintrag)) + (tu-eq "geruest-artnr-anzeige/gruppe" "111, 222" + (geruest-artnr-anzeige _gruppe)) + ;; Eine Befestigungsspalte (Prefix b) mit Art.-Nr.-Zeile je Teil + (setq _rec (geruest-dcl-ersetzungen "Saeulen" (list _eintrag) nil + (list '(("name" . "A"))))) + (tu-true "geruest-dcl-ersetzungen/befestigung-key" + (vl-some '(lambda (z) (vl-string-search "key = \"bm0\"" z)) + (cdr (assoc "BEFESTIGUNG" _rec)))) + (tu-true "geruest-dcl-ersetzungen/artnr-zeile" + (vl-some '(lambda (z) (vl-string-search "Art.-Nr. 825002019" z)) + (cdr (assoc "BEFESTIGUNG" _rec)))) ;; --- Variante gewinnt vor Baugruppe (TEILEART/dummy) --- ;; Die zusammengefuehrte Saeulen-Baugruppe unterscheidet 1 Zoll und @@ -1032,9 +1188,7 @@ (geruest-variante-wert nil _bgtest "dummy")) ;; --- Zusammengefuehrte Saeulen-Baugruppe --- - (setq _saeulen nil) - (foreach _e (geruest-baugruppen-liste) - (if (equal (car _e) "Saeulen") (setq _saeulen (cdr _e)))) + (setq _saeulen (geruest-baugruppe "Saeulen" (geruest-daten))) (tu-eq "geruest/saeulen-vorhanden" T (if _saeulen T nil)) (if _saeulen (progn @@ -1046,10 +1200,27 @@ (tu-geruest-artikel-unvollstaendig (ssg-json-get _saeulen "geometrie_varianten"))) (tu-eq "geruest/saeulen-anbauteile" T - (if (ssg-json-get _saeulen "anbaugruppen") T nil)) + (if (geruest-anbau-liste _saeulen "befestigung") T nil)) (tu-eq "geruest/saeulen-anbauteile-artikel" 0 (tu-geruest-artikel-unvollstaendig - (ssg-json-get _saeulen "anbaugruppen"))) + (geruest-anbau-liste _saeulen "befestigung"))) + ;; Haltearme passen weder oben noch unten -> eigene Sonstiges-Zeile + (tu-eq "geruest/saeulen-sonstiges" 4 + (length (geruest-anbau-liste _saeulen "sonstiges"))) + (tu-eq "geruest/saeulen-sonstiges-artikel" 0 + (tu-geruest-artikel-unvollstaendig + (geruest-anbau-liste _saeulen "sonstiges"))) + (tu-nil "geruest/saeulen-haltearm-nicht-befestigung" + (vl-some '(lambda (a) + (wcmatch (geruest-eintrag-name a) "HALTEARM*")) + (geruest-anbau-liste _saeulen "befestigung"))) + ;; Rohrabhaenger/Wandbefestigung haben keine Sonstiges-Teile + (foreach _e '("Rohrabhaenger" "Wandbefestigung") + (setq _rec (geruest-baugruppe _e (geruest-daten))) + (tu-true (strcat "geruest/" _e "-befestigung") + (geruest-anbau-liste _rec "befestigung")) + (tu-nil (strcat "geruest/" _e "-ohne-sonstiges") + (geruest-anbau-liste _rec "sonstiges"))) (tu-eq "geruest/saeulen-titel" "Saeulen" (geruest-titel _saeulen)) ;; Variante R 1" traegt die eigene TEILEART - per Name gesucht, ;; die Reihenfolge in geruest.json ist nicht fest. @@ -1136,20 +1307,33 @@ (tu-eqf "geruest-traeger-streben/6000-letzte" 5750.0 (last _rec)) ;; Konfiguration: fehlende Felder -> Standard, ohne querstrebe -> nil ;; Ergebnis (dummy laenge querlinie abstand rand-min rand-max) + ;; Streben nur bei Varianten mit "mit_querstrebe": true + (setq _vmq (ssg-json-parse "{\"name\": \"A\", \"mit_querstrebe\": true}")) (tu-eqf "geruest-traeger-strebe-cfg/standard" '(nil 30.0 25.0 500.0 100.0 250.0) - (geruest-traeger-strebe-cfg nil + (geruest-traeger-strebe-cfg _vmq (ssg-json-parse "{\"querstrebe\": {\"rand_min\": 100}}"))) (tu-eqf "geruest-traeger-strebe-cfg/dummy" '("s.dwg" 30.0 25.0 500.0 100.0 250.0) - (geruest-traeger-strebe-cfg nil + (geruest-traeger-strebe-cfg _vmq (ssg-json-parse "{\"querstrebe\": {\"dummy\": \"s.dwg\"}}"))) (tu-eqf "geruest-traeger-strebe-cfg/wert" '(nil 30.0 25.0 400.0 100.0 250.0) + (geruest-traeger-strebe-cfg _vmq + (ssg-json-parse "{\"querstrebe\": {\"abstand\": 400}}"))) + (tu-eqf "geruest-traeger-strebe-cfg/variante" '(nil 30.0 25.0 300.0 100.0 250.0) + (geruest-traeger-strebe-cfg + (ssg-json-parse + "{\"mit_querstrebe\": true, \"querstrebe\": {\"abstand\": 300}}") + (ssg-json-parse "{\"querstrebe\": {\"abstand\": 400}}"))) + (tu-nil "geruest-traeger-strebe-cfg/ohne-flag" + (geruest-traeger-strebe-cfg (ssg-json-parse "{\"name\": \"Rohr 1\"}") + (ssg-json-parse "{\"querstrebe\": {\"abstand\": 400}}"))) + (tu-nil "geruest-traeger-strebe-cfg/ohne-variante" (geruest-traeger-strebe-cfg nil (ssg-json-parse "{\"querstrebe\": {\"abstand\": 400}}"))) ;; Querlinien an Anfang und Ende der 30 mm langen Strebe (tu-eqf "geruest-traeger-strebe-enden" '(235.0 265.0) (geruest-traeger-strebe-enden 250.0 30.0)) (tu-nil "geruest-traeger-strebe-cfg/ohne" - (geruest-traeger-strebe-cfg nil (ssg-json-parse "{\"id\": \"X\"}"))) + (geruest-traeger-strebe-cfg _vmq (ssg-json-parse "{\"id\": \"X\"}"))) ;; Muffe nur bei "mit_muffe": true; Variante darf eigene Muffe mitbringen (setq _bgtest (ssg-json-parse "{\"muffe\": {\"dummy\": \"m.dwg\"}}")) (tu-eq "geruest-traeger-muffe-dummy/flag" "m.dwg" @@ -1271,13 +1455,8 @@ _bgtest "LAENGENABZUGENDE" "aktiv")) ;; --- Rohr-Geruest-Traeger in der echten Datendatei --- - ;; Eigene Datei data/json/geruest_traeger.json: im Bereichs-Dropdown von - ;; GERUEST darf er nicht auftauchen, ueber geruest-traeger-daten muss er - ;; auffindbar sein. - (setq _rec nil) - (foreach _e (geruest-baugruppen-liste) - (if (equal (car _e) "Traeger") (setq _rec T))) - (tu-nil "geruest/traeger-nicht-im-dropdown" _rec) + ;; Eigene Datei data/json/geruest_traeger.json: in geruest.json darf er + ;; nicht stehen, ueber geruest-traeger-daten muss er auffindbar sein. (tu-true "geruest/traeger-datei" (findfile (geruest-json-pfad "geruest_traeger.json"))) (setq _traeger (geruest-baugruppe "Traeger" (geruest-traeger-daten))) @@ -1297,12 +1476,26 @@ (geruest-attr-feld nil _traeger "LAENGE" "max")) (tu-eqf "geruest/traeger-querstrebe" '("dummy_Strebe_30x4.dwg" 30.0 25.0 500.0 100.0 250.0) - (geruest-traeger-strebe-cfg nil _traeger)) + (geruest-traeger-strebe-cfg _vmq _traeger)) + ;; Querstreben-Flag je Variante: alle ausser den beiden Rohr-1"-Varianten + (setq _rec 0) + (foreach _v (ssg-json-get _traeger "geometrie_varianten") + (if (geruest-traeger-strebe-cfg _v _traeger) (setq _rec (1+ _rec)))) + (tu-eq "geruest/traeger-querstreben-varianten" 6 _rec) + (tu-nil "geruest/traeger-rohr-ohne-querstrebe" + (geruest-traeger-strebe-cfg + (car (ssg-json-get _traeger "geometrie_varianten")) _traeger)) ;; Muffen-Flag ausdruecklich je Variante: genau die "mit (2) Muffe(n)" (setq _rec 0) (foreach _v (ssg-json-get _traeger "geometrie_varianten") (if (geruest-traeger-muffe-dummy _v _traeger) (setq _rec (1+ _rec)))) (tu-eq "geruest/traeger-muffen-varianten" 4 _rec) + ;; Dialog: ein Radiobutton je Variante, auch fuer die mit Muffe + (tu-eq "geruest/traeger-radiobuttons" 8 + (length (geruest-dcl-varianten-zeilen + (ssg-json-get _traeger "geometrie_varianten") + (geruest-indizes (length (ssg-json-get _traeger + "geometrie_varianten")))))) ;; Jede Variante definiert Beschriftungstext UND -layer selbst - der ;; Layer ist je Traegervariante verschieden, eine Vorgabe der ;; Baugruppe gibt es dafuer bewusst nicht. @@ -1327,6 +1520,44 @@ ) ) + ;; --- Omniflo-Fahrstrecke (data/json/omniflo_fahrstrecke.json) --- + ;; Gleiche Linien-Logik wie der Traeger: jede Variante ein Radiobutton, + ;; nur ST/STL gibt es mit Muffen, nur ST/STL sind farbig. + (setq _fs (geruest-baugruppe "Fahrstrecke" (geruest-fahrstrecke-daten))) + (tu-true "fahrstrecke/vorhanden" _fs) + (if _fs + (progn + (setq _rec (ssg-json-get _fs "geometrie_varianten")) + (tu-eq "fahrstrecke/titel" "Fahrstrecke" (geruest-titel _fs)) + (tu-eq "fahrstrecke/varianten" + '("AP 110" "APG 110" "AP 60" "ST" "ST mit Muffen" "STL" "STL mit Muffen") + (mapcar 'geruest-eintrag-name _rec)) + (tu-eq "fahrstrecke/mit-muffe" '("ST mit Muffen" "STL mit Muffen") + (mapcar 'geruest-eintrag-name + (vl-remove-if-not '(lambda (v) (ssg-json-get v "mit_muffe")) _rec))) + ;; AP 110 ohne "farbig" -> leerer TEILEFARBE-Eintrag, ST farbig + (tu-eq "fahrstrecke/ap110-nicht-farbig" '("") + (geruest-farbliste (geruest-teile-paare (nth 0 _rec) nil) "RAL7035")) + (tu-eq "fahrstrecke/st-farbig" '("RAL7035") + (geruest-farbliste + (geruest-teile-paare + (nth (geruest-name-index "ST" _rec) _rec) nil) + "RAL7035")) + ;; Keine Querstreben; Muffen-Dummy wie beim Traeger nur bei den + ;; Varianten mit "mit_muffe": true + (tu-nil "fahrstrecke/ohne-querstrebe" + (geruest-traeger-strebe-cfg (nth (geruest-name-index "ST" _rec) _rec) _fs)) + (tu-eq "fahrstrecke/muffe-dummy" "dummy_Muffe_1zoll.dwg" + (geruest-traeger-muffe-dummy + (nth (geruest-name-index "ST mit Muffen" _rec) _rec) _fs)) + (tu-nil "fahrstrecke/ohne-muffe-dummy" + (geruest-traeger-muffe-dummy + (nth (geruest-name-index "ST" _rec) _rec) _fs)) + ) + ) + (tu-true "fahrstrecke/dcl-vorlage" + (findfile (geruest-dcl-vorlage-pfad "fahrstrecke.dcl"))) + ;; --- Rundlauf Schreiber -> Parser --- ;; Prueft den Konfigurations-Schreiber ohne BricsCAD-Dialog. Bewusst in ;; eine temporaere Datei: ein Test darf cfg/geruest_user.json nicht @@ -1337,9 +1568,10 @@ (cons "variante" "ROHR R 1\" 33,7 x 2,6") (cons "laenge" "2000") (cons "teilefarbe" "RAL 7035 Lichtgrau") - (cons "oben" (list (list (cons "artikel" "ROHRKLAMMER 1\" KPL. VERTIKAL") - (cons "anzahl" 2)))) - (cons "unten" nil))) + (cons "befestigung" (list (list (cons "artikel" "ROHRKLAMMER 1\" KPL. VERTIKAL") + (cons "anzahl" 2)))) + (cons "sonstiges" nil) + (cons "winkel_platte" 90))) (setq _pfad (vl-filename-mktemp "grtest" nil ".json")) (setq _f (open _pfad "w")) (write-line "{ \"Test\": [" _f) @@ -1356,12 +1588,16 @@ (ssg-json-get _zurueck "laenge")) (tu-eq "geruest-schreiber/farbe" "RAL 7035 Lichtgrau" (ssg-json-get _zurueck "teilefarbe")) - (tu-eq "geruest-schreiber/oben-artikel" "ROHRKLAMMER 1\" KPL. VERTIKAL" - (ssg-json-get (car (ssg-json-get _zurueck "oben")) "artikel")) - (tu-eq "geruest-schreiber/oben-anzahl" 2 - (ssg-json-get (car (ssg-json-get _zurueck "oben")) "anzahl")) - (tu-eq "geruest-schreiber/unten-leer" nil - (ssg-json-get _zurueck "unten")) + (tu-eq "geruest-schreiber/befestigung-artikel" "ROHRKLAMMER 1\" KPL. VERTIKAL" + (ssg-json-get (car (ssg-json-get _zurueck "befestigung")) "artikel")) + (tu-eq "geruest-schreiber/befestigung-anzahl" 2 + (ssg-json-get (car (ssg-json-get _zurueck "befestigung")) "anzahl")) + (tu-eq "geruest-schreiber/sonstiges-leer" nil + (ssg-json-get _zurueck "sonstiges")) + (tu-eq "geruest-schreiber/winkel" 90 + (ssg-json-get _zurueck "winkel_platte")) + ;; altes Format wird nicht mehr geschrieben + (tu-nil "geruest-schreiber/ohne-oben" (assoc "oben" _zurueck)) ) ) ) @@ -1713,6 +1949,7 @@ (tu-eq "ssg-sl-klasse/vf" "ils_strecke" (car (ssg-sl-klasse "VF_2"))) (tu-eq "ssg-sl-klasse/gf" "ils_strecke" (car (ssg-sl-klasse "GF_1"))) (tu-eq "ssg-sl-klasse/geruest" "geruest" (car (ssg-sl-klasse "GR_Saeulen_20260101120000"))) + (tu-eq "ssg-sl-klasse/fahrstrecke" "fahrstrecke" (car (ssg-sl-klasse "GR_Fahrstrecke_20260101120000"))) (tu-eq "ssg-sl-klasse/ap60" "ap60" (car (ssg-sl-klasse "AP60_20260101120000"))) (tu-eq "ssg-sl-klasse/apg110" "apg110" (car (ssg-sl-klasse "APG110_20260101120000"))) (tu-eq "ssg-sl-klasse/ap110" "ap110" (car (ssg-sl-klasse "AP110_20260101120000")))