Merge branch 'master' of https://gitea.schoenenberger.de/Schoenenberger_Systeme_GmbH/dxfmakros
This commit is contained in:
@@ -75,6 +75,7 @@ Die `start_briscad.bat` ruft `setenv.bat` auf und startet BricsCAD.
|
||||
| VarioFoerderer | `VarioFoerderer` | FOERDERANLAGE, VARIOFOERDERER_EDIT, Vario_Kette_Merge |
|
||||
| Gefaellestrecke | `Gefaellestrecke` | GEFAELLESTRECKE, GEFAELLESTRECKE_EDIT |
|
||||
| Omniflo (komplett) | `OmniModulInsert` | OMNI_APB_*, OMNI_W*_*, OMNI_AP*, OMNI_TEF_*, OMNI_TV_*, OMNI_EDIT |
|
||||
| Geruest | `GeruestInsert` | GERUEST_ROHRABHAENGER, GERUEST_SAEULE_2ZOLL, GERUEST_SAEULE_1ZOLL, GERUEST_WANDBEFESTIGUNG |
|
||||
| Connections | `Connection_Edit` + `SSG_LIB_Commands` | CONNECTION_INSERT, CONNECTION_EDIT, ILS_EINGANG_INSERT, ILS_AUSGANG_INSERT |
|
||||
| Export | `export` | EXPORTSIVAS, EXPORTCSV, CALLPYTHON |
|
||||
| Konfiguration | `SSG_LIB_Commands` + `DrawPlanquadrate` | SSG_DIM_SWITCH, SSG_SPRACHE, PLANQUADRATE_TOGGLE (DRAW_PLANQUADRATE/DELETE_PLANQUADRATE) |
|
||||
@@ -92,7 +93,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_<dim>]` -> `[allgemein]`), `ssg-layer-anlegen` (Layer mit cfg-Farbe anlegen, optional aktivieren) und `ssg-layer-setzen` (Blockreferenz auf den Baugruppen-Layer legen) - fuer ZUSAMMENGEBAUTE Baugruppen; `ssg-block-layer-vorgabe` (LAYER-Attribut -> `ssg-ils-block-ebene`) fuer nur EINGEFUEGTE Bloecke. Alle liefern nil, wenn nichts konfiguriert ist, und lassen den Layer dann unangetastet |
|
||||
| `ssg_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_<dim>]` -> `[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_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) |
|
||||
@@ -106,6 +107,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_EDIT | Omniflo-Komponenten: Boegen, Weichen, Verbinder, Transferwagen, Edit-Dialog |
|
||||
| `SSG_LIB_Commands.lsp` | ILS_BTMT_Beladung, ILS_BTMT_Entladung, ILS_SCANNER_INSERT, ILS_SEPARATOR_INSERT, ILS_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_<DIM>.dwg`/`Ausgang_<DIM>.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_<Typ>`) fuer sps_skel (lib/tro_annotate.py): TRO_INSERT fuegt eine bestehende Blockdefinition an einem gewaehlten Punkt ein und setzt ID/TYPE (bricht ab, wenn der Typ noch keine Blockdefinition in der Zeichnung hat - die entsteht nur ueber tro_annotate.py); TRO_EDIT aendert ID/TYPE eines bestehenden Markers per Dialog. Typliste aus `tro_types.lsp` (von `tro_annotate.py --emit-lisp` nach DXFM_LISP geschrieben). Der Dispatcher SSG_BLOCKEDIT leitet Blocknamen `TRO_*` zu TRO_EDIT. |
|
||||
| `GeruestInsert.lsp` | GERUEST_ROHRABHAENGER, GERUEST_SAEULE_2ZOLL, GERUEST_SAEULE_1ZOLL, GERUEST_WANDBEFESTIGUNG | Geruest-Baugruppen aus `data/json/geruest.json` konfigurieren und einfuegen. Dialog (`dcl/geruest.dcl`): Basis-Variante aus `geometrie_varianten` (Dropdown), Anbauteile aus `anbaugruppen` (`list_box` mit `multiple_select` - im Projekt der erste), Laenge (gegen `attribute.Laenge` min/max geprueft, Retry-Schleife) und Farbe (`attribute.Farbe`, Freitext bei `frei_option`). Baugruppen ohne `attribute`-Block (Wandbefestigung) bekommen Laenge/Farbe gesperrt. 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*` (ARTINR, LAENGE, BEZEICHNUNG, TEILEART, FARBE, 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. Blockname `GR_<id>_<ssg-timestamp>` (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 `menge` es vorgibt (benannte Gruppen mit `teile` werden rekursiv aufgeloest); BEZEICHNUNG 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, FARBE/LAYER (+ ARTINR bei export_csv.py) im Merkmale-/details-JSON. Noch NICHT enthalten: Edit-Pfad (GERUEST_EDIT) |
|
||||
| `menu-inventory.lsp` | MenuInventory | BricsCAD Diagnostik (Menuegruppen, Plugins, Startdateien) |
|
||||
| `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). |
|
||||
|
||||
@@ -121,6 +123,7 @@ 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.dcl` | Alle GERUEST_*-Befehle (GeruestInsert.lsp, `geruest-dialog`) - ein Dialog fuer alle Baugruppen, Listen zur Laufzeit gefuellt |
|
||||
| `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` |
|
||||
|
||||
|
||||
@@ -0,0 +1,488 @@
|
||||
;; ============================================================
|
||||
;; GeruestInsert.lsp - Geruest-Baugruppen konfigurieren und einfuegen
|
||||
;;
|
||||
;; Liest data/json/geruest.json (rekursiv per ssg-json-laden),
|
||||
;; laesst den Nutzer im Dialog dcl/geruest.dcl eine Basis-Variante, beliebige
|
||||
;; Anbauteile, Laenge und Farbe waehlen, und fuegt das Ergebnis als Block
|
||||
;; GR_<id>_<Zeitstempel> ein.
|
||||
;;
|
||||
;; Der Block wird - wie KREISEL_n/VF_n - selbst zusammengebaut: die Dummy-DWG
|
||||
;; aus data/geruest liefert nur die Geometrie, das Attribut-Schema kommt aus
|
||||
;; *geruest-attrib-defs*. Damit kann kein Attribut still verlorengehen, wenn
|
||||
;; die Dummy-DWG einen Tag nicht kennt (ssg-attrib-set-on schreibt nur Tags,
|
||||
;; die als ATTDEF existieren).
|
||||
;;
|
||||
;; Das GR_-Praefix ist nicht kosmetisch: SSG_BLOCKEDIT haelt jeden Block mit
|
||||
;; TEILEART-Attribut fuer ein Omniflo-Element (SSG_LIB_Commands.lsp). Der
|
||||
;; Doppelklick-Dispatcher erkennt Geruest-Bloecke an diesem Praefix.
|
||||
;;
|
||||
;; Befehle: GERUEST_ROHRABHAENGER, GERUEST_SAEULE_2ZOLL,
|
||||
;; GERUEST_SAEULE_1ZOLL, GERUEST_WANDBEFESTIGUNG
|
||||
;; ============================================================
|
||||
|
||||
(vl-load-com)
|
||||
|
||||
;; Attribut-Schema des Wrapper-Blocks. Die Dummy-DWG darf eigene Tags
|
||||
;; mitbringen - die bleiben erhalten (ssg-attrib-merge).
|
||||
;; "ID" (leer vorbelegt, wie bei Kreisel/VF_n/GF_n) ist Voraussetzung dafuer,
|
||||
;; dass ssg-id-check-all dem Block ueberhaupt eine ID zuweisen kann -
|
||||
;; ssg-attrib-set-on schreibt nur auf ein bereits vorhandenes ATTDEF, siehe
|
||||
;; oben. Ohne diesen Eintrag bliebe ID fuer immer leer (csv:read-attribs
|
||||
;; exportiert dann eben kein "ID"-Feld statt eines Werts).
|
||||
(if (null *geruest-attrib-defs*)
|
||||
(setq *geruest-attrib-defs*
|
||||
'(("ID" "")
|
||||
("ARTINR" "")
|
||||
("LAENGE" "")
|
||||
("BEZEICHNUNG" "")
|
||||
("TEILEART" "")
|
||||
("FARBE" "")
|
||||
("LAYER" "")
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(if (null *geruest-block-counter*) (setq *geruest-block-counter* 0))
|
||||
|
||||
|
||||
;; ============================================================
|
||||
;; DATEN
|
||||
;; ============================================================
|
||||
|
||||
(defun geruest-data-verzeichnis ( / )
|
||||
(cond
|
||||
((getenv "DXFM_DATA") (vl-string-translate "\\" "/" (getenv "DXFM_DATA")))
|
||||
((getenv "DXFMAKRO")
|
||||
(strcat (vl-string-translate "\\" "/" (getenv "DXFMAKRO")) "/data"))
|
||||
)
|
||||
)
|
||||
|
||||
(defun geruest-json-pfad ( / basis)
|
||||
(if (setq basis (geruest-data-verzeichnis))
|
||||
(strcat basis "/json/geruest.json")
|
||||
)
|
||||
)
|
||||
|
||||
(defun geruest-dummy-pfad (datei / basis)
|
||||
(if (and datei (setq basis (geruest-data-verzeichnis)))
|
||||
(strcat basis "/geruest/" datei)
|
||||
)
|
||||
)
|
||||
|
||||
;; Datendatei einmal je Zeichnungssitzung laden.
|
||||
(defun geruest-daten ( / pfad)
|
||||
(if (null *geruest-daten*)
|
||||
(progn
|
||||
(setq pfad (geruest-json-pfad))
|
||||
(cond
|
||||
((null pfad) (princ (ssg-text "gr-fehler-datenpfad")))
|
||||
((null (findfile pfad)) (princ (ssg-textf "gr-fehler-json-fehlt" (list pfad))))
|
||||
(T
|
||||
(setq *geruest-daten* (ssg-json-laden pfad))
|
||||
(if (null *geruest-daten*)
|
||||
(princ (ssg-textf "gr-fehler-json-lesbar" (list pfad)))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
*geruest-daten*
|
||||
)
|
||||
|
||||
;; Baugruppe ueber ihr ASCII-Feld "id" suchen. Der aeussere JSON-Schluessel
|
||||
;; ("Rohrabhaenger" mit Umlaut, "2\" Saeulen" mit Anfuehrungszeichen) taugt
|
||||
;; dafuer nicht - er ist aus ASCII-Quelltext nicht vergleichbar.
|
||||
(defun geruest-baugruppe (id / erg)
|
||||
(foreach eintrag (geruest-daten)
|
||||
;; equal statt = : fehlt einer Baugruppe das id-Feld, liefert ssg-json-get
|
||||
;; nil - = ist mit nil-Argumenten nicht zuverlaessig.
|
||||
(if (and (null erg)
|
||||
(listp (cdr eintrag))
|
||||
(equal (ssg-json-get (cdr eintrag) "id") id))
|
||||
(setq erg (cdr eintrag))
|
||||
)
|
||||
)
|
||||
erg
|
||||
)
|
||||
|
||||
|
||||
;; ============================================================
|
||||
;; TEILE AUSWERTEN
|
||||
;; ============================================================
|
||||
|
||||
;; Anzeigename eines Eintrags: benannte Gruppe ("name") oder Einzelteil
|
||||
;; ("artikel").
|
||||
(defun geruest-eintrag-name (eintrag / n)
|
||||
(setq n (ssg-json-get eintrag "name"))
|
||||
(if (and n (= (type n) 'STR) (/= n ""))
|
||||
n
|
||||
(ssg-json-get eintrag "artikel")
|
||||
)
|
||||
)
|
||||
|
||||
(defun geruest-menge (eintrag / m)
|
||||
(setq m (ssg-json-get eintrag "menge"))
|
||||
(if (and m (numberp m) (> m 0)) (fix m) 1)
|
||||
)
|
||||
|
||||
;; Sivas-ID als String. Im JSON stehen rein numerische IDs als Zahl
|
||||
;; (Projektkonvention), zusammengesetzte Codes waeren Strings.
|
||||
(defun geruest-id-string (wert)
|
||||
(cond
|
||||
((null wert) nil)
|
||||
((= (type wert) 'STR) wert)
|
||||
((= (type wert) 'INT) (itoa wert))
|
||||
((= (type wert) 'REAL) (rtos wert 2 0))
|
||||
)
|
||||
)
|
||||
|
||||
(defun geruest-wiederholen (wert n / erg i)
|
||||
(setq erg nil i 0)
|
||||
(if wert
|
||||
(while (< i n)
|
||||
(setq erg (cons wert erg))
|
||||
(setq i (1+ i))
|
||||
)
|
||||
)
|
||||
erg
|
||||
)
|
||||
|
||||
;; Alle Artikelnummern eines Eintrags, jede gemaess "menge" wiederholt.
|
||||
;; Benannte Gruppen ("teile") werden rekursiv aufgeloest.
|
||||
(defun geruest-artikelnummern (eintrag / erg teile)
|
||||
(setq erg nil)
|
||||
(setq teile (ssg-json-get eintrag "teile"))
|
||||
(if teile
|
||||
(foreach teil teile
|
||||
(setq erg (append erg (geruest-artikelnummern teil)))
|
||||
)
|
||||
(setq erg (geruest-wiederholen
|
||||
(geruest-id-string (ssg-json-get eintrag "sivas_id"))
|
||||
(geruest-menge eintrag)))
|
||||
)
|
||||
erg
|
||||
)
|
||||
|
||||
|
||||
;; ============================================================
|
||||
;; DIALOG
|
||||
;; ============================================================
|
||||
|
||||
;; "0 3 5" -> (0 3 5). Rueckgabe von get_tile bei multiple_select.
|
||||
(defun geruest-indizes (s / erg tok i c)
|
||||
(setq erg nil tok "" i 1)
|
||||
(if (null s) (setq s ""))
|
||||
(while (<= i (strlen s))
|
||||
(setq c (substr s i 1))
|
||||
(if (= c " ")
|
||||
(progn
|
||||
(if (/= tok "") (setq erg (cons (atoi tok) erg)))
|
||||
(setq tok "")
|
||||
)
|
||||
(setq tok (strcat tok c))
|
||||
)
|
||||
(setq i (1+ i))
|
||||
)
|
||||
(if (/= tok "") (setq erg (cons (atoi tok) erg)))
|
||||
(reverse erg)
|
||||
)
|
||||
|
||||
;; Dialog zeigen. Rueckgabe:
|
||||
;; (variante-index (anbau-indizes) laenge-string farbe-string) oder nil
|
||||
(defun geruest-dialog (bg / dcl-pfad dat varianten anbauteile attr laenge-def
|
||||
farb-opts frei-opt fertig rueckgabe ergebnis
|
||||
dlg-variante dlg-anbau dlg-laenge dlg-farbe dlg-frei
|
||||
min-l max-l wert-l farbe-txt)
|
||||
(setq dcl-pfad (strcat (getenv "DXFM_DCL") "/geruest.dcl"))
|
||||
(setq varianten (ssg-json-get bg "geometrie_varianten"))
|
||||
(setq anbauteile (ssg-json-get bg "anbaugruppen"))
|
||||
(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 "Farbe")))
|
||||
(setq min-l (if laenge-def (ssg-json-get laenge-def "min")))
|
||||
(setq max-l (if laenge-def (ssg-json-get laenge-def "max")))
|
||||
|
||||
;; Farboptionen + freie Option ans Listenende; Index davon merkt sich der
|
||||
;; Callback, um das Freitextfeld freizuschalten.
|
||||
(setq *geruest-farb-liste* nil *geruest-frei-idx* -1)
|
||||
(if farb-opts
|
||||
(progn
|
||||
(setq *geruest-farb-liste* (ssg-json-get farb-opts "optionen"))
|
||||
(if (ssg-json-get farb-opts "frei_erlaubt")
|
||||
(progn
|
||||
(setq frei-opt (ssg-json-get farb-opts "frei_option"))
|
||||
(if (null frei-opt) (setq frei-opt "Individuell"))
|
||||
(setq *geruest-frei-idx* (length *geruest-farb-liste*))
|
||||
(setq *geruest-farb-liste*
|
||||
(append *geruest-farb-liste* (list frei-opt)))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(setq dlg-variante "0" dlg-anbau "" dlg-laenge "" dlg-farbe "0" dlg-frei "")
|
||||
(setq fertig nil rueckgabe nil)
|
||||
|
||||
;; Schleife, damit der Dialog nach einer ungueltigen Laenge mit den
|
||||
;; bisherigen Eingaben erneut erscheint (Projektmuster, vgl. vf_linienzug).
|
||||
(while (not fertig)
|
||||
(setq dat (load_dialog dcl-pfad))
|
||||
(if (or (< dat 0) (not (new_dialog "geruest" dat)))
|
||||
(progn
|
||||
(alert (ssg-text "gr-fehler-dcl"))
|
||||
(setq fertig T)
|
||||
)
|
||||
(progn
|
||||
(set_tile "kopf" (ssg-textf "gr-dlg-kopf"
|
||||
(list (ssg-json-get bg "teileart"))))
|
||||
|
||||
(start_list "variante")
|
||||
(foreach v varianten (add_list (geruest-eintrag-name v)))
|
||||
(end_list)
|
||||
(set_tile "variante" dlg-variante)
|
||||
|
||||
(start_list "anbau")
|
||||
(foreach a anbauteile (add_list (geruest-eintrag-name a)))
|
||||
(end_list)
|
||||
(if (/= dlg-anbau "") (set_tile "anbau" dlg-anbau))
|
||||
|
||||
;; Laenge/Farbe nur bei Baugruppen mit "attribute"-Block
|
||||
(if laenge-def
|
||||
(set_tile "laenge" dlg-laenge)
|
||||
(mode_tile "laenge" 1)
|
||||
)
|
||||
(if *geruest-farb-liste*
|
||||
(progn
|
||||
(start_list "farbe")
|
||||
(foreach f *geruest-farb-liste* (add_list f))
|
||||
(end_list)
|
||||
(set_tile "farbe" dlg-farbe)
|
||||
(set_tile "farbe_frei" dlg-frei)
|
||||
(mode_tile "farbe_frei"
|
||||
(if (= (atoi dlg-farbe) *geruest-frei-idx*) 0 1))
|
||||
(action_tile "farbe"
|
||||
"(mode_tile \"farbe_frei\" (if (= (atoi $value) *geruest-frei-idx*) 0 1))")
|
||||
)
|
||||
(progn
|
||||
(mode_tile "farbe" 1)
|
||||
(mode_tile "farbe_frei" 1)
|
||||
)
|
||||
)
|
||||
|
||||
(action_tile "accept"
|
||||
(strcat "(setq dlg-variante (get_tile \"variante\"))"
|
||||
"(setq dlg-anbau (get_tile \"anbau\"))"
|
||||
"(setq dlg-laenge (get_tile \"laenge\"))"
|
||||
"(setq dlg-farbe (get_tile \"farbe\"))"
|
||||
"(setq dlg-frei (get_tile \"farbe_frei\"))"
|
||||
"(done_dialog 1)"))
|
||||
(action_tile "cancel" "(done_dialog 0)")
|
||||
(setq ergebnis (start_dialog))
|
||||
(unload_dialog dat)
|
||||
|
||||
(cond
|
||||
((/= ergebnis 1) (setq fertig T))
|
||||
;; Laenge pruefen - Bereichspruefung erfolgt im Projekt immer nach
|
||||
;; done_dialog, DCL kann das nicht.
|
||||
((and laenge-def
|
||||
(progn (setq wert-l (atof dlg-laenge))
|
||||
(or (= (ssg-cfg-trim dlg-laenge) "")
|
||||
(and min-l (< wert-l min-l))
|
||||
(and max-l (> wert-l max-l)))))
|
||||
(alert (ssg-textf "gr-alert-laenge"
|
||||
(list dlg-laenge
|
||||
(if min-l (rtos min-l 2 0) "0")
|
||||
(if max-l (rtos max-l 2 0) "-"))))
|
||||
)
|
||||
(T
|
||||
(setq farbe-txt
|
||||
(cond
|
||||
((null *geruest-farb-liste*) "")
|
||||
((= (atoi dlg-farbe) *geruest-frei-idx*) dlg-frei)
|
||||
(T (nth (atoi dlg-farbe) *geruest-farb-liste*))
|
||||
)
|
||||
)
|
||||
(setq rueckgabe (list (atoi dlg-variante)
|
||||
(geruest-indizes dlg-anbau)
|
||||
(if laenge-def dlg-laenge "")
|
||||
(if farbe-txt farbe-txt "")))
|
||||
(setq fertig T)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
rueckgabe
|
||||
)
|
||||
|
||||
|
||||
;; ============================================================
|
||||
;; BLOCK BAUEN UND EINFUEGEN
|
||||
;; ============================================================
|
||||
|
||||
;; Eindeutiger Blockname. ssg-timestamp hat Sekundenaufloesung - bei zwei
|
||||
;; Aufrufen in derselben Sekunde wird ein Zaehler angehaengt (Muster aus
|
||||
;; OmniModulInsert.lsp).
|
||||
(defun geruest-blockname (id / bname)
|
||||
(setq bname (strcat "GR_" id "_" (ssg-timestamp)))
|
||||
(while (tblsearch "BLOCK" bname)
|
||||
(setq *geruest-block-counter* (1+ *geruest-block-counter*))
|
||||
(setq bname (strcat "GR_" id "_" (ssg-timestamp) "_"
|
||||
(itoa *geruest-block-counter*)))
|
||||
)
|
||||
bname
|
||||
)
|
||||
|
||||
;; Dummy-Geometrie + eigene ATTDEFs zu einem Block zusammenfassen und am
|
||||
;; gewaehlten Punkt einfuegen. werte = alist der berechneten Attributwerte.
|
||||
;; Rueckgabe: (blockname . entity) oder nil.
|
||||
(defun geruest-block-bauen (bg werte pt / datei dummy lastEnt dummyEnt e ss
|
||||
bname blockEnt dummy-attribs attribs)
|
||||
(setq datei (ssg-json-get bg "dummy"))
|
||||
(setq dummy (geruest-dummy-pfad datei))
|
||||
(if (or (null dummy) (null (findfile dummy)))
|
||||
(progn
|
||||
(princ (ssg-textf "gr-fehler-dummy" (list (if dummy dummy datei))))
|
||||
nil
|
||||
)
|
||||
(progn
|
||||
(setvar "ATTREQ" 0)
|
||||
(setvar "ATTDIA" 0)
|
||||
(setvar "OSMODE" 0)
|
||||
(setq lastEnt (entlast))
|
||||
|
||||
;; Dummy bei (0,0,0) einfuegen - seine Attribute liefern u.a. die
|
||||
;; LAYER-Vorgabe.
|
||||
(command "_.INSERT" dummy (list 0.0 0.0 0.0) 1 1 0)
|
||||
(setq dummyEnt (entlast))
|
||||
(setq dummy-attribs (ssg-attrib-read dummyEnt))
|
||||
|
||||
;; Unser Schema gewinnt an Struktur, die Dummy-Werte an Inhalt:
|
||||
;; ssg-attrib-merge legt alle Tags aus *geruest-attrib-defs* an und
|
||||
;; uebernimmt zusaetzlich alle Tags der Dummy-DWG.
|
||||
(setq attribs (ssg-attrib-merge dummy-attribs *geruest-attrib-defs*))
|
||||
(foreach paar werte
|
||||
(if (assoc (car paar) attribs)
|
||||
(setq attribs (subst paar (assoc (car paar) attribs) attribs))
|
||||
(setq attribs (append attribs (list paar)))
|
||||
)
|
||||
)
|
||||
|
||||
(ssg-attrib-make-defs (ssg-attrib-alist-to-defs attribs) 50.0)
|
||||
|
||||
;; Alles Neue seit lastEnt einsammeln (Dummy-INSERT + ATTDEFs)
|
||||
(setq ss (ssadd))
|
||||
(setq e (if lastEnt (entnext lastEnt) (entnext)))
|
||||
(while e
|
||||
(ssadd e ss)
|
||||
(setq e (entnext e))
|
||||
)
|
||||
|
||||
(setq bname (geruest-blockname (ssg-json-get bg "id")))
|
||||
(command "_.-BLOCK" bname (list 0.0 0.0 0.0) ss "")
|
||||
|
||||
;; Stand VOR dem Einfuegen merken: bricht der Nutzer die Drehung mit ESC
|
||||
;; ab, entsteht kein neues INSERT und (entlast) zeigt auf ein voellig
|
||||
;; fremdes Objekt - ohne diesen Vergleich wuerden dessen Attribute
|
||||
;; ueberschrieben.
|
||||
(setq lastEnt (entlast))
|
||||
;; pause = Drehwinkel interaktiv am Cursor
|
||||
(command "_.INSERT" bname pt 1 1 pause)
|
||||
;; Laufende Einfuegung sicher beenden (z.B. ESC waehrend der Drehung)
|
||||
(if (> (getvar "CMDACTIVE") 0) (command))
|
||||
(if (> (getvar "CMDACTIVE") 0) (command))
|
||||
|
||||
(setq blockEnt (entlast))
|
||||
(if (and blockEnt (not (eq blockEnt lastEnt))
|
||||
(= (cdr (assoc 0 (entget blockEnt))) "INSERT"))
|
||||
(progn
|
||||
(ssg-attrib-set-on blockEnt attribs)
|
||||
(ssg-block-layer-vorgabe blockEnt bname attribs)
|
||||
(cons bname blockEnt)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
;; ============================================================
|
||||
;; ABLAUF
|
||||
;; ============================================================
|
||||
|
||||
(defun geruest-run (id / bg wahl varianten anbauteile variante gewaehlt
|
||||
artnr bezeichnung teile-namen werte pt ergebnis)
|
||||
(setq bg (geruest-baugruppe id))
|
||||
(cond
|
||||
((null bg)
|
||||
(if (geruest-daten) (princ (ssg-textf "gr-fehler-baugruppe" (list id))))
|
||||
)
|
||||
((null (setq varianten (ssg-json-get bg "geometrie_varianten")))
|
||||
(princ (ssg-textf "gr-fehler-keine-varianten" (list id)))
|
||||
)
|
||||
(T
|
||||
(setq anbauteile (ssg-json-get bg "anbaugruppen"))
|
||||
(setq wahl (geruest-dialog bg))
|
||||
(if (null wahl)
|
||||
(princ (ssg-text "gr-abgebrochen"))
|
||||
(progn
|
||||
(setq variante (nth (car wahl) varianten))
|
||||
(setq gewaehlt nil)
|
||||
(foreach i (cadr wahl)
|
||||
(if (< i (length anbauteile))
|
||||
(setq gewaehlt (append gewaehlt (list (nth i anbauteile))))
|
||||
)
|
||||
)
|
||||
|
||||
;; ARTINR: jede Sivas-ID so oft, wie "menge" es vorgibt
|
||||
(setq artnr (geruest-artikelnummern variante))
|
||||
(foreach a gewaehlt
|
||||
(setq artnr (append artnr (geruest-artikelnummern a)))
|
||||
)
|
||||
|
||||
;; BEZEICHNUNG: mit " + " verketten - die Artikelbezeichnungen
|
||||
;; enthalten selbst Kommas ("ROHR R 1\" 33,7 x 2,6").
|
||||
(setq teile-namen (list (ssg-json-get bg "teileart")
|
||||
(geruest-eintrag-name variante)))
|
||||
(foreach a gewaehlt
|
||||
(setq teile-namen (append teile-namen
|
||||
(list (geruest-eintrag-name a))))
|
||||
)
|
||||
(setq bezeichnung (ssg-join teile-namen " + "))
|
||||
|
||||
(setq werte (list (cons "ARTINR" (ssg-join artnr ","))
|
||||
(cons "BEZEICHNUNG" bezeichnung)
|
||||
(cons "TEILEART" (ssg-json-get bg "teileart"))))
|
||||
(if (/= (caddr wahl) "")
|
||||
(setq werte (append werte (list (cons "LAENGE" (caddr wahl))))))
|
||||
(if (/= (cadddr wahl) "")
|
||||
(setq werte (append werte (list (cons "FARBE" (cadddr wahl))))))
|
||||
|
||||
(setq pt (getpoint (ssg-text "gr-prompt-einfuegepunkt")))
|
||||
(if (null pt)
|
||||
(princ (ssg-text "gr-abgebrochen"))
|
||||
(progn
|
||||
(ssg-start "Geruest" '(("OSMODE") ("ATTREQ") ("ATTDIA")))
|
||||
(setq ergebnis (geruest-block-bauen bg werte pt))
|
||||
(ssg-end)
|
||||
(if ergebnis
|
||||
(princ (ssg-textf "gr-fertig"
|
||||
(list (ssg-json-get bg "teileart") (car ergebnis))))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(princ)
|
||||
)
|
||||
|
||||
|
||||
(defun c:GERUEST_ROHRABHAENGER () (geruest-run "Rohrabhaenger"))
|
||||
(defun c:GERUEST_SAEULE_2ZOLL () (geruest-run "Saeulen_2Zoll"))
|
||||
(defun c:GERUEST_SAEULE_1ZOLL () (geruest-run "Saeulen_1Zoll"))
|
||||
(defun c:GERUEST_WANDBEFESTIGUNG () (geruest-run "Wandbefestigung"))
|
||||
|
||||
(princ "\nGeruestInsert.lsp geladen. Befehle: GERUEST_ROHRABHAENGER, GERUEST_SAEULE_2ZOLL, GERUEST_SAEULE_1ZOLL, GERUEST_WANDBEFESTIGUNG")
|
||||
(princ)
|
||||
@@ -400,6 +400,14 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; Geruest-Baugruppen -> nativer Attribut-Editor.
|
||||
;; MUSS vor dem Omniflo-Zweig stehen: Geruest-Bloecke tragen ein
|
||||
;; TEILEART-Attribut und wuerden dort sonst als Omniflo-Element erkannt.
|
||||
((wcmatch bname "GR_*")
|
||||
(princ (ssg-textf "cmd-attribute-bearbeiten" (list bname)))
|
||||
(command "_.EATTEDIT")
|
||||
)
|
||||
|
||||
;; Omniflo-Bloecke -> OMNI_EDIT
|
||||
;; Erkennung: TEILEART-Attribut vorhanden, AP110-Blockname oder rein numerisch
|
||||
((progn
|
||||
|
||||
+13
-2
@@ -198,12 +198,18 @@
|
||||
|
||||
;; --- String fuer JSON escapen (Anfuehrungszeichen/Backslash) ---
|
||||
;; Konvertiert nicht-String-Werte (z.B. T, nil, Zahlen) defensiv in String.
|
||||
;; ssg-str-replace-all (ssg_lang.lsp) statt vl-string-subst: vl-string-subst
|
||||
;; ersetzt nur das ERSTE Vorkommen, nicht alle - bei einem Attributwert mit
|
||||
;; MEHREREN Anfuehrungszeichen (z.B. BEZEICHNUNG einer Geruest-Baugruppe mit
|
||||
;; zwei Zoll-Angaben wie 'F. 2" UND 1" ROHR') blieb das zweite Vorkommen
|
||||
;; unescaped stehen und brach die JSON-Struktur beim Python-Parsen (realer
|
||||
;; Bug, behoben) - export_raw.json/EXPORTCSV.
|
||||
(defun csv:json-escape (s)
|
||||
(if (not (= (type s) 'STR))
|
||||
(setq s (if s (vl-princ-to-string s) ""))
|
||||
)
|
||||
(setq s (vl-string-subst "\\\\" "\\" s))
|
||||
(vl-string-subst "\\\"" "\"" s)
|
||||
(setq s (ssg-str-replace-all "\\\\" "\\" s))
|
||||
(ssg-str-replace-all "\\\"" "\"" s)
|
||||
)
|
||||
|
||||
|
||||
@@ -1082,6 +1088,10 @@
|
||||
;; ils-insert-station in SSG_LIB_Commands.lsp). Anders als Separator/
|
||||
;; Scanner werden sie von KEINEM anderen Element mitgezaehlt - export_csv.py
|
||||
;; UND export_sivas.py fuehren sie beide als eigene TeileArt-Zeilen.
|
||||
;; GR_* = Geruest-Baugruppen (siehe pattern_geruest in cfg/export.cfg,
|
||||
;; GeruestInsert.lsp). Wie BTMT eigenstaendig und von keinem anderen
|
||||
;; Element mitgezaehlt - export_csv.py UND export_sivas.py fuehren sie
|
||||
;; beide als eigene TeileArt-Zeilen.
|
||||
;; Gibt Auswahlsatz zurueck oder nil.
|
||||
(defun csv:collect-export-blocks ( / ss-all ss-out i ename ed bname)
|
||||
(setq ss-all (ssget "X" (list (cons 0 "INSERT"))))
|
||||
@@ -1101,6 +1111,7 @@
|
||||
(wcmatch bname (export:pattern "pattern_scanner" "Scanner*"))
|
||||
(wcmatch bname (export:pattern "pattern_btmt_beladung" "BTMT-Beladung*"))
|
||||
(wcmatch bname (export:pattern "pattern_btmt_entladung" "SC_Entladung*"))
|
||||
(wcmatch bname (export:pattern "pattern_geruest" "GR_*"))
|
||||
;; Rein numerische Namen = Omniflo SivasNr (Boegen/Weichen)
|
||||
;; Rein LISP-intern (Python klassifiziert Omniflo stattdessen
|
||||
;; ueber exakten Katalog-Match), daher fest im Code statt in
|
||||
|
||||
@@ -1561,6 +1561,213 @@
|
||||
)
|
||||
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; STRING-LISTE VERKETTEN
|
||||
;; ------------------------------------------------------------
|
||||
;; (ssg-join '("a" "b" "c") ",") -> "a,b,c"; leere Liste -> "".
|
||||
;; Alle Elemente muessen Strings sein (Zahlen vorher mit itoa/rtos wandeln).
|
||||
(defun ssg-join (lst sep / s erst)
|
||||
(setq s "" erst T)
|
||||
(foreach x lst
|
||||
(if erst
|
||||
(setq s x erst nil)
|
||||
(setq s (strcat s sep x))
|
||||
)
|
||||
)
|
||||
s
|
||||
)
|
||||
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; REKURSIVER JSON-PARSER
|
||||
;; ------------------------------------------------------------
|
||||
;; Ergaenzung zu ssg-parse-json-array/ssg-cfg-parse-nested, die BEIDE
|
||||
;; zeilenbasiert und flach arbeiten und daher prinzipiell weder echte
|
||||
;; Verschachtelung noch mehrzeilige Arrays, maskierte Anfuehrungszeichen
|
||||
;; (\") oder Kommas innerhalb von Strings lesen koennen. Die beiden alten
|
||||
;; Parser bleiben unveraendert - ihre Konsumenten (Konfiguration, Sprache,
|
||||
;; VF-Spec) sind auf ihr Verhalten eingestellt.
|
||||
;;
|
||||
;; Abbildung: Objekt -> Alist (("key" . wert) ...), Array -> Liste,
|
||||
;; String -> STR, Zahl -> INT/REAL, true -> T, false/null -> nil.
|
||||
;; Da false und null beide nil ergeben, ist "Feld fehlt" nicht von
|
||||
;; "Feld ist false" unterscheidbar.
|
||||
;; \uXXXX wird nur fuer ASCII (< 128) aufgeloest, sonst "?" - echte
|
||||
;; Umlaute stehen in unseren Daten direkt als UTF-8 in der Datei.
|
||||
|
||||
(defun ssg-json-zeichen ( / )
|
||||
(if (<= *ssg-json-pos* *ssg-json-len*)
|
||||
(substr *ssg-json-txt* *ssg-json-pos* 1)
|
||||
)
|
||||
)
|
||||
|
||||
(defun ssg-json-weiter ( / )
|
||||
(setq *ssg-json-pos* (1+ *ssg-json-pos*))
|
||||
)
|
||||
|
||||
(defun ssg-json-leerraum ( / c)
|
||||
(while (and (setq c (ssg-json-zeichen))
|
||||
(member c '(" " "\t" "\r" "\n")))
|
||||
(ssg-json-weiter)
|
||||
)
|
||||
)
|
||||
|
||||
;; String ab dem oeffnenden Anfuehrungszeichen lesen, Escapes aufloesen.
|
||||
(defun ssg-json-string ( / c erg fertig code)
|
||||
(ssg-json-weiter)
|
||||
(setq erg "" fertig nil)
|
||||
(while (and (not fertig) (setq c (ssg-json-zeichen)))
|
||||
(cond
|
||||
((= c "\"") (setq fertig T) (ssg-json-weiter))
|
||||
((= c "\\")
|
||||
(ssg-json-weiter)
|
||||
(setq c (ssg-json-zeichen))
|
||||
;; equal statt = : nach dem Backslash kann das Textende erreicht sein
|
||||
;; (c = nil), und = ist mit nil-Argumenten nicht zuverlaessig.
|
||||
(cond
|
||||
((equal c "n") (setq erg (strcat erg "\n")) (ssg-json-weiter))
|
||||
((equal c "t") (setq erg (strcat erg "\t")) (ssg-json-weiter))
|
||||
((equal c "r") (setq erg (strcat erg "\r")) (ssg-json-weiter))
|
||||
;; AutoLISP kennt nur \\ \" \e \n \r \t - Backspace/Seitenvorschub
|
||||
;; daher ueber chr statt als Escape-Literal.
|
||||
((equal c "b") (setq erg (strcat erg (chr 8))) (ssg-json-weiter))
|
||||
((equal c "f") (setq erg (strcat erg (chr 12))) (ssg-json-weiter))
|
||||
((equal c "u")
|
||||
(ssg-json-weiter)
|
||||
(setq code (ssg-json-hex4))
|
||||
(setq erg (strcat erg (if (< code 128) (chr code) "?")))
|
||||
)
|
||||
;; \" \\ \/ und alles andere: Zeichen unveraendert uebernehmen
|
||||
(c (setq erg (strcat erg c)) (ssg-json-weiter))
|
||||
)
|
||||
)
|
||||
(T (setq erg (strcat erg c)) (ssg-json-weiter))
|
||||
)
|
||||
)
|
||||
erg
|
||||
)
|
||||
|
||||
;; Vier Hex-Ziffern lesen und als Zahl liefern (Position rueckt mit).
|
||||
(defun ssg-json-hex4 ( / i c code ziffer)
|
||||
(setq code 0 i 0)
|
||||
(while (< i 4)
|
||||
(setq c (ssg-json-zeichen))
|
||||
(if c
|
||||
(progn
|
||||
(setq ziffer
|
||||
(cond
|
||||
((and (>= (ascii c) 48) (<= (ascii c) 57)) (- (ascii c) 48))
|
||||
((and (>= (ascii c) 97) (<= (ascii c) 102)) (+ 10 (- (ascii c) 97)))
|
||||
((and (>= (ascii c) 65) (<= (ascii c) 70)) (+ 10 (- (ascii c) 65)))
|
||||
(T 0)
|
||||
)
|
||||
)
|
||||
(setq code (+ (* code 16) ziffer))
|
||||
(ssg-json-weiter)
|
||||
)
|
||||
(setq i 4)
|
||||
)
|
||||
(setq i (1+ i))
|
||||
)
|
||||
code
|
||||
)
|
||||
|
||||
;; Zahl bzw. true/false/null bis zum naechsten Trennzeichen lesen.
|
||||
(defun ssg-json-literal ( / start s c)
|
||||
(setq start *ssg-json-pos*)
|
||||
(while (and (setq c (ssg-json-zeichen))
|
||||
(not (member c '("," "}" "]" " " "\t" "\r" "\n"))))
|
||||
(ssg-json-weiter)
|
||||
)
|
||||
(setq s (substr *ssg-json-txt* start (- *ssg-json-pos* start)))
|
||||
(cond
|
||||
((= s "true") T)
|
||||
((= s "false") nil)
|
||||
((= s "null") nil)
|
||||
((vl-string-search "." s) (atof s))
|
||||
(T (atoi s))
|
||||
)
|
||||
)
|
||||
|
||||
(defun ssg-json-objekt ( / erg key c vorher)
|
||||
(ssg-json-weiter)
|
||||
(setq erg nil)
|
||||
(ssg-json-leerraum)
|
||||
(while (and (setq c (ssg-json-zeichen)) (/= c "}"))
|
||||
(setq vorher *ssg-json-pos*)
|
||||
(if (= c "\"")
|
||||
(progn
|
||||
(setq key (ssg-json-string))
|
||||
(ssg-json-leerraum)
|
||||
(if (equal (ssg-json-zeichen) ":") (ssg-json-weiter))
|
||||
(setq erg (cons (cons key (ssg-json-wert)) erg))
|
||||
)
|
||||
;; Komma oder unerwartetes Zeichen ueberspringen
|
||||
(ssg-json-weiter)
|
||||
)
|
||||
(ssg-json-leerraum)
|
||||
;; Schutz gegen Endlosschleife bei fehlerhafter Datei: kommt die Position
|
||||
;; nicht voran, wird zwangsweise weitergerueckt. Ein haengendes BricsCAD
|
||||
;; waere schlimmer als ein unvollstaendig gelesenes Objekt.
|
||||
(if (= vorher *ssg-json-pos*) (ssg-json-weiter))
|
||||
)
|
||||
(if (equal (ssg-json-zeichen) "}") (ssg-json-weiter))
|
||||
(reverse erg)
|
||||
)
|
||||
|
||||
(defun ssg-json-array ( / erg c vorher)
|
||||
(ssg-json-weiter)
|
||||
(setq erg nil)
|
||||
(ssg-json-leerraum)
|
||||
(while (and (setq c (ssg-json-zeichen)) (/= c "]"))
|
||||
(setq vorher *ssg-json-pos*)
|
||||
(if (= c ",")
|
||||
(ssg-json-weiter)
|
||||
(setq erg (cons (ssg-json-wert) erg))
|
||||
)
|
||||
(ssg-json-leerraum)
|
||||
(if (= vorher *ssg-json-pos*) (ssg-json-weiter))
|
||||
)
|
||||
(if (equal (ssg-json-zeichen) "]") (ssg-json-weiter))
|
||||
(reverse erg)
|
||||
)
|
||||
|
||||
(defun ssg-json-wert ( / c)
|
||||
(ssg-json-leerraum)
|
||||
(setq c (ssg-json-zeichen))
|
||||
(cond
|
||||
((null c) nil)
|
||||
((= c "{") (ssg-json-objekt))
|
||||
((= c "[") (ssg-json-array))
|
||||
((= c "\"") (ssg-json-string))
|
||||
(T (ssg-json-literal))
|
||||
)
|
||||
)
|
||||
|
||||
;; JSON-Text parsen. Rueckgabe: Struktur (siehe Abbildung oben).
|
||||
(defun ssg-json-parse (text / erg)
|
||||
(setq *ssg-json-txt* text
|
||||
*ssg-json-len* (strlen text)
|
||||
*ssg-json-pos* 1)
|
||||
(setq erg (ssg-json-wert))
|
||||
;; Quelltext nicht global stehen lassen - eine Datendatei haelt sonst
|
||||
;; dauerhaft mehrere KB in einer globalen Variablen fest.
|
||||
(setq *ssg-json-txt* nil *ssg-json-len* 0 *ssg-json-pos* 1)
|
||||
erg
|
||||
)
|
||||
|
||||
;; JSON-Datei parsen. Rueckgabe: Struktur oder nil, wenn die Datei fehlt.
|
||||
(defun ssg-json-laden (datei / zeilen)
|
||||
(setq zeilen (ssg-read-file-lines datei))
|
||||
(if zeilen (ssg-json-parse (ssg-join zeilen "\n")))
|
||||
)
|
||||
|
||||
;; Feld eines geparsten JSON-Objekts lesen.
|
||||
(defun ssg-json-get (obj key)
|
||||
(cdr (assoc key obj))
|
||||
)
|
||||
|
||||
|
||||
;; Verschachteltes JSON-Objekt parsen (1 Ebene tief)
|
||||
;; {"section": {"key": val, ...}, ...}
|
||||
;; -> (("section" ("key" . val) ...) ...)
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
;; pattern_btmt_entladung in cfg/export.cfg) aus demselben Grund: sonst bleibt
|
||||
;; ihre ID trotz ATTDEF leer und sie fehlen bei der zeichnungsweiten Duplikat-
|
||||
;; pruefung/Maximum-Ermittlung (ssg-id-check-all).
|
||||
;; GR_* (Geruest-Baugruppen, siehe pattern_geruest in cfg/export.cfg) ebenso -
|
||||
;; das ID-ATTDEF steht seit *geruest-attrib-defs* zur Verfuegung.
|
||||
(defun ssg-id-collect-blocks ( / ss-all ss-out i ename ed bname)
|
||||
(dbgf "ssg-id-collect-blocks")
|
||||
(setq ss-all (ssget "X" (list (cons 0 "INSERT"))))
|
||||
@@ -55,6 +57,7 @@
|
||||
(wcmatch bname "Vario*,Staustrecke*,AUS_Element*,EIN_Element*,VF_*,GF_*")
|
||||
(wcmatch bname "Separator_SP*,S-LP*,Scanner*")
|
||||
(wcmatch bname "BTMT-Beladung*,SC_Entladung*")
|
||||
(wcmatch bname "GR_*")
|
||||
(wcmatch bname "#*")
|
||||
)
|
||||
(ssadd ename ss-out)
|
||||
|
||||
@@ -36,6 +36,10 @@
|
||||
# fuehren sie daher beide als eigene TeileArt-Zeilen (export_sivas.py zusaetzlich
|
||||
# in den Summierungszaehlern "Anzahl aller BTBeladung"/"Anzahl aller
|
||||
# Abwurfstationen" der ILS-Automation-Zeile).
|
||||
#
|
||||
# pattern_geruest: Geruest-Baugruppen (GeruestInsert.lsp, GR_<id>_<timestamp>).
|
||||
# Eigenstaendig wie BTMT, kein ANZAHL_*-Attribut an einem Carrier - export_csv.py
|
||||
# UND export_sivas.py fuehren sie als eigene TeileArt-Zeilen.
|
||||
# ============================================================
|
||||
|
||||
[blockpattern]
|
||||
@@ -50,6 +54,7 @@ pattern_separator= Separator_SP*, S-LP*
|
||||
pattern_scanner= Scanner*
|
||||
pattern_btmt_beladung= BTMT-Beladung*
|
||||
pattern_btmt_entladung= SC_Entladung*
|
||||
pattern_geruest= GR_*
|
||||
pattern_ks_subblocks= KS_EIN, KS_AUS, K1, K2, K3, K4
|
||||
|
||||
[python]
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,419 @@
|
||||
{
|
||||
"Rohrabhänger": {
|
||||
"id": "Rohrabhaenger",
|
||||
"teileart": "Geruest Rohrabhaenger",
|
||||
"dummy": "Rohrabhaenger_dummy.dwg",
|
||||
"attribute": {
|
||||
"Laenge": {
|
||||
"typ": "number",
|
||||
"min": 0,
|
||||
"max": 6000,
|
||||
"einheit": "mm"
|
||||
},
|
||||
"Farbe": {
|
||||
"typ": "auswahl",
|
||||
"optionen": [
|
||||
"RAL7035",
|
||||
"RAL7030"
|
||||
],
|
||||
"frei_erlaubt": true,
|
||||
"frei_option": "Individuell"
|
||||
}
|
||||
},
|
||||
"geometrie_varianten": [
|
||||
{
|
||||
"name": "ROHR R 1\" 33,7 x 2,6",
|
||||
"teile": [
|
||||
{
|
||||
"artikel": "ROHR R 1\" 33,7 x 2,6",
|
||||
"sivas_id": 821006026,
|
||||
"menge": 1
|
||||
},
|
||||
{
|
||||
"artikel": "CAD - ROHRABH. 1\" NICHT GEQUETSCHT - MONTAGEELEMENTE KPL.",
|
||||
"sivas_id": 821004202,
|
||||
"menge": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ROHR R 1\" 33,7 x 2,6 einseitig gequetscht",
|
||||
"teile": [
|
||||
{
|
||||
"artikel": "ROHR R 1\" 33,7 x 2,6 einseitig gequetscht",
|
||||
"sivas_id": 821006034,
|
||||
"menge": 1
|
||||
},
|
||||
{
|
||||
"artikel": "CAD - ROHRABHÄNGER 1\" EINSEITIG GEQUETSCHT - MONTAGEELEMENTE KPL.",
|
||||
"sivas_id": 821004203,
|
||||
"menge": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ROHR R 1\" 33,7 x 2,6 beidseitig gequetscht",
|
||||
"teile": [
|
||||
{
|
||||
"artikel": "ROHR R 1\" 33,7 x 2,6 beidseitig gequetscht",
|
||||
"sivas_id": 821006035,
|
||||
"menge": 1
|
||||
},
|
||||
{
|
||||
"artikel": "CAD - ROHRABHÄNGER 1\" BEIDSEITIG GEQUETSCHT - MONTAGEELEMENTE KPL.",
|
||||
"sivas_id": 821004204,
|
||||
"menge": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"anbaugruppen": [
|
||||
{
|
||||
"artikel": "SPANNPRATZE ST - KH 8-11 KPL.SELBSTSICHERND",
|
||||
"sivas_id": 821004120,
|
||||
"menge": 1
|
||||
},
|
||||
{
|
||||
"artikel": "SPANNPRATZE SELBSTSICHERND KPL.",
|
||||
"sivas_id": 821004058,
|
||||
"menge": 1
|
||||
},
|
||||
{
|
||||
"name": "Schraubenset",
|
||||
"teile": [
|
||||
{
|
||||
"artikel": "Scheibe DIN 125 - A 10,5 - 140 HV - St",
|
||||
"sivas_id": 913011010,
|
||||
"menge": 1
|
||||
},
|
||||
{
|
||||
"artikel": "Sechskantmutter DIN 934 - M10 - 8",
|
||||
"sivas_id": 912011010,
|
||||
"menge": 2
|
||||
},
|
||||
{
|
||||
"artikel": "Sechskantschraube DIN 933 - M10 x 30 - 8.8",
|
||||
"sivas_id": 911011008,
|
||||
"menge": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"artikel": "U-BÜGEL M7 41X49 FÜR PROFILGERÜST - BG",
|
||||
"sivas_id": 825004049,
|
||||
"menge": 1
|
||||
},
|
||||
{
|
||||
"artikel": "ROHRKLAMMER 1\" KPL. VERTIKAL",
|
||||
"sivas_id": 825004040,
|
||||
"menge": 2
|
||||
},
|
||||
{
|
||||
"artikel": "WINKEL 60X60X6X300",
|
||||
"sivas_id": 821006043,
|
||||
"menge": 1
|
||||
},
|
||||
{
|
||||
"artikel": "WINKEL 60X60X6X60",
|
||||
"sivas_id": 821006042,
|
||||
"menge": 1
|
||||
},
|
||||
{
|
||||
"artikel": "ROHRKLAMMER 1\" T-VERBINDUNG KPL.",
|
||||
"sivas_id": 825004030,
|
||||
"menge": 1
|
||||
},
|
||||
{
|
||||
"artikel": "ROHRKLAMMER 1\" FLACH UND LANG, KPL.",
|
||||
"sivas_id": 825002021,
|
||||
"menge": 1
|
||||
},
|
||||
{
|
||||
"artikel": "DURCHSTECKANKER HST M12X115X20",
|
||||
"sivas_id": 922021003,
|
||||
"menge": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"1\" Säulen": {
|
||||
"id": "Saeulen_1Zoll",
|
||||
"teileart": "Geruest Saeule 1 Zoll",
|
||||
"dummy": "R2-Saeule_dummy.dwg",
|
||||
"attribute": {
|
||||
"Laenge": {
|
||||
"typ": "number",
|
||||
"min": 0,
|
||||
"max": 6000,
|
||||
"einheit": "mm"
|
||||
},
|
||||
"Farbe": {
|
||||
"typ": "auswahl",
|
||||
"optionen": [
|
||||
"RAL7035",
|
||||
"RAL7030"
|
||||
],
|
||||
"frei_erlaubt": true,
|
||||
"frei_option": "Individuell"
|
||||
}
|
||||
},
|
||||
"geometrie_varianten": [
|
||||
{
|
||||
"name": "R 1\"",
|
||||
"teile": [
|
||||
{
|
||||
"artikel": "ROHR R 1\" 33,7 x 2,6",
|
||||
"sivas_id": 821006026,
|
||||
"menge": 1
|
||||
},
|
||||
{
|
||||
"artikel": "CAD - BODENSÄULE R 1\" - BODENPLATTE KPL.",
|
||||
"sivas_id": 821004200,
|
||||
"menge": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"2\" Säulen": {
|
||||
"id": "Saeulen_2Zoll",
|
||||
"teileart": "Geruest Saeule 2 Zoll",
|
||||
"dummy": "R2-Saeule_dummy.dwg",
|
||||
"attribute": {
|
||||
"Laenge": {
|
||||
"typ": "number",
|
||||
"min": 0,
|
||||
"max": 6000,
|
||||
"einheit": "mm"
|
||||
},
|
||||
"Farbe": {
|
||||
"typ": "auswahl",
|
||||
"optionen": [
|
||||
"RAL7035",
|
||||
"RAL7030"
|
||||
],
|
||||
"frei_erlaubt": true,
|
||||
"frei_option": "Individuell"
|
||||
}
|
||||
},
|
||||
"einbauwinkel": {
|
||||
"Platte": [
|
||||
0,
|
||||
90
|
||||
],
|
||||
"Arm": [
|
||||
0,
|
||||
90,
|
||||
180,
|
||||
270
|
||||
]
|
||||
},
|
||||
"geometrie_varianten": [
|
||||
{
|
||||
"name": "R 2\"",
|
||||
"teile": [
|
||||
{
|
||||
"artikel": "BODENSÄULE R 2\" 60,3 MIT FUSSPLATTE",
|
||||
"sivas_id": 821006051,
|
||||
"menge": 1
|
||||
},
|
||||
{
|
||||
"artikel": "CAD - BODENSÄULE R 2\" - DURCHSTECKANKER KPL.",
|
||||
"sivas_id": 821004201,
|
||||
"menge": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "R 2\" Haltearm 1-ARMIG",
|
||||
"teile": [
|
||||
{
|
||||
"artikel": "BODENSÄULE R 2\" 60,3 MIT FUSSPLATTE",
|
||||
"sivas_id": 821006051,
|
||||
"menge": 1
|
||||
},
|
||||
{
|
||||
"artikel": "CAD - BODENSÄULE R 2\" - DURCHSTECKANKER KPL.",
|
||||
"sivas_id": 821004201,
|
||||
"menge": 1
|
||||
},
|
||||
{
|
||||
"artikel": "HALTEARM FÜR BODENSÄULE R 2\" 1-ARMIG KPL.",
|
||||
"sivas_id": 821004051,
|
||||
"menge": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "R 2\" Haltearm 2-ARMIG 90 Grad",
|
||||
"teile": [
|
||||
{
|
||||
"artikel": "BODENSÄULE R 2\" 60,3 MIT FUSSPLATTE",
|
||||
"sivas_id": 821006051,
|
||||
"menge": 1
|
||||
},
|
||||
{
|
||||
"artikel": "CAD - BODENSÄULE R 2\" - DURCHSTECKANKER KPL.",
|
||||
"sivas_id": 821004201,
|
||||
"menge": 1
|
||||
},
|
||||
{
|
||||
"artikel": "HALTEARM FÜR BODENSÄULE R 2\" 2-ARMIG 90 Grad KPL.",
|
||||
"sivas_id": 821004054,
|
||||
"menge": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "R 2\" Haltearm 2-ARMIG 180 Grad",
|
||||
"teile": [
|
||||
{
|
||||
"artikel": "BODENSÄULE R 2\" 60,3 MIT FUSSPLATTE",
|
||||
"sivas_id": 821006051,
|
||||
"menge": 1
|
||||
},
|
||||
{
|
||||
"artikel": "CAD - BODENSÄULE R 2\" - DURCHSTECKANKER KPL.",
|
||||
"sivas_id": 821004201,
|
||||
"menge": 1
|
||||
},
|
||||
{
|
||||
"artikel": "HALTEARM FÜR BODENSÄULE R 2\" 2-ARMIG 180 Grad KPL.",
|
||||
"sivas_id": 821004052,
|
||||
"menge": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "R 2\" Haltearm 3-ARMIG",
|
||||
"teile": [
|
||||
{
|
||||
"artikel": "BODENSÄULE R 2\" 60,3 MIT FUSSPLATTE",
|
||||
"sivas_id": 821006051,
|
||||
"menge": 1
|
||||
},
|
||||
{
|
||||
"artikel": "CAD - BODENSÄULE R 2\" - DURCHSTECKANKER KPL.",
|
||||
"sivas_id": 821004201,
|
||||
"menge": 1
|
||||
},
|
||||
{
|
||||
"artikel": "HALTEARM FÜR BODENSÄULE R 2\" 3-ARMIG KPL.",
|
||||
"sivas_id": 821004053,
|
||||
"menge": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"anbaugruppen": [
|
||||
{
|
||||
"artikel": "KLEMMRING MIT MUFFE EINFACH KPL.",
|
||||
"sivas_id": 825002019,
|
||||
"menge": 2
|
||||
},
|
||||
{
|
||||
"artikel": "KLEMMRING MIT MUFFE DOPPELT 90 Grad, KPL.",
|
||||
"sivas_id": 825002009,
|
||||
"menge": 2
|
||||
},
|
||||
{
|
||||
"artikel": "KLEMMRING MIT MUFFE DOPPELT 180 Grad, KPL.",
|
||||
"sivas_id": 825002008,
|
||||
"menge": 2
|
||||
},
|
||||
{
|
||||
"artikel": "KLEMMRING M. MUFFE DREIFACH 90 Grad/180 Grad KPL.",
|
||||
"sivas_id": 825002007,
|
||||
"menge": 2
|
||||
},
|
||||
{
|
||||
"artikel": "KLEMMRING MIT LASCHE KPL. ZUSAMMENBAUZEICHNUNG",
|
||||
"sivas_id": 825002020,
|
||||
"menge": 2
|
||||
},
|
||||
{
|
||||
"artikel": "QUERSCHELLE F. 1\" UND 2\" ROHR GESCHW./VZ. M. 4X M10X30 KPL.",
|
||||
"sivas_id": 825002022,
|
||||
"menge": 2
|
||||
},
|
||||
{
|
||||
"artikel": "KREUZSCHELLE F. 2\" UND 1\" ROHR SCHWENKBAR 360 Grad",
|
||||
"sivas_id": 922083009,
|
||||
"menge": 2
|
||||
}
|
||||
]
|
||||
},
|
||||
"Wandbefestigung": {
|
||||
"id": "Wandbefestigung",
|
||||
"teileart": "Geruest Wandbefestigung",
|
||||
"dummy": "Rohrabhaenger_dummy.dwg",
|
||||
"geometrie_varianten": [
|
||||
{
|
||||
"name": "WANDFLANSCH EINZELTEIL",
|
||||
"teile": [
|
||||
{
|
||||
"artikel": "WANDFLANSCH EINZELTEIL",
|
||||
"sivas_id": 821006031,
|
||||
"menge": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "WINKEL 60X60X6X60",
|
||||
"teile": [
|
||||
{
|
||||
"artikel": "WINKEL 60X60X6X60",
|
||||
"sivas_id": 821006042,
|
||||
"menge": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "WINKEL 60X60X6X300",
|
||||
"teile": [
|
||||
{
|
||||
"artikel": "WINKEL 60X60X6X300",
|
||||
"sivas_id": 821006043,
|
||||
"menge": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ROHRSCHELLE 1\" OBERTEIL",
|
||||
"teile": [
|
||||
{
|
||||
"artikel": "ROHRSCHELLE 1\" OBERTEIL",
|
||||
"sivas_id": 825006009,
|
||||
"menge": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"anbaugruppen": [
|
||||
{
|
||||
"name": "Nylondübel 12x60 inkl. Holzschrauben",
|
||||
"teile": [
|
||||
{
|
||||
"artikel": "HOLZSCHRAUB,10X70, 6KT DIN 571 VZ",
|
||||
"sivas_id": 911271027,
|
||||
"menge": 2
|
||||
},
|
||||
{
|
||||
"artikel": "NYLON - DUEBEL 12X60 (TYP S)",
|
||||
"sivas_id": 922013003,
|
||||
"menge": 2
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "HST M12X115X20",
|
||||
"teile": [
|
||||
{
|
||||
"artikel": "DURCHSTECKANKER HST M12X115X20 WANDABH.",
|
||||
"sivas_id": 922021003,
|
||||
"menge": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
// ============================================================
|
||||
// geruest.dcl - Konfiguration einer Geruest-Baugruppe
|
||||
// Ein Dialog fuer ALLE Baugruppen (Rohrabhaenger, Saeulen, Wandbefestigung).
|
||||
// Kopfzeile, Varianten-Dropdown, Farbliste und Anbauteil-Liste werden zur
|
||||
// Laufzeit aus data/json/geruest.json befuellt - siehe
|
||||
// Lisp/GeruestInsert.lsp, Abschnitt "DIALOG".
|
||||
// Baugruppen ohne "attribute"-Block (z.B. Wandbefestigung) bekommen die
|
||||
// Laengen- und Farbfelder per mode_tile gesperrt.
|
||||
// ============================================================
|
||||
|
||||
geruest : dialog {
|
||||
label = "Geruest-Baugruppe konfigurieren";
|
||||
|
||||
: text {
|
||||
key = "kopf";
|
||||
label = "";
|
||||
width = 64;
|
||||
}
|
||||
|
||||
: boxed_column {
|
||||
label = "Basis";
|
||||
|
||||
: popup_list {
|
||||
key = "variante";
|
||||
label = "Variante:";
|
||||
width = 56;
|
||||
}
|
||||
|
||||
: row {
|
||||
: edit_box {
|
||||
key = "laenge";
|
||||
label = "Laenge (mm):";
|
||||
edit_width = 10;
|
||||
}
|
||||
: popup_list {
|
||||
key = "farbe";
|
||||
label = "Farbe:";
|
||||
width = 18;
|
||||
}
|
||||
: edit_box {
|
||||
key = "farbe_frei";
|
||||
label = "eigene:";
|
||||
edit_width = 12;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
: boxed_column {
|
||||
label = "Anbauteile (Mehrfachauswahl mit Strg)";
|
||||
|
||||
: list_box {
|
||||
key = "anbau";
|
||||
label = "";
|
||||
multiple_select = true;
|
||||
width = 64;
|
||||
height = 12;
|
||||
}
|
||||
}
|
||||
|
||||
ok_cancel;
|
||||
}
|
||||
@@ -145,6 +145,133 @@ Elementnummer;TeileArt;TeileId;Bezeichnung;Planquadrat;Anzahl;Position;Boundingb
|
||||
Insertpoint;K1;K2;K3;K4;Nachbarn;TrackIds;Fehler;Warnungen;Merkmale
|
||||
```
|
||||
|
||||
- **Position** = Mittenkoordinate x, y, z; **Boundingbox** = Ausdehnung
|
||||
(Laenge, Breite, Hoehe) in x, y, z — beide aus `csv:get-bbox`
|
||||
(`vla-getboundingbox`), siehe Phase 1.
|
||||
- **Insertpoint** = KOS-String (24-Zeichen Base64, Position+Rotation als
|
||||
Quaternion, `csv:kos-encode`) des Block-Einfuegepunkts selbst.
|
||||
- **K1-K4** = Positions-Strings der im Block enthaltenen Koordinatensysteme
|
||||
K1..K4 (12-Zeichen Base64, nur Position, `csv:trans-encode`) — nur bei
|
||||
Omniflo Bogen/Weiche/Gerade und VF_n/GF_n (K1/K2 aus AS/ES) vorhanden,
|
||||
sonst leer.
|
||||
- **Fehler** = `"unverbunden"` (keine Partner, aber mindestens einer noetig),
|
||||
`"nur ein Partner"` (ein Partner, aber mindestens zwei noetig) oder leer.
|
||||
Kreisel/Eckrad/Omniflo brauchen mindestens einen Partner,
|
||||
Gefaellestrecke/Foerderer/Strecke-Modul mindestens zwei
|
||||
(`export_neighbors.MIN_PARTNER`).
|
||||
- **Elementnummer** wird NICHT aus der TeileId uebernommen, sondern am Ende
|
||||
neu von 1 an vergeben, nachdem alle Zeilen aufsteigend nach TeileId
|
||||
sortiert wurden (`teileid_sort_key` in `process_blocks`). Ohne geloeschte
|
||||
Elemente stimmen Elementnummer und TeileId dadurch ueberein; geloeschte
|
||||
Elemente hinterlassen Luecken nur in der TeileId-Folge. Zeilen ohne
|
||||
numerische TeileId (Omniflo-Sum-Zeile, SEP-/SCN-Fallback-IDs ohne
|
||||
ID-Attribut) behalten stabil ihre bisherige Reihenfolge und stehen danach.
|
||||
|
||||
### Beispiel: Kreisel mit 2 Separatoren + VarioFoerderer mit 2 Separatoren
|
||||
|
||||
Ausgangslage in der Zeichnung: ein kleiner Kreisel (`KREISEL_1`, ID `0010`)
|
||||
mit zwei frei aufgesetzten Separatoren auf seiner Bahn, daran andockend ein
|
||||
`VF_1` mit einer Kette AS -> Separator -> Separator -> ES (IDs `0021`-`0024`).
|
||||
|
||||
**Ausschnitt `export_raw.json`** (von `csv:collect-export-blocks` /
|
||||
`csv:block-to-json` geschrieben, hier gekuerzt auf die fuer dieses Beispiel
|
||||
relevanten Felder):
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"block_name": "KREISEL_1",
|
||||
"layer": "ILS_Kreisel",
|
||||
"handle": "2A1",
|
||||
"x": 10000.0, "y": 5000.0, "z": 0.0, "rotation": 0.0,
|
||||
"attribs": {"ID": "0010", "DREHRICHTUNG": "UZS", "ABSTAND": "800"},
|
||||
"insertpoint": "AAB3QAAATkAAAAAA...",
|
||||
"bbox": {"min": [9200.0, 4200.0, 0.0], "max": [10800.0, 5800.0, 0.0]}
|
||||
},
|
||||
{
|
||||
"block_name": "Separator_SP_300mm",
|
||||
"layer": "ILS_Sensor",
|
||||
"handle": "2A5",
|
||||
"x": 10800.0, "y": 5000.0, "z": 0.0, "rotation": 0.0,
|
||||
"attribs": {"ID": "0011"},
|
||||
"insertpoint": "AAD4QAAATkAAAAAA..."
|
||||
},
|
||||
{
|
||||
"block_name": "Separator_SP_300mm",
|
||||
"layer": "ILS_Sensor",
|
||||
"handle": "2A9",
|
||||
"x": 10000.0, "y": 5800.0, "z": 0.0, "rotation": 90.0,
|
||||
"attribs": {"ID": "0012"},
|
||||
"insertpoint": "AAB3QAAAxEAAAAAA..."
|
||||
},
|
||||
{
|
||||
"block_name": "VF_1",
|
||||
"layer": "ILS_Foerderer",
|
||||
"handle": "2B0",
|
||||
"x": 10800.0, "y": 5000.0, "z": 0.0, "rotation": 0.0,
|
||||
"attribs": {"ID": "0021", "Bezeichnung": ""},
|
||||
"insertpoint": "AAD4QAAATkAAAAAA...",
|
||||
"k1": "AAD4QAAATkAAAAAA...",
|
||||
"k2": "AAAAQwAATkAAAAAA...",
|
||||
"bbox": {"min": [10800.0, 4850.0, 0.0], "max": [13000.0, 5150.0, 300.0]},
|
||||
"sepliste": [
|
||||
["AS", 1, 10800.0, 5000.0],
|
||||
["SEP", 2, 11600.0, 5000.0],
|
||||
["SEP", 3, 12300.0, 5000.0],
|
||||
["ES", 4, 13000.0, 5000.0]
|
||||
]
|
||||
},
|
||||
{
|
||||
"block_name": "Separator_SP_300mm",
|
||||
"layer": "ILS_Sensor",
|
||||
"handle": "2B4",
|
||||
"x": 11600.0, "y": 5000.0, "z": 0.0, "rotation": 0.0,
|
||||
"attribs": {"ID": "0022"}
|
||||
},
|
||||
{
|
||||
"block_name": "Separator_SP_300mm",
|
||||
"layer": "ILS_Sensor",
|
||||
"handle": "2B8",
|
||||
"x": 12300.0, "y": 5000.0, "z": 0.0, "rotation": 0.0,
|
||||
"attribs": {"ID": "0023"}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
Die beiden Separatoren `0022`/`0023` sind hier die ECHTEN, top-level
|
||||
exportierten Separator-Bloecke (identisch mit den `SEP`-Eintraegen der
|
||||
`sepliste` von `VF_1` — siehe "Die `sepliste`" oben: kein doppeltes Konzept,
|
||||
zwei Blickwinkel auf dieselben Symbole).
|
||||
|
||||
**Resultierende CSV-Zeilen** (Header + betroffene Zeilen, Spalten
|
||||
`Insertpoint`/`K3`/`K4`/`Merkmale` fuer die Lesbarkeit gekuerzt):
|
||||
|
||||
```text
|
||||
Elementnummer;TeileArt;TeileId;Bezeichnung;Planquadrat;Anzahl;Position;Boundingbox;Insertpoint;K1;K2;K3;K4;Nachbarn;TrackIds;Fehler;Warnungen;Merkmale
|
||||
1;"ILS 2.0 Kreisel";"0010";"Kreisel :1";"B/3";1;"10000.0, 5000.0, 0.0";"1600.0, 1600.0, 0.0";"...";"";"";"";"";"0011, 0012, 0021";"0011, 0012, 0021, 0022, 0023, 0024";"";"";{"Abstand":"800"}
|
||||
2;"ILS 2.0 Separator";"0011";"Separator :1";"B/3";1;"10800.0, 5000.0, 0.0";"210.0, 150.0, 14.0";"...";"";"";"";"";"0010, 0012";"";"";"";{"Zuordnung":"0010"}
|
||||
3;"ILS 2.0 Separator";"0012";"Separator :2";"B/3";1;"10000.0, 5800.0, 0.0";"150.0, 210.0, 14.0";"...";"";"";"";"";"0011, 0021";"";"";"";{"Zuordnung":"0010"}
|
||||
4;"ILS 2.0 VarioFoerderer";"0021";"VarioFoerderer :1";"B/3";1;"11900.0, 5000.0, 0.0";"2200.0, 300.0, 300.0";"...";"...";"...";"";"";"0010, 0024";"0021, 0022, 0023, 0024";"";"";{}
|
||||
5;"ILS 2.0 Separator";"0022";"Separator :3";"C/4";1;"11600.0, 5000.0, 0.0";"210.0, 150.0, 14.0";"...";"";"";"";"";"";"";"";"";{"Zuordnung":"0021"}
|
||||
6;"ILS 2.0 Separator";"0023";"Separator :4";"C/4";1;"12300.0, 5000.0, 0.0";"210.0, 150.0, 14.0";"...";"";"";"";"";"";"";"";"";{"Zuordnung":"0021"}
|
||||
```
|
||||
|
||||
Zu beachten:
|
||||
|
||||
- Der Kreisel (`0010`) traegt in `TrackIds` den KOMPLETTEN Umlauf inkl. der
|
||||
VF-Kettenenden (`0021`=AS, `0024`=ES, aus `compute_kreisel_umlauf`), waehrend
|
||||
seine `Nachbarn`-Spalte nur die unmittelbaren Umlauf-Nachbarn zeigt.
|
||||
- `VF_1` (`0021`) bekommt seine eigene `TrackIds`-Spalte
|
||||
(`write_separatorliste_merkmale`) aus der `sepliste`: AS -> SEP -> SEP -> ES
|
||||
in Baureihenfolge, unabhaengig vom Kreisel-Umlauf.
|
||||
- Die AS/ES-Enden (`0021`=AS, `0024`=ES) sind hier synthetische Zeilen aus
|
||||
`build_strecke_schleus_items` (Zeilentyp "ILS Ausschleuselement"/
|
||||
"ILS Einschleuselement") — in diesem gekuerzten Beispiel nicht einzeln
|
||||
aufgefuehrt, aber ihre TeileIds tauchen in `TrackIds` beider Seiten auf.
|
||||
- Die Separatoren 3 und 5 (`0012`/`0022`) unterscheiden sich nur durch ihre
|
||||
`Zuordnung`: `0012` haengt am Kreisel, `0022`/`0023` an der VF-Kette — beide
|
||||
Faelle laufen ueber denselben `pattern_separator`-Blocktyp.
|
||||
|
||||
### 1. Blöcke klassifizieren
|
||||
|
||||
Eine grosse Schleife über alle rohen JSON-Blöcke ordnet jeden Block anhand
|
||||
|
||||
+13
-1
@@ -969,6 +969,18 @@
|
||||
"vfl-kette-diag-startbaustein": "\n [Diagnose] KS_AUS Startbaustein (%1): X=%2 Y=%3 Z=%4",
|
||||
"vfl-kette-diag-naechster-kandidat": "\n [Diagnose] Naechster Kandidat: %1 Abstand=%2 mm (Toleranz eng=%3 mm, weit=%4 mm)",
|
||||
"vfl-kette-diag-kein-anderer": "\n [Diagnose] Kein anderer Baustein mit KS_EIN gefunden (insgesamt %1 Bausteine erfasst).",
|
||||
"vfl-kette-diag-verdaechtig": "\n [Diagnose] VERDAECHTIG: '%1' -> '%2' Abstand=%3 mm (innerhalb Toleranz, aber nicht ~0)"
|
||||
"vfl-kette-diag-verdaechtig": "\n [Diagnose] VERDAECHTIG: '%1' -> '%2' Abstand=%3 mm (innerhalb Toleranz, aber nicht ~0)",
|
||||
"gr-fehler-datenpfad": "\nGeruest: Datenverzeichnis unbekannt - DXFM_DATA bzw. DXFMAKRO nicht gesetzt (bin/setenv.bat ausfuehren).",
|
||||
"gr-fehler-json-fehlt": "\nGeruest: Datendatei nicht gefunden: %1",
|
||||
"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-fehler-dummy": "\nGeruest: Dummy-Baugruppe nicht gefunden: %1",
|
||||
"gr-fehler-dcl": "Dialog geruest.dcl konnte nicht geladen werden.",
|
||||
"gr-dlg-kopf": "%1 konfigurieren",
|
||||
"gr-alert-laenge": "Laenge ungueltig: '%1' mm. Erlaubt: %2 bis %3 mm.",
|
||||
"gr-prompt-einfuegepunkt": "\nEinfuegepunkt waehlen: ",
|
||||
"gr-abgebrochen": "\nAbgebrochen.",
|
||||
"gr-fertig": "\nGeruest-Baugruppe '%1' eingefuegt (Block %2)."
|
||||
}
|
||||
}
|
||||
|
||||
+13
-1
@@ -969,6 +969,18 @@
|
||||
"vfl-kette-diag-startbaustein": "\n [Diagnose] KS_AUS start block (%1): X=%2 Y=%3 Z=%4",
|
||||
"vfl-kette-diag-naechster-kandidat": "\n [Diagnose] Next candidate: %1 distance=%2 mm (tolerance tight=%3 mm, wide=%4 mm)",
|
||||
"vfl-kette-diag-kein-anderer": "\n [Diagnose] No other block with KS_EIN found (%1 blocks captured in total).",
|
||||
"vfl-kette-diag-verdaechtig": "\n [Diagnose] SUSPICIOUS: '%1' -> '%2' distance=%3 mm (within tolerance, but not ~0)"
|
||||
"vfl-kette-diag-verdaechtig": "\n [Diagnose] SUSPICIOUS: '%1' -> '%2' distance=%3 mm (within tolerance, but not ~0)",
|
||||
"gr-fehler-datenpfad": "\nScaffold: data directory unknown - DXFM_DATA or DXFMAKRO not set (run bin/setenv.bat).",
|
||||
"gr-fehler-json-fehlt": "\nScaffold: data file not found: %1",
|
||||
"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-fehler-dummy": "\nScaffold: dummy assembly not found: %1",
|
||||
"gr-fehler-dcl": "Dialog geruest.dcl could not be loaded.",
|
||||
"gr-dlg-kopf": "Configure %1",
|
||||
"gr-alert-laenge": "Invalid length: '%1' mm. Allowed: %2 to %3 mm.",
|
||||
"gr-prompt-einfuegepunkt": "\nSelect insertion point: ",
|
||||
"gr-abgebrochen": "\nCancelled.",
|
||||
"gr-fertig": "\nScaffold assembly '%1' inserted (block %2)."
|
||||
}
|
||||
}
|
||||
|
||||
+50
-98
@@ -3,111 +3,21 @@
|
||||
"""
|
||||
export_csv.py - Erzeugt eine einfache Item-Liste als CSV.
|
||||
|
||||
Fuer Omniflo-Elemente (Bogen/Weiche/Gerade) wird am Ende zusaetzlich eine
|
||||
"Omniflo Sum"-Zeile mit Anzahl Boegen/Weichentypen und Gesamtlaenge AP110/AP60
|
||||
angehaengt (siehe build_omni_sum_merkmale).
|
||||
|
||||
Nach der Kollisions-/Nachbarschaftserkennung wird ausserdem an jedem
|
||||
Beruehrpunkt zweier Kreisel eine "ILS Weiche"-Zeile angehaengt (siehe
|
||||
build_kreisel_weiche_items / export_neighbors.compute_kreisel_touch_switches):
|
||||
Anzahl 1, Position = Beruehrkoordinaten, Nachbarn = die beiden Kreisel-IDs,
|
||||
K1-K4/Insertpoint leer, Boundingbox = feste Element-Box (element_box_mm,
|
||||
cfg/export.cfg [Boundingbox]),
|
||||
mit der Laengsseite senkrecht zur Achse des beruehrenden Kreisels; die TeileId
|
||||
zaehlt aus der hoechsten bereits vergebenen numerischen ID hoch.
|
||||
|
||||
Anschliessend (TeileId-Zaehlung laeuft ueber die Weichen hinweg weiter) wird
|
||||
an jedem Ende einer Gefaellestrecke/eines Foerderers, an dem ein Kreisel
|
||||
anschliesst, ein Aus- (Anfang) bzw. Einschleuselement (Ende) an der Kollisions-
|
||||
position Kreisel<->Strecke angehaengt (siehe build_strecke_schleus_items /
|
||||
export_neighbors.compute_strecke_kreisel_schleus) - Format wie die Weiche,
|
||||
Nachbarn = Kreisel-ID + Strecken-ID. Zugeordnet wird je Streckenende der
|
||||
naechstgelegene ihrer BBox-Kreisel-Nachbarn.
|
||||
|
||||
Warnungen = Spalte fuer Auffaelligkeiten. Aktuell: eine Strecke sollte genau
|
||||
zwei Kreisel (Anfang + Ende) beruehren - beruehrt ihre (in x/y gepruefte)
|
||||
Bounding-Box mehr, steht hier ein Hinweis und es wird zusaetzlich eine
|
||||
Konsolen-WARNUNG ausgegeben (mit exakten 3D-BBoxen sollte das nicht auftreten).
|
||||
Scanner-Zeilen bekommen dieselbe Spalte fuer strittige Distanz-Zuordnungen:
|
||||
liegt ein Scanner ausserhalb jeder Kreisel-/Streckengruppen-/Gefaellestrecke-
|
||||
Boundingbox und ist der Abstand zum naechsten und zweitnaechsten Carrier fast
|
||||
gleich gross, schreibt Lisp/count_sep_scan.lsp (cs-zuordnung-lauf, vor dem
|
||||
Export automatisch aufgerufen) einen Warnungstext mit den IDs beider
|
||||
Kandidaten in das "warnung"-Feld des Scanner-Blocks im Roh-JSON (siehe
|
||||
csv:block-to-json in export.lsp) - hier unveraendert uebernommen.
|
||||
|
||||
Aufruf:
|
||||
python export_csv.py <export_raw.json> <data_dir> <output.csv>
|
||||
|
||||
CSV-Format:
|
||||
CSV-Format (Header):
|
||||
Elementnummer;TeileArt;TeileId;Bezeichnung;Planquadrat;Anzahl;Position;Boundingbox;
|
||||
Insertpoint;K1;K2;K3;K4;Nachbarn;TrackIds;Fehler;Warnungen;Merkmale
|
||||
|
||||
Position und Boundingbox stammen aus der von export.lsp (csv:get-bbox, per
|
||||
vla-getboundingbox) ermittelten Bounding-Box je Block:
|
||||
Position = Mittenkoordinate x, y, z
|
||||
Boundingbox = Ausdehnung (Laenge, Breite, Hoehe) in x, y, z
|
||||
Insertpoint = KOS-String (24-Zeichen Base64, Position+Rotation als Quaternion,
|
||||
siehe csv:kos-encode in export.lsp) des Block-Einfuegepunkts selbst.
|
||||
K1-K4 = Positions-Strings der im Block enthaltenen Koordinatensysteme K1..K4
|
||||
(12-Zeichen Base64, nur Position ohne Rotation, siehe csv:trans-encode;
|
||||
nur bei Omniflo Bogen/Weiche/Gerade vorhanden, sonst leer).
|
||||
Planquadrat wird aus der x/y-Koordinate des Blocks berechnet, siehe
|
||||
export_planquadrat.py ([Planquadrate] in cfg/export.cfg).
|
||||
Nachbarn = kommaseparierte TeileId-Liste ueberschneidender Elemente (Bounding-
|
||||
Box-Ueberschneidung in der x/y-Ebene, reines Python ohne externe Abhaengigkeit,
|
||||
siehe export_neighbors.py). Geprueft wird NICHT global ueber alle Elemente,
|
||||
sondern in drei getrennten Gruppen: 1) Kreisel/Eckrad gegen Kreisel/Eckrad,
|
||||
2) Kreisel/Eckrad gegen Gefaellestrecke/Foerderer/Strecke-Modul (diese drei
|
||||
nicht gegeneinander), 3) Omniflo-Elemente gegen Omniflo-Elemente. Fuer die
|
||||
Omniflo-Gruppe liefert eine shapely-STRtree-Broad-Phase zunaechst alle Paare
|
||||
mit ueberschneidenden Bounding-Boxen; anschliessend gelten sie nur dann als
|
||||
benachbart, wenn sich ihre Anschluss-Koordinatensysteme K1-K4 tatsaechlich
|
||||
beruehren (ein K-Punkt naeher als omniflo_ks_toleranz_mm, Default 10mm) -
|
||||
das trennt bloss ueberlappende BBoxen von echten Anschluessen (Geraden fuehren
|
||||
dafuer beim Export synthetisierte K1/K2, siehe csv:gerade-k-kos-strings).
|
||||
Toleranzen und (Fallback-)Rastergroesse konfigurierbar ueber [Nachbarschaft]
|
||||
in cfg/export.cfg.
|
||||
TrackIds = kommaseparierte TeileId-Liste der Separatoren/BTMT-Beladung/
|
||||
BTMT-Entladung (und bei einem Kreisel zusaetzlich der AS/ES-Streckenenden
|
||||
und Kreisel-Kreisel-Weichen) entlang einer VF_n/GF_n-Strecke bzw. rund um
|
||||
einen Kreisel, in Baureihenfolge (Strecke) bzw. Umlaufreihenfolge ab Winkel
|
||||
0 Grad (Kreisel, siehe export_neighbors.compute_kreisel_umlauf) - nur bei
|
||||
VF_n/GF_n/Kreisel vorhanden, sonst leer. Siehe write_separatorliste_
|
||||
merkmale/write_kreisel_separatorliste_merkmale.
|
||||
Fehler = "unverbunden" (keine Partner, aber mindestens einer noetig),
|
||||
"nur ein Partner" (ein Partner, aber mindestens zwei noetig) oder leer
|
||||
(Mindestanzahl erreicht bzw. TeileArt wird nicht geprueft). Kreisel/Eckrad/
|
||||
Omniflo-Elemente brauchen mindestens einen Partner, Gefaellestrecke/
|
||||
Foerderer/Strecke-Modul mindestens zwei (siehe export_neighbors.py
|
||||
MIN_PARTNER). Ein Kreisel wird dabei NICHT als eine, sondern als zwei
|
||||
BBoxen (links/rechts, geteilt entlang der Achse durch Antriebs-/
|
||||
Spannstation, siehe export_neighbors.kreisel_half_bboxes) gegen
|
||||
Gefaellestrecke/Foerderer getestet - deren "Nachbarn"-Spalte zeigt darum
|
||||
"<KreiselTeileId>-L" bzw. "-R" statt nur der Kreisel-TeileId.
|
||||
Separator/Scanner-Zeilen bekommen zusaetzlich ein berechnetes "Zuordnung"-
|
||||
Merkmal (Gefaellestrecke > Foerderer > Kreiselhaelfte, per BBox-Ueber-
|
||||
schneidung - siehe export_neighbors.compute_sensor_zuordnung), das die
|
||||
ATTRIB-Zuordnung (falls das Attribut ZUORDNUNG in der Zeichnung von Hand
|
||||
gesetzt wurde) ersetzt, sofern ein Treffer gefunden wird. Scanner-Zeilen
|
||||
bekommen zusaetzlich ein "Naechster Separator"-Merkmal (raeumlich naechst-
|
||||
gelegener Separator, euklidischer Abstand der BBox-Mittelpunkte - eigene,
|
||||
von der Zuordnung unabhaengige Suche, siehe export_neighbors.compute_
|
||||
scanner_nearest_separator).
|
||||
Position, Boundingbox, Planquadrat, Nachbarn und Fehler sind nur fuer
|
||||
EXPORTCSV vorhanden (nicht EXPORTSIVAS) - siehe csv:run-export. Insertpoint/
|
||||
K1-K4 stehen zwar in export_raw.json fuer jeden Export zur Verfuegung (siehe
|
||||
csv:block-to-json), werden aber ebenfalls nur von diesem Skript (EXPORTCSV)
|
||||
als CSV-Spalten ausgegeben.
|
||||
Beispielzeile (Separator, TeileId 0011 an Kreisel 0010):
|
||||
2;"ILS 2.0 Separator";"0011";"Separator :1";"B/3";1;
|
||||
"10800.0, 5000.0, 0.0";"210.0, 150.0, 14.0";"...";"";"";"";"";
|
||||
"0010, 0012";"";"";"";{"Zuordnung":"0010"}
|
||||
|
||||
Reihenfolge/Elementnummer: die Zeilen werden am Ende aufsteigend nach
|
||||
TeileId sortiert (numerische IDs) und die Elementnummer (erste Spalte)
|
||||
danach neu von 1 an vergeben (siehe teileid_sort_key in process_blocks) -
|
||||
wurde kein Element geloescht, stimmen Elementnummer und TeileId dadurch
|
||||
ueberein, geloeschte Elemente hinterlassen Luecken in der TeileId-Folge.
|
||||
Zeilen ohne numerische TeileId (Omniflo-Sum-Zeile, SEP-/SCN-Fallback-IDs
|
||||
ohne ID-Attribut) behalten stabil ihre bisherige Reihenfolge und stehen
|
||||
danach.
|
||||
Fuer die vollstaendige Herleitung jeder Spalte (Nachbarn/TrackIds/sepliste/
|
||||
Fehler/Warnungen, inkl. eines durchgerechneten Beispiels Kreisel+VarioFoerderer
|
||||
von export_raw.json bis zur fertigen CSV-Zeile) siehe doc/csv-export.md.
|
||||
"""
|
||||
|
||||
import json
|
||||
@@ -353,6 +263,23 @@ def build_btmt_merkmale(block):
|
||||
}
|
||||
|
||||
|
||||
def build_geruest_merkmale(block):
|
||||
"""Merkmale-Dict fuer einen GR_-Geruest-Baugruppenblock (siehe
|
||||
pattern_geruest in cfg/export.cfg, GeruestInsert.lsp *geruest-attrib-defs*).
|
||||
|
||||
ARTINR/LAENGE/BEZEICHNUNG wandern in feste CSV-Spalten (teileid/
|
||||
bezeichnung ueben in process_blocks unten), TEILEART/FARBE/LAYER bleiben
|
||||
als Rest-Attribute in der Merkmale-JSON-Spalte - so wie bei Separator/
|
||||
Scanner/BTMT bereits ueblich."""
|
||||
attribs = block.get("attribs", {})
|
||||
return {
|
||||
"TeileArt": attribs.get("TEILEART", ""),
|
||||
"Farbe": attribs.get("FARBE", ""),
|
||||
"Laenge": attribs.get("LAENGE", ""),
|
||||
"Layer": attribs.get("LAYER", ""),
|
||||
}
|
||||
|
||||
|
||||
def format_sensor_id(prefix, n):
|
||||
"""Fallback-TeileId fuer Separator/Scanner-Zeilen im CSV-Export, falls das
|
||||
Block-Attribut "ID" (noch) leer ist.
|
||||
@@ -959,6 +886,7 @@ def process_blocks(blocks, lookup, dbg=None):
|
||||
scanner_count = 0
|
||||
btmt_beladung_count = 0
|
||||
btmt_entladung_count = 0
|
||||
geruest_count = 0
|
||||
|
||||
# Zaehlung fuer die Omniflo-Sum-Zeile (nur Bogen/Weiche/Gerade)
|
||||
cnt_wk = cnt_einzel = cnt_delta = cnt_doppel = cnt_stern = 0
|
||||
@@ -1231,6 +1159,30 @@ def process_blocks(blocks, lookup, dbg=None):
|
||||
})
|
||||
continue
|
||||
|
||||
# Geruest-Baugruppe (GR_<id>_<timestamp>) - eigene TeileArt-Zeile,
|
||||
# analog zu BTMT: kein ANZAHL_*-Attribut an einem Carrier zaehlt sie
|
||||
# mit. TeileId ist das echte ID-Attribut (ssg-id-check-all fuellt es
|
||||
# vor jedem Export, siehe *geruest-attrib-defs*); ARTINR (Sivas-IDs,
|
||||
# ggf. mehrere kommagetrennt) landet als eigene Spalte in den
|
||||
# Merkmalen statt in "teileart" - anders als bei Kreisel/BTMT ist
|
||||
# "TEILEART" hier ein FREIES Attribut (Rohrabhaenger/Saeule/...), keine
|
||||
# feste Konstante.
|
||||
if matches_any(bname, BLOCKPATTERNS.get("pattern_geruest", [])):
|
||||
elem_nr += 1
|
||||
geruest_count += 1
|
||||
attribs = block.get("attribs", {})
|
||||
bezeichnung = attribs.get("BEZEICHNUNG", "").strip()
|
||||
items.append({
|
||||
"nr": elem_nr,
|
||||
"teileart": "Geruest",
|
||||
"teileid": attribs.get("ID") or format_sensor_id("GR", geruest_count),
|
||||
"bezeichnung": bezeichnung if bezeichnung else f"Geruest :{geruest_count}",
|
||||
"planquadrat": planquadrat_column(block, planquadrat_cfg),
|
||||
"merkmale": {"ARTINR": attribs.get("ARTINR", ""), **build_geruest_merkmale(block)},
|
||||
**bbox_columns(block),
|
||||
})
|
||||
continue
|
||||
|
||||
if has_omniflo:
|
||||
elem_nr += 1
|
||||
items.append({
|
||||
|
||||
@@ -288,6 +288,21 @@ def build_eckrad_details(block):
|
||||
}
|
||||
|
||||
|
||||
def build_geruest_details(block):
|
||||
"""Merkmale-Dict fuer eine GR_-Geruest-Baugruppe (siehe pattern_geruest in
|
||||
cfg/export.cfg, GeruestInsert.lsp *geruest-attrib-defs*). ARTINR/
|
||||
BEZEICHNUNG/TEILEART/LAENGE wandern in feste Sivas-Spalten (sivasnr/
|
||||
bezeichnung/teileart/laenge_mm), FARBE bleibt als Rest-Attribut hier.
|
||||
LAYER ist reine BricsCAD-Zeichnungsinformation ohne Sivas-Bedeutung und
|
||||
wird bewusst NICHT mit exportiert (anders als im CSV-Export
|
||||
export_csv.py, wo sie fuer die Zuordnung in der Zeichnung nuetzlich
|
||||
bleibt)."""
|
||||
attribs = block.get("attribs", {})
|
||||
return {
|
||||
"Farbe": attribs.get("FARBE", ""),
|
||||
}
|
||||
|
||||
|
||||
# --- Bekannte Bloecke ignorieren ---
|
||||
SKIP_BLOCKS = set(BLOCKPATTERNS.get("pattern_ks_subblocks", ["K1", "K2", "K3", "K4", "KS_EIN", "KS_AUS"]))
|
||||
|
||||
@@ -339,6 +354,7 @@ def process_blocks(blocks, lookup):
|
||||
btmt_beladung_bezeichnungen = []
|
||||
btmt_entladung_ids = [] # IDs aller SC_Entladung*-Bloecke (eine gruppierte Zeile)
|
||||
btmt_entladung_bezeichnungen = []
|
||||
geruest_list = [] # Liste von GR_-Geruest-Baugruppenbloecken, je einer Zeile
|
||||
|
||||
counters = {
|
||||
"anzahl_boegen": 0,
|
||||
@@ -369,6 +385,7 @@ def process_blocks(blocks, lookup):
|
||||
"anzahl_scanner": 0,
|
||||
"anzahl_btbeladung": 0,
|
||||
"anzahl_abwurfstationen": 0,
|
||||
"anzahl_geruest": 0,
|
||||
}
|
||||
|
||||
for block in blocks:
|
||||
@@ -398,6 +415,18 @@ def process_blocks(blocks, lookup):
|
||||
counters["anzahl_abwurfstationen"] += 1
|
||||
continue
|
||||
|
||||
# --- Geruest-Baugruppe ---
|
||||
# Anders als BTMT/Separator je Block eine EIGENE Zeile statt gruppiert:
|
||||
# ARTINR (Sivas-IDs) und Laenge/Farbe koennen von Block zu Block
|
||||
# unterschiedlich sein (freie Basis-Variante+Anbauteile-Auswahl je
|
||||
# GERUEST_*-Aufruf), eine Gruppierung wuerde das verschleiern - wie
|
||||
# bei VF_N/Kreisel oben, die aus demselben Grund ebenfalls einzeln
|
||||
# bleiben.
|
||||
if matches_any(bname, BLOCKPATTERNS.get("pattern_geruest", [])):
|
||||
geruest_list.append(block)
|
||||
counters["anzahl_geruest"] += 1
|
||||
continue
|
||||
|
||||
# --- Omniflo Bogen oder Weiche (erkannt via Katalog) ---
|
||||
if bname in lookup:
|
||||
typ, eintrag = lookup[bname]
|
||||
@@ -702,6 +731,40 @@ def process_blocks(blocks, lookup):
|
||||
})
|
||||
nr += 1
|
||||
|
||||
# Geruest-Baugruppen (GR_<id>_<timestamp>) - je Block eine eigene Zeile
|
||||
# (siehe Kommentar bei geruest_list oben). Sivasnr kommt direkt aus dem
|
||||
# ARTINR-Attribut - kann mehrere, kommagetrennte Sivas-IDs enthalten
|
||||
# (Baugruppe aus mehreren Einzelteilen, siehe ssg-join in
|
||||
# GeruestInsert.lsp) und dieselbe ID mehrfach (menge>1 je Einzelteil).
|
||||
# Anders als bei den uebrigen Teilearten also KEIN fester Eintrag aus
|
||||
# ILS_SIVASNR - JEDE Artikelnummer bekommt ihre EIGENE Sivas-Zeile (Sivas
|
||||
# kennt nur eine Sivasnr je Zeile), gleiche Artikelnummern INNERHALB
|
||||
# derselben Baugruppe werden dabei zu einer Zeile mit anzahl>1
|
||||
# zusammengefasst (wie bogen_groups/weiche_groups oben). Die volle
|
||||
# LAENGE der Baugruppe steht auf JEDER so entstandenen Zeile - Sivas hat
|
||||
# kein Konzept einer "gemeinsamen" Laenge ueber mehrere Zeilen hinweg.
|
||||
for block in geruest_list:
|
||||
attribs = block.get("attribs", {})
|
||||
artinr_list = [a.strip() for a in attribs.get("ARTINR", "").split(",") if a.strip()]
|
||||
artinr_groups = {}
|
||||
for artinr in artinr_list:
|
||||
artinr_groups.setdefault(artinr, 0)
|
||||
artinr_groups[artinr] += 1
|
||||
for artinr, anzahl in artinr_groups.items():
|
||||
items.append({
|
||||
"nr": nr,
|
||||
"teileart": attribs.get("TEILEART", "Geruest"),
|
||||
"sivasnr": artinr,
|
||||
"sivasnr_quoted": True,
|
||||
"bezeichnung": attribs.get("BEZEICHNUNG", ""),
|
||||
"dispgruppe": 20,
|
||||
"anzahl": anzahl,
|
||||
"laenge_mm": attribs.get("LAENGE", ""),
|
||||
"ids": [get_id(block)],
|
||||
"details": build_geruest_details(block),
|
||||
})
|
||||
nr += 1
|
||||
|
||||
# VarioFoerderer-Compound-Bloecke (VF_N) - je Block eine eigene Zeile mit
|
||||
# vollstaendigen Gefaelle-/Angetrieben-Teilgruppen (immer TYP "Streckengruppe").
|
||||
for block in vario_list:
|
||||
|
||||
+181
-125
@@ -530,205 +530,229 @@
|
||||
<Command>^C^C(ssg-ensure "OmniModulInsert") OMNI_EDIT</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00115">
|
||||
<MenuMacro UID="MM_00114">
|
||||
<Macro>
|
||||
<Name>Rohrabhaenger</Name>
|
||||
<Command>^C^C(ssg-ensure "GeruestInsert") GERUEST_ROHRABHAENGER</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00116">
|
||||
<Macro>
|
||||
<Name>2 Zoll Saeulen</Name>
|
||||
<Command>^C^C(ssg-ensure "GeruestInsert") GERUEST_SAEULE_2ZOLL</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00117">
|
||||
<Macro>
|
||||
<Name>1 Zoll Saeulen</Name>
|
||||
<Command>^C^C(ssg-ensure "GeruestInsert") GERUEST_SAEULE_1ZOLL</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00118">
|
||||
<Macro>
|
||||
<Name>Wandbefestigung</Name>
|
||||
<Command>^C^C(ssg-ensure "GeruestInsert") GERUEST_WANDBEFESTIGUNG</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00121">
|
||||
<Macro>
|
||||
<Name>Marker einfuegen</Name>
|
||||
<Command>^C^C(ssg-ensure "Tro_Edit") TRO_INSERT</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00116">
|
||||
<MenuMacro UID="MM_00122">
|
||||
<Macro>
|
||||
<Name>Marker bearbeiten</Name>
|
||||
<Command>^C^C(ssg-ensure "Tro_Edit") TRO_EDIT</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00117">
|
||||
<MenuMacro UID="MM_00123">
|
||||
<Macro>
|
||||
<Name>Bearbeiten (Auto)</Name>
|
||||
<Command>^C^C(ssg-ensure "SSG_LIB_Commands") SSG_BLOCKEDIT</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00119">
|
||||
<MenuMacro UID="MM_00125">
|
||||
<Macro>
|
||||
<Name>Verbindung einfuegen</Name>
|
||||
<Command>^C^C(ssg-ensure "Connection_Edit") CONNECTION_INSERT</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00120">
|
||||
<MenuMacro UID="MM_00126">
|
||||
<Macro>
|
||||
<Name>Verbindung bearbeiten</Name>
|
||||
<Command>^C^C(ssg-ensure "Connection_Edit") CONNECTION_EDIT</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00122">
|
||||
<MenuMacro UID="MM_00128">
|
||||
<Macro>
|
||||
<Name>Eingang</Name>
|
||||
<Command>^C^C(ssg-ensure "SSG_LIB_Commands") ILS_EINGANG_INSERT</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00123">
|
||||
<MenuMacro UID="MM_00129">
|
||||
<Macro>
|
||||
<Name>Ausgang</Name>
|
||||
<Command>^C^C(ssg-ensure "SSG_LIB_Commands") ILS_AUSGANG_INSERT</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00124">
|
||||
<MenuMacro UID="MM_00130">
|
||||
<Macro>
|
||||
<Name>SPS Schliessen</Name>
|
||||
<Command>^C^C</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00126">
|
||||
<MenuMacro UID="MM_00132">
|
||||
<Macro>
|
||||
<Name>Export Sivas</Name>
|
||||
<Command>^C^C(ssg-ensure "export") EXPORTSIVAS</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00127">
|
||||
<MenuMacro UID="MM_00133">
|
||||
<Macro>
|
||||
<Name>Export CSV</Name>
|
||||
<Command>^C^C(ssg-ensure "export") EXPORTCSV</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00129">
|
||||
<MenuMacro UID="MM_00135">
|
||||
<Macro>
|
||||
<Name>Umschalten 2D und 3D</Name>
|
||||
<Command>^C^C(ssg-ensure "SSG_LIB_Commands") SSG_DIM_SWITCH</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00130">
|
||||
<MenuMacro UID="MM_00136">
|
||||
<Macro>
|
||||
<Name>Alle Bloecke auf 2D</Name>
|
||||
<Command>^C^C(ssg-ensure "SSG_LIB_Commands") SSG_DIM_ALL_2D</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00131">
|
||||
<MenuMacro UID="MM_00137">
|
||||
<Macro>
|
||||
<Name>Alle Bloecke auf 3D</Name>
|
||||
<Command>^C^C(ssg-ensure "SSG_LIB_Commands") SSG_DIM_ALL_3D</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00132">
|
||||
<MenuMacro UID="MM_00138">
|
||||
<Macro>
|
||||
<Name>Sprache</Name>
|
||||
<Command>^C^C(ssg-ensure "SSG_LIB_Commands") SSG_SPRACHE</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00133">
|
||||
<MenuMacro UID="MM_00139">
|
||||
<Macro>
|
||||
<Name>Planquadrate an/aus</Name>
|
||||
<Command>^C^C(ssg-ensure "DrawPlanquadrate") PLANQUADRATE_TOGGLE</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00136">
|
||||
<MenuMacro UID="MM_00142">
|
||||
<Macro>
|
||||
<Name>alle Tests ausfuehren und exportieren</Name>
|
||||
<Command>^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_run_all.lsp")) SSG_RUN_ALL_TESTS_EXPORT</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00137">
|
||||
<MenuMacro UID="MM_00143">
|
||||
<Macro>
|
||||
<Name>Tests ausfuehren und stehen lassen</Name>
|
||||
<Command>^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_run_all.lsp")) SSG_RUN_ALL_TESTS_OFFEN</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00138">
|
||||
<MenuMacro UID="MM_00144">
|
||||
<Macro>
|
||||
<Name>Export CSV/Sivas ALL</Name>
|
||||
<Command>^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_export_all.lsp")) TEST_EXPORT_ALL</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00140">
|
||||
<MenuMacro UID="MM_00146">
|
||||
<Macro>
|
||||
<Name>Kreisel</Name>
|
||||
<Command>^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_kreisel.lsp")) TEST_KREISEL</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00141">
|
||||
<MenuMacro UID="MM_00147">
|
||||
<Macro>
|
||||
<Name>Foerderer</Name>
|
||||
<Command>^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_foerderer.lsp")) TEST_FOERDERER</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00142">
|
||||
<MenuMacro UID="MM_00148">
|
||||
<Macro>
|
||||
<Name>Foerderer-Linienzug</Name>
|
||||
<Command>^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_linienzug.lsp")) TEST_LINIENZUG TEST_LINIENZUG_STUFE2</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00143">
|
||||
<MenuMacro UID="MM_00149">
|
||||
<Macro>
|
||||
<Name>Omniflo</Name>
|
||||
<Command>^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_omniflo.lsp")) TEST_OMNIFLO</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00144">
|
||||
<MenuMacro UID="MM_00150">
|
||||
<Macro>
|
||||
<Name>Omniflo Strecke</Name>
|
||||
<Command>^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_omniflo_strecke.lsp")) TEST_OMNIFLO_STRECKE</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00145">
|
||||
<MenuMacro UID="MM_00151">
|
||||
<Macro>
|
||||
<Name>Gefaellestrecke</Name>
|
||||
<Command>^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_gefaellestrecke.lsp")) TEST_GEFAELLESTRECKE</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00146">
|
||||
<MenuMacro UID="MM_00152">
|
||||
<Macro>
|
||||
<Name>Mubea Gesamtmodell</Name>
|
||||
<Command>^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_mubea.lsp")) TEST_MUBEA</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00147">
|
||||
<MenuMacro UID="MM_00153">
|
||||
<Macro>
|
||||
<Name>HundM05 Kreisel-Abschnitt</Name>
|
||||
<Command>^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_hundm05.lsp")) TEST_HUNDM05</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00148">
|
||||
<MenuMacro UID="MM_00154">
|
||||
<Macro>
|
||||
<Name>KS 2D/3D pruefen (CSV)</Name>
|
||||
<Command>^C^C(load (strcat (getenv "DXFMAKRO") "/Lisp/ks_pruefung.lsp")) KS_PRUEFEN</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00160">
|
||||
<MenuMacro UID="MM_00166">
|
||||
<Macro>
|
||||
<Name>Kreisel bearbeiten</Name>
|
||||
<Command>(ssg-ensure "KreiselInsert") KreiselEdit</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00161">
|
||||
<MenuMacro UID="MM_00167">
|
||||
<Macro>
|
||||
<Name>Omniflo Element bearbeiten</Name>
|
||||
<Command>(ssg-ensure "OmniModulInsert") OMNI_EDIT</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00162">
|
||||
<MenuMacro UID="MM_00168">
|
||||
<Macro>
|
||||
<Name>Gefaellestrecke bearbeiten</Name>
|
||||
<Command>(ssg-ensure "Gefaellestrecke") GEFAELLESTRECKE_EDIT</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00163">
|
||||
<MenuMacro UID="MM_00169">
|
||||
<Macro>
|
||||
<Name>VarioFoerderer bearbeiten</Name>
|
||||
<Command>(ssg-ensure "VarioFoerderer") VARIOFOERDERER_EDIT</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00164">
|
||||
<MenuMacro UID="MM_00170">
|
||||
<Macro>
|
||||
<Name>TRO-Marker bearbeiten</Name>
|
||||
<Command>(ssg-ensure "Tro_Edit") TRO_EDIT</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00165">
|
||||
<MenuMacro UID="MM_00171">
|
||||
<Macro>
|
||||
<Name>Verbindung bearbeiten</Name>
|
||||
<Command>(ssg-ensure "Connection_Edit") CONNECTION_EDIT</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00167">
|
||||
<MenuMacro UID="MM_00173">
|
||||
<Macro>
|
||||
<Name>SSG Bearbeiten (Auto)</Name>
|
||||
<Command>(ssg-ensure "SSG_LIB_Commands") SSG_BLOCKEDIT</Command>
|
||||
@@ -746,9 +770,10 @@
|
||||
<PopMenuRef pUID="PM_00005"/>
|
||||
<PopMenuRef pUID="PM_00031"/>
|
||||
<PopMenuRef pUID="PM_00113"/>
|
||||
<PopMenuRef pUID="PM_00125"/>
|
||||
<PopMenuRef pUID="PM_00128"/>
|
||||
<PopMenuRef pUID="PM_00135"/>
|
||||
<PopMenuRef pUID="PM_00119"/>
|
||||
<PopMenuRef pUID="PM_00131"/>
|
||||
<PopMenuRef pUID="PM_00134"/>
|
||||
<PopMenuRef pUID="PM_00141"/>
|
||||
</PopMenu>
|
||||
<PopMenu UID="PM_00005">
|
||||
<Name>ILS</Name>
|
||||
@@ -1342,244 +1367,275 @@
|
||||
</PopMenuItem>
|
||||
</PopMenu>
|
||||
<PopMenu UID="PM_00113">
|
||||
<Name>SPS</Name>
|
||||
<PopMenuRef pUID="PM_00114"/>
|
||||
<PopMenuRef pUID="PM_00118"/>
|
||||
<Name>Geruest</Name>
|
||||
<PopMenuItem>
|
||||
<NameRef>Eingang</NameRef>
|
||||
<NameRef>Rohrabhaenger</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00122"/>
|
||||
<MacroRef MenuMacroID="MM_00114"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuRef pUID="PM_00115"/>
|
||||
<PopMenuItem>
|
||||
<NameRef>Ausgang</NameRef>
|
||||
<NameRef>Wandbefestigung</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00123"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>SPS Schliessen</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00124"/>
|
||||
<MacroRef MenuMacroID="MM_00118"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
</PopMenu>
|
||||
<PopMenu UID="PM_00114">
|
||||
<Name>TRO</Name>
|
||||
<PopMenu UID="PM_00115">
|
||||
<Name>Saeulen</Name>
|
||||
<PopMenuItem>
|
||||
<NameRef>Marker einfuegen</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00115"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Marker bearbeiten</NameRef>
|
||||
<NameRef>2 Zoll Saeulen</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00116"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Bearbeiten (Auto)</NameRef>
|
||||
<NameRef>1 Zoll Saeulen</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00117"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
</PopMenu>
|
||||
<PopMenu UID="PM_00118">
|
||||
<Name>Connections</Name>
|
||||
<PopMenu UID="PM_00119">
|
||||
<Name>SPS</Name>
|
||||
<PopMenuRef pUID="PM_00120"/>
|
||||
<PopMenuRef pUID="PM_00124"/>
|
||||
<PopMenuItem>
|
||||
<NameRef>Verbindung einfuegen</NameRef>
|
||||
<NameRef>Eingang</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00119"/>
|
||||
<MacroRef MenuMacroID="MM_00128"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Verbindung bearbeiten</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00120"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Bearbeiten (Auto)</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00117"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
</PopMenu>
|
||||
<PopMenu UID="PM_00125">
|
||||
<Name>Export</Name>
|
||||
<PopMenuItem>
|
||||
<NameRef>Export Sivas</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00126"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Export CSV</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00127"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
</PopMenu>
|
||||
<PopMenu UID="PM_00128">
|
||||
<Name>Konfiguration</Name>
|
||||
<PopMenuItem>
|
||||
<NameRef>Umschalten 2D und 3D</NameRef>
|
||||
<NameRef>Ausgang</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00129"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Alle Bloecke auf 2D</NameRef>
|
||||
<NameRef>SPS Schliessen</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00130"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
</PopMenu>
|
||||
<PopMenu UID="PM_00120">
|
||||
<Name>TRO</Name>
|
||||
<PopMenuItem>
|
||||
<NameRef>Alle Bloecke auf 3D</NameRef>
|
||||
<NameRef>Marker einfuegen</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00131"/>
|
||||
<MacroRef MenuMacroID="MM_00121"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Sprache</NameRef>
|
||||
<NameRef>Marker bearbeiten</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00122"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Bearbeiten (Auto)</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00123"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
</PopMenu>
|
||||
<PopMenu UID="PM_00124">
|
||||
<Name>Connections</Name>
|
||||
<PopMenuItem>
|
||||
<NameRef>Verbindung einfuegen</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00125"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Verbindung bearbeiten</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00126"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Bearbeiten (Auto)</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00123"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
</PopMenu>
|
||||
<PopMenu UID="PM_00131">
|
||||
<Name>Export</Name>
|
||||
<PopMenuItem>
|
||||
<NameRef>Export Sivas</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00132"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Planquadrate an/aus</NameRef>
|
||||
<NameRef>Export CSV</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00133"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
</PopMenu>
|
||||
<PopMenu UID="PM_00134">
|
||||
<Name>Konfiguration</Name>
|
||||
<PopMenuItem>
|
||||
<NameRef>Konfiguration Schliessen</NameRef>
|
||||
<NameRef>Umschalten 2D und 3D</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00124"/>
|
||||
<MacroRef MenuMacroID="MM_00135"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
</PopMenu>
|
||||
<PopMenu UID="PM_00135">
|
||||
<Name>Tests</Name>
|
||||
<PopMenuItem>
|
||||
<NameRef>alle Tests ausfuehren und exportieren</NameRef>
|
||||
<NameRef>Alle Bloecke auf 2D</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00136"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Tests ausfuehren und stehen lassen</NameRef>
|
||||
<NameRef>Alle Bloecke auf 3D</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00137"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Export CSV/Sivas ALL</NameRef>
|
||||
<NameRef>Sprache</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00138"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Planquadrate an/aus</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00139"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Konfiguration Schliessen</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00130"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
</PopMenu>
|
||||
<PopMenu UID="PM_00141">
|
||||
<Name>Tests</Name>
|
||||
<PopMenuItem>
|
||||
<NameRef>alle Tests ausfuehren und exportieren</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00142"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Tests ausfuehren und stehen lassen</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00143"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Export CSV/Sivas ALL</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00144"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem IsSeparator="true"/>
|
||||
<PopMenuItem>
|
||||
<NameRef>Kreisel</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00140"/>
|
||||
<MacroRef MenuMacroID="MM_00146"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Foerderer</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00141"/>
|
||||
<MacroRef MenuMacroID="MM_00147"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Foerderer-Linienzug</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00142"/>
|
||||
<MacroRef MenuMacroID="MM_00148"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Omniflo</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00143"/>
|
||||
<MacroRef MenuMacroID="MM_00149"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Omniflo Strecke</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00144"/>
|
||||
<MacroRef MenuMacroID="MM_00150"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Gefaellestrecke</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00145"/>
|
||||
<MacroRef MenuMacroID="MM_00151"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Mubea Gesamtmodell</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00146"/>
|
||||
<MacroRef MenuMacroID="MM_00152"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>HundM05 Kreisel-Abschnitt</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00147"/>
|
||||
<MacroRef MenuMacroID="MM_00153"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>KS 2D/3D pruefen (CSV)</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00148"/>
|
||||
<MacroRef MenuMacroID="MM_00154"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
</PopMenu>
|
||||
<PopMenu UID="PM_00159">
|
||||
<PopMenu UID="PM_00165">
|
||||
<Alias>POP501</Alias>
|
||||
<Name>SSG_LIB Edit Context</Name>
|
||||
<PopMenuItem>
|
||||
<NameRef>Kreisel bearbeiten</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00160"/>
|
||||
<MacroRef MenuMacroID="MM_00166"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Omniflo Element bearbeiten</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00161"/>
|
||||
<MacroRef MenuMacroID="MM_00167"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Gefaellestrecke bearbeiten</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00162"/>
|
||||
<MacroRef MenuMacroID="MM_00168"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>VarioFoerderer bearbeiten</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00163"/>
|
||||
<MacroRef MenuMacroID="MM_00169"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>TRO-Marker bearbeiten</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00164"/>
|
||||
<MacroRef MenuMacroID="MM_00170"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Verbindung bearbeiten</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00165"/>
|
||||
<MacroRef MenuMacroID="MM_00171"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem IsSeparator="true"/>
|
||||
<PopMenuItem>
|
||||
<NameRef>SSG Bearbeiten (Auto)</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00167"/>
|
||||
<MacroRef MenuMacroID="MM_00173"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
</PopMenu>
|
||||
|
||||
@@ -110,6 +110,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]
|
||||
[Rohrabhaenger]^C^C(ssg-ensure "GeruestInsert") GERUEST_ROHRABHAENGER
|
||||
[->Saeulen]
|
||||
[2 Zoll Saeulen]^C^C(ssg-ensure "GeruestInsert") GERUEST_SAEULE_2ZOLL
|
||||
[<-1 Zoll Saeulen]^C^C(ssg-ensure "GeruestInsert") GERUEST_SAEULE_1ZOLL
|
||||
[<-Wandbefestigung]^C^C(ssg-ensure "GeruestInsert") GERUEST_WANDBEFESTIGUNG
|
||||
[->SPS]
|
||||
[->TRO]
|
||||
[Marker einfuegen]^C^C(ssg-ensure "Tro_Edit") TRO_INSERT
|
||||
|
||||
@@ -424,6 +424,134 @@
|
||||
)
|
||||
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; TESTS: ssg_core.lsp - rekursiver JSON-Parser + ssg-join
|
||||
;; ------------------------------------------------------------
|
||||
(defun tu-tests-json ( / _p _datei _daten _bg _var _anb)
|
||||
(princ "\n[ssg_core/json]")
|
||||
|
||||
;; ssg-join
|
||||
(tu-eq "ssg-join/leer" "" (ssg-join '() ","))
|
||||
(tu-eq "ssg-join/eins" "a" (ssg-join '("a") ","))
|
||||
(tu-eq "ssg-join/drei" "a,b,c" (ssg-join '("a" "b" "c") ","))
|
||||
(tu-eq "ssg-join/plus" "a + b" (ssg-join '("a" "b") " + "))
|
||||
|
||||
;; Skalare und flaches Objekt
|
||||
(tu-eq "json/objekt-flach" '(("a" . 1)) (ssg-json-parse "{\"a\": 1}"))
|
||||
(tu-eq "json/zwei-keys" '(("a" . 1) ("b" . 2))
|
||||
(ssg-json-parse "{\"a\": 1, \"b\": 2}"))
|
||||
(tu-eq "json/string" "hallo" (ssg-json-get (ssg-json-parse "{\"a\": \"hallo\"}") "a"))
|
||||
(tu-eq "json/int" 6000 (ssg-json-get (ssg-json-parse "{\"a\": 6000}") "a"))
|
||||
(tu-eqf "json/real" 1.5 (ssg-json-get (ssg-json-parse "{\"a\": 1.5}") "a"))
|
||||
(tu-eq "json/true" T (ssg-json-get (ssg-json-parse "{\"a\": true}") "a"))
|
||||
(tu-eq "json/false" nil (ssg-json-get (ssg-json-parse "{\"a\": false}") "a"))
|
||||
(tu-eq "json/null" nil (ssg-json-get (ssg-json-parse "{\"a\": null}") "a"))
|
||||
|
||||
;; Verschachtelung - genau das, was die alten Zeilen-Parser nicht koennen
|
||||
(tu-eq "json/objekt-verschachtelt" '(("a" ("b" . 2)))
|
||||
(ssg-json-parse "{\"a\": {\"b\": 2}}"))
|
||||
(tu-eq "json/array" '(("a" 1 2 3))
|
||||
(ssg-json-parse "{\"a\": [1, 2, 3]}"))
|
||||
(tu-eq "json/array-objekte" '(("a" (("b" . 1)) (("b" . 2))))
|
||||
(ssg-json-parse "{\"a\": [{\"b\": 1}, {\"b\": 2}]}"))
|
||||
(tu-eq "json/array-leer" '(("a")) (ssg-json-parse "{\"a\": []}"))
|
||||
|
||||
;; Mehrzeilig (alte Parser verlangen Arrays in EINER Zeile)
|
||||
(tu-eq "json/mehrzeilig" '(("a" "x" "y"))
|
||||
(ssg-json-parse "{\n \"a\": [\n \"x\",\n \"y\"\n ]\n}"))
|
||||
|
||||
;; Maskiertes Anfuehrungszeichen und Komma im String - beides kommt in den
|
||||
;; Geruest-Artikelbezeichnungen real vor ("ROHR R 1\" 33,7 x 2,6")
|
||||
(tu-eq "json/escape-quote" "R 1\" x"
|
||||
(ssg-json-get (ssg-json-parse "{\"a\": \"R 1\\\" x\"}") "a"))
|
||||
(tu-eq "json/komma-im-string" "33,7 x 2,6"
|
||||
(ssg-json-get (ssg-json-parse "{\"a\": \"33,7 x 2,6\"}") "a"))
|
||||
(tu-eq "json/escape-backslash" "a\\b"
|
||||
(ssg-json-get (ssg-json-parse "{\"a\": \"a\\\\b\"}") "a"))
|
||||
(tu-eq "json/escape-newline" (chr 10)
|
||||
(ssg-json-get (ssg-json-parse "{\"a\": \"\\n\"}") "a"))
|
||||
|
||||
;; Echte Datendatei: der eigentliche Praxisfall
|
||||
(setq _datei (strcat (getenv "DXFMAKRO") "/data/json/geruest.json"))
|
||||
(if (findfile _datei)
|
||||
(progn
|
||||
(setq _daten (ssg-json-laden _datei))
|
||||
(tu-eq "json/geruest-baugruppen" 4 (length _daten))
|
||||
;; Baugruppe ueber das ASCII-Feld "id" finden (aeusserer Schluessel
|
||||
;; traegt Umlaute bzw. Anfuehrungszeichen)
|
||||
(setq _bg nil)
|
||||
(foreach _e _daten
|
||||
(if (and (null _bg) (= (ssg-json-get (cdr _e) "id") "Rohrabhaenger"))
|
||||
(setq _bg (cdr _e))))
|
||||
(tu-eq "json/geruest-id-gefunden" T (if _bg T nil))
|
||||
(if _bg
|
||||
(progn
|
||||
(setq _var (ssg-json-get _bg "geometrie_varianten"))
|
||||
(setq _anb (ssg-json-get _bg "anbaugruppen"))
|
||||
(tu-eq "json/geruest-varianten" 3 (length _var))
|
||||
(tu-eq "json/geruest-teileart" "Geruest Rohrabhaenger"
|
||||
(ssg-json-get _bg "teileart"))
|
||||
(tu-eq "json/geruest-dummy" "Rohrabhaenger_dummy.dwg"
|
||||
(ssg-json-get _bg "dummy"))
|
||||
;; Sivas-ID als Zahl geparst, Laengengrenze aus dem attribute-Block
|
||||
(tu-eq "json/geruest-sivas" 821006026
|
||||
(ssg-json-get (car (ssg-json-get (car _var) "teile")) "sivas_id"))
|
||||
(tu-eq "json/geruest-max" 6000
|
||||
(ssg-json-get (ssg-json-get (ssg-json-get _bg "attribute") "Laenge") "max"))
|
||||
)
|
||||
)
|
||||
)
|
||||
(tu-record nil "json/geruest-datei" (strcat "nicht gefunden: " _datei))
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; TESTS: GeruestInsert.lsp - reine Hilfsfunktionen
|
||||
;; ------------------------------------------------------------
|
||||
(defun tu-tests-geruest ( / _eintrag _gruppe)
|
||||
(princ "\n[GeruestInsert]")
|
||||
(if (and (null (atoms-family 1 '("GERUEST-ARTIKELNUMMERN")))
|
||||
(atoms-family 1 '("SSG-ENSURE")))
|
||||
(ssg-ensure "GeruestInsert")
|
||||
)
|
||||
(if (null (atoms-family 1 '("GERUEST-ARTIKELNUMMERN")))
|
||||
(tu-record nil "geruest/modul" "GeruestInsert.lsp nicht geladen")
|
||||
(progn
|
||||
;; Indizes aus get_tile bei multiple_select
|
||||
(tu-eq "geruest-indizes/leer" '() (geruest-indizes ""))
|
||||
(tu-eq "geruest-indizes/eins" '(0) (geruest-indizes "0"))
|
||||
(tu-eq "geruest-indizes/drei" '(0 3 5) (geruest-indizes "0 3 5"))
|
||||
|
||||
(tu-eq "geruest-id-string/int" "821006026" (geruest-id-string 821006026))
|
||||
(tu-eq "geruest-id-string/str" "0_B10071" (geruest-id-string "0_B10071"))
|
||||
(tu-eq "geruest-id-string/nil" nil (geruest-id-string nil))
|
||||
|
||||
;; Einzelteil mit menge 2 -> Artikelnummer zweimal (ARTINR-Regel)
|
||||
(setq _eintrag (ssg-json-parse
|
||||
"{\"artikel\": \"X\", \"sivas_id\": 825002019, \"menge\": 2}"))
|
||||
(tu-eq "geruest-artnr/menge2" '("825002019" "825002019")
|
||||
(geruest-artikelnummern _eintrag))
|
||||
(tu-eq "geruest-name/artikel" "X" (geruest-eintrag-name _eintrag))
|
||||
|
||||
;; Benannte Gruppe -> teile rekursiv aufloesen, Mengen beachten
|
||||
(setq _gruppe (ssg-json-parse
|
||||
(strcat "{\"name\": \"Schraubenset\", \"teile\": ["
|
||||
"{\"artikel\": \"A\", \"sivas_id\": 111, \"menge\": 1},"
|
||||
"{\"artikel\": \"B\", \"sivas_id\": 222, \"menge\": 2}]}")))
|
||||
(tu-eq "geruest-artnr/gruppe" '("111" "222" "222")
|
||||
(geruest-artikelnummern _gruppe))
|
||||
(tu-eq "geruest-name/gruppe" "Schraubenset" (geruest-eintrag-name _gruppe))
|
||||
|
||||
;; Fehlendes menge-Feld -> 1
|
||||
(tu-eq "geruest-artnr/ohne-menge" '("333")
|
||||
(geruest-artikelnummern
|
||||
(ssg-json-parse "{\"artikel\": \"C\", \"sivas_id\": 333}")))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; REPORT SCHREIBEN
|
||||
;; ------------------------------------------------------------
|
||||
@@ -467,6 +595,8 @@
|
||||
(tu-tests-omni)
|
||||
(tu-tests-kreisel)
|
||||
(tu-tests-sepliste)
|
||||
(tu-tests-json)
|
||||
(tu-tests-geruest)
|
||||
|
||||
(princ "\n\n----------------------------------------------------------------")
|
||||
(princ (strcat "\n Gesamt: " (itoa (+ *tu-pass* *tu-fail*))
|
||||
|
||||
Reference in New Issue
Block a user