From 9c7dda8a378617a7c9fd3321733985657346c2c4 Mon Sep 17 00:00:00 2001 From: Samer Ayadi Date: Mon, 3 Aug 2026 15:56:13 +0200 Subject: [PATCH] Add TRO_INSERT command to hand-place new TRO markers Lets the TRO menu insert a fresh TRO_SYM_ marker (point + type + auto-suggested TROnn id) by reusing a block definition tro_annotate.py already created, instead of only editing markers it placed. --- CLAUDE.md | 4 + Lisp/Tro_Edit.lsp | 183 ++++++++++++++++++++++++++++++++++++++++++--- dcl/tro_insert.dcl | 34 +++++++++ lang/de_DE.json | 7 +- lang/en_GB.json | 7 +- menu/SSG_LIB.mnu | 1 + 6 files changed, 223 insertions(+), 13 deletions(-) create mode 100644 dcl/tro_insert.dcl diff --git a/CLAUDE.md b/CLAUDE.md index ae4f203..ac85c10 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -66,6 +66,7 @@ Die `start_briscad.bat` ruft `setenv.bat` auf und startet BricsCAD. | Menue-Bereich | Modul | Befehle | |---|---|---| | Kreisel-Module | `KreiselInsert` | KreiselInsert, KreiselConnect, KreiselEdit, ILS_Eckrad | +| TRO | `Tro_Edit` | TRO_INSERT, TRO_EDIT | | Zusatzmodul/Foerderer/Kurven | `SSG_LIB_Commands` | ILS_BTMT_*, ILS_ETF_*, ILS_K*_*, ILS_GK*_* | | VarioFoerderer | `VarioFoerderer` | FOERDERANLAGE, VARIOFOERDERER_EDIT, Vario_Kette_Merge | | Gefaellestrecke | `Gefaellestrecke` | GEFAELLESTRECKE, GEFAELLESTRECKE_EDIT | @@ -97,6 +98,7 @@ Detaillierte Dokumentation aller Funktionen und Befehle: siehe `Lisp/README.md`. | `export.lsp` | EXPORTSIVAS, EXPORTCSV, OMNI_UPDATE_ATTRIBS | JSON-Sammlung und Python-Export (Omniflo-Merkmale/Sum-Zeile via lib/export_csv.py) | | `OmniModulInsert.lsp` | OMNI_LOAD, OMNI_APB_*, OMNI_W*_*, OMNI_AP60/AP110, OMNI_TEF_*, OMNI_TV_*, OMNI_APBW_*, OMNI_EDIT | Omniflo-Komponenten: Boegen, Weichen, Verbinder, Transferwagen, Edit-Dialog | | `SSG_LIB_Commands.lsp` | ILS_BTMT_*, ILS_ETF_*, ILS_K*_*, ILS_GK*_*, SSG_BLOCKEDIT, SSG_DIM_SWITCH, SSG_SPRACHE | Dummy-Befehle fuer Menue + Doppelklick/Kontextmenue-Dispatcher + Konfiguration (2D/3D, Sprache) | +| `Tro_Edit.lsp` | TRO_INSERT, TRO_EDIT | TRO-Marker (Block `TRO_SYM_`) fuer sps_skel (lib/tro_annotate.py): TRO_INSERT fuegt eine bestehende Blockdefinition an einem gewaehlten Punkt ein und setzt ID/TYPE (bricht ab, wenn der Typ noch keine Blockdefinition in der Zeichnung hat - die entsteht nur ueber tro_annotate.py); TRO_EDIT aendert ID/TYPE eines bestehenden Markers per Dialog. Typliste aus `tro_types.lsp` (von `tro_annotate.py --emit-lisp` nach DXFM_LISP geschrieben). Der Dispatcher SSG_BLOCKEDIT leitet Blocknamen `TRO_*` zu TRO_EDIT. | | `menu-inventory.lsp` | MenuInventory | BricsCAD Diagnostik (Menuegruppen, Plugins, Startdateien) | ## DCL-Dialoge @@ -109,6 +111,8 @@ Detaillierte Dokumentation aller Funktionen und Befehle: siehe `Lisp/README.md`. | `omniflo_boegen.dcl` | OMNI_APB_* (OmniModulInsert.lsp) | | `omniflo_weichen.dcl` | OMNI_W*_* (OmniModulInsert.lsp) | | `sprache.dcl` | SSG_SPRACHE (SSG_LIB_Commands.lsp) | +| `tro_insert.dcl` | TRO_INSERT (Tro_Edit.lsp) | +| `tro_edit.dcl` | TRO_EDIT (Tro_Edit.lsp) | ## Menue (SSG_LIB.mnu + SSG_LIB.mnl) diff --git a/Lisp/Tro_Edit.lsp b/Lisp/Tro_Edit.lsp index 5176e21..83cf9c2 100644 --- a/Lisp/Tro_Edit.lsp +++ b/Lisp/Tro_Edit.lsp @@ -1,14 +1,23 @@ ;; ============================================================ -;; TRO_EDIT.LSP - TRO-Marker bearbeiten +;; TRO_EDIT.LSP - TRO-Marker einfuegen und bearbeiten ;; -;; Bearbeitet die Attribute ID und TYPE eines TRO_*-Blocks. Die Marker -;; werden von sps_skel (lib/tro_annotate.py) in eine Kopie der Zeichnung -;; eingefuegt; ein Marker ist ein Block TRO_SYM_ mit den Attributen +;; Verwaltet die Attribute ID und TYPE eines TRO_*-Blocks. Die Marker +;; werden in der Regel von sps_skel (lib/tro_annotate.py) in eine Kopie der +;; Zeichnung eingefuegt; ein Marker ist ein Block TRO_SYM_ mit den +;; Attributen ;; ID, TYPE sichtbar ;; FB_BLOCK sichtbar (nur wenn mit --fb beschriftet) ;; ITEMS, CONFIDENCE, SEPARATORS unsichtbar, reine Daten ;; -;; Aufruf: +;; Aufruf TRO_INSERT (neuen Marker einfuegen): +;; - Menue SSG_LIB > TRO > Marker einfuegen +;; - direkt: TRO_INSERT +;; Fuegt eine bestehende TRO_SYM_-Blockdefinition ein - die Form +;; entsteht nur ueber tro_annotate.py, TRO_INSERT zeichnet keine neue. +;; Ohne einen frueheren Lauf mit dem gewuenschten Typ bricht der Befehl +;; mit einem Hinweis ab. +;; +;; Aufruf TRO_EDIT (Attribute eines bestehenden Markers aendern): ;; - Doppelklick auf den Marker -> ***DOUBLECLICK [INSERT] -> SSG_BLOCKEDIT ;; - EATTEDIT -> c:EATTEDIT -> SSG_BLOCKEDIT ;; - Menue SSG_LIB > TRO > Marker bearbeiten @@ -18,12 +27,14 @@ ;; ;; Die Auswahlliste der Typen kommt aus tro_types.lsp, die sps_skel mit ;; lib/tro_annotate.py --emit-lisp -;; nach DXFM_LISP schreibt. Fehlt die Datei, bleibt nur der aktuelle Typ des -;; Blocks in der Liste - der Dialog laeuft also weiter. +;; nach DXFM_LISP schreibt. Fehlt die Datei, bleibt bei TRO_EDIT nur der +;; aktuelle Typ des Blocks in der Liste; TRO_INSERT bricht dann ab (siehe +;; tro-insert-kein-typ). ;; -;; Grenze: geaendert werden nur die Attribute. Die *Form* des Markers gehoert -;; zur Blockdefinition des Typs und FB_BLOCK ist aus dem Typ abgeleitet - -;; beides passt erst nach einem neuen Lauf von tro_annotate.py wieder. +;; Grenze: TRO_EDIT aendert nur die Attribute, TRO_INSERT nur die Position - +;; die *Form* des Markers gehoert zur Blockdefinition des Typs und +;; FB_BLOCK ist aus dem Typ abgeleitet; beides passt erst nach einem neuen +;; Lauf von tro_annotate.py wieder. ;; ;; Setzt ssg_core.lsp (ssg-start/ssg-end, ssg-attrib-*) und ssg_lang.lsp voraus. ;; ============================================================ @@ -80,6 +91,156 @@ ) +;; ------------------------------------------------------------ +;; Zahl mit fuehrenden Nullen auf gegebene Breite auffuellen +;; ------------------------------------------------------------ +(defun tro-id-format (n breite / s) + (setq s (itoa n)) + (while (< (strlen s) breite) (setq s (strcat "0" s))) + (strcat "TRO" s) +) + + +;; ------------------------------------------------------------ +;; Naechste freie TRO-Kennung vorschlagen. +;; Sucht ueber alle TRO_*-Blockinstanzen die hoechste Zahl hinter "TRO" +;; (Format wie in sps_skel, lib/tro_flow.py: "TRO" + Zahl) und schlaegt die +;; naechste vor, in derselben Stellenbreite wie der bisherige Bestand +;; (Default 2-stellig, wenn noch keine TROs in der Zeichnung sind). +;; ------------------------------------------------------------ +(defun tro-naechste-id ( / ss i ent attribs id-val rest num maxnum breite) + (setq maxnum 0 breite 2) + (if (setq ss (ssget "_X" (list '(0 . "INSERT") '(2 . "TRO_*")))) + (progn + (setq i 0) + (while (setq ent (ssname ss i)) + (setq attribs (ssg-attrib-read ent)) + (setq id-val (cdr (assoc "ID" attribs))) + (if (and id-val (>= (strlen id-val) 4) + (= (strcase (substr id-val 1 3)) "TRO")) + (progn + (setq rest (substr id-val 4)) + (setq num (atoi rest)) + (if (> num maxnum) (setq maxnum num)) + (if (> (strlen rest) breite) (setq breite (strlen rest))) + ) + ) + (setq i (1+ i)) + ) + ) + ) + (tro-id-format (1+ maxnum) breite) +) + + +;; ------------------------------------------------------------ +;; Layer fuer einen neuen Marker ermitteln. +;; Uebernimmt den Layer einer bereits vorhandenen Instanz desselben Blocks +;; (Farbgruppen-Layer stammen aus tro_annotate.py/build_layers), sonst der +;; aktuell aktive Layer. +;; ------------------------------------------------------------ +(defun tro-marker-layer (bname / ss) + (if (setq ss (ssget "_X" (list '(0 . "INSERT") (cons 2 bname)))) + (cdr (assoc 8 (entget (ssname ss 0)))) + (getvar "CLAYER") + ) +) + + +;; ------------------------------------------------------------ +;; C:TRO_INSERT - neuen TRO-Marker einfuegen +;; +;; Fuegt eine bestehende TRO_SYM_-Blockdefinition an einem gewaehlten +;; Punkt ein und setzt ID und TYPE. Die Blockdefinition (Form, Farbe) +;; entsteht nur ueber sps_skel (lib/tro_annotate.py) - ohne einen frueheren +;; Lauf mit dem gewuenschten Typ bricht der Befehl mit einem Hinweis ab. +;; ------------------------------------------------------------ +(defun c:TRO_INSERT ( / liste dcl-pfad dat ergebnis typ id pt bname lay + oldAttreq oldAttdia) + + (ssg-start "TRO_INSERT" nil) + + (setq liste (tro-typliste nil)) + (if (or (null liste) (equal liste (list ""))) + (progn + (alert (ssg-text "tro-insert-kein-typ")) + (ssg-end) + (exit) + ) + ) + + ;; --- Dialog: Typ + Kennung --------------------------------------------- + (setq dcl-pfad (strcat (getenv "DXFM_DCL") "/tro_insert.dcl")) + (setq dat (load_dialog dcl-pfad)) + (if (not (new_dialog "tro_insert" dat)) + (progn + (alert (ssg-textf "tro-edit-dialog-fehlt" (list dcl-pfad))) + (ssg-end) + (exit) + ) + ) + + (start_list "type") + (foreach typname liste (add_list typname)) + (end_list) + (set_tile "type" "0") + (set_tile "id" (tro-naechste-id)) + (set_tile "hinweis" (ssg-text "tro-insert-hinweis")) + + (setq typ (car liste)) + (action_tile "type" "(setq typ (nth (atoi (get_tile \"type\")) liste))") + (action_tile "id" "(setq id (get_tile \"id\"))") + (action_tile "accept" + (strcat "(setq typ (nth (atoi (get_tile \"type\")) liste)" + " id (get_tile \"id\"))" + "(done_dialog 1)")) + (action_tile "cancel" "(done_dialog 0)") + + (setq ergebnis (start_dialog)) + (unload_dialog dat) + + (if (/= ergebnis 1) + (progn (ssg-end) (exit)) + ) + (if (= (vl-string-trim " " id) "") + (progn (alert (ssg-text "tro-edit-id-leer")) (ssg-end) (exit)) + ) + + ;; --- Blockdefinition pruefen -------------------------------------------- + (setq bname (strcat *tro-block-prefix* typ)) + (if (not (tblsearch "BLOCK" bname)) + (progn + (alert (ssg-textf "tro-insert-kein-block" (list bname))) + (ssg-end) + (exit) + ) + ) + + ;; --- Einfuegepunkt ------------------------------------------------------- + (setq pt (getpoint (ssg-text "tro-insert-prompt-punkt"))) + (if (null pt) + (progn (ssg-end) (exit)) + ) + + ;; --- Einfuegen ------------------------------------------------------------ + (setq lay (tro-marker-layer bname)) + (command "_LAYER" "_M" lay "") + (setq oldAttreq (getvar "ATTREQ") oldAttdia (getvar "ATTDIA")) + (setvar "ATTREQ" 0) + (setvar "ATTDIA" 0) + (command "_.INSERT" bname pt 1 1 0) + (setvar "ATTREQ" oldAttreq) + (setvar "ATTDIA" oldAttdia) + + (ssg-attrib-set-on (entlast) + (list (cons "ID" id) (cons "TYPE" typ) (cons "CONFIDENCE" "manuell"))) + (entupd (entlast)) + + (princ (ssg-textf "tro-insert-eingefuegt" (list id typ))) + (ssg-end) +) + + ;; ------------------------------------------------------------ ;; C:TRO_EDIT - Dialog fuer einen TRO-Marker ;; ------------------------------------------------------------ @@ -189,5 +350,5 @@ ) -(prompt "\nTro_Edit.lsp geladen - Befehl: TRO_EDIT") +(prompt "\nTro_Edit.lsp geladen - Befehle: TRO_INSERT, TRO_EDIT") (princ) diff --git a/dcl/tro_insert.dcl b/dcl/tro_insert.dcl new file mode 100644 index 0000000..6395c38 --- /dev/null +++ b/dcl/tro_insert.dcl @@ -0,0 +1,34 @@ +// ============================================================ +// tro_insert.dcl - Neuen TRO-Marker einfuegen +// Fragt Typ und Kennung fuer einen neuen TRO_SYM_-Marker ab. Die +// Blockdefinition (Form, Farbe) muss aus einem frueheren Lauf von +// sps_skel (lib/tro_annotate.py) bereits in der Zeichnung vorhanden sein. +// Aufruf ueber c:TRO_INSERT (Lisp/Tro_Edit.lsp). +// ============================================================ + +tro_insert : dialog { + label = "TRO einfuegen"; + + : column { + + : popup_list { + key = "type"; + label = "TRO-Typ:"; + width = 30; + } + + : edit_box { + key = "id"; + label = "TRO-Kennung:"; + edit_width = 30; + } + + : text { + key = "hinweis"; + label = ""; + } + + } + + ok_cancel; +} diff --git a/lang/de_DE.json b/lang/de_DE.json index b41044f..41c7dcc 100644 --- a/lang/de_DE.json +++ b/lang/de_DE.json @@ -659,6 +659,11 @@ "tro-edit-hinweis": "Symbol und FB folgen erst beim naechsten Lauf von tro_annotate.py.", "tro-edit-id-leer": "Die TRO-Kennung darf nicht leer sein - nichts geaendert.", "tro-edit-gespeichert": "\nTRO gespeichert: ID = %1, TYP = %2", - "tro-edit-typ-geaendert": "\nTyp geaendert - tro_annotate.py neu laufen lassen, damit Symbol und FB passen." + "tro-edit-typ-geaendert": "\nTyp geaendert - tro_annotate.py neu laufen lassen, damit Symbol und FB passen.", + "tro-insert-kein-typ": "Keine TRO-Typen verfuegbar (tro_types.lsp fehlt) - bitte lib/tro_annotate.py --emit-lisp ausfuehren.", + "tro-insert-hinweis": "Die Blockform muss bereits in der Zeichnung vorhanden sein (aus einem frueheren Lauf von tro_annotate.py).", + "tro-insert-kein-block": "Kein Symbol fuer diesen Typ in der Zeichnung (%1) - bitte tro_annotate.py mit diesem Typ laufen lassen.", + "tro-insert-prompt-punkt": "\nEinfuegepunkt: ", + "tro-insert-eingefuegt": "\nTRO eingefuegt: ID = %1, TYP = %2" } } diff --git a/lang/en_GB.json b/lang/en_GB.json index 32a7635..85e855b 100644 --- a/lang/en_GB.json +++ b/lang/en_GB.json @@ -659,6 +659,11 @@ "tro-edit-hinweis": "Symbol and FB follow on the next tro_annotate.py run.", "tro-edit-id-leer": "The TRO id must not be empty - nothing changed.", "tro-edit-gespeichert": "\nTRO saved: ID = %1, TYPE = %2", - "tro-edit-typ-geaendert": "\nType changed - re-run tro_annotate.py so symbol and FB match." + "tro-edit-typ-geaendert": "\nType changed - re-run tro_annotate.py so symbol and FB match.", + "tro-insert-kein-typ": "No TRO types available (tro_types.lsp missing) - run lib/tro_annotate.py --emit-lisp.", + "tro-insert-hinweis": "The block shape must already exist in the drawing (from an earlier tro_annotate.py run).", + "tro-insert-kein-block": "No symbol for this type in the drawing (%1) - run tro_annotate.py with this type first.", + "tro-insert-prompt-punkt": "\nInsertion point: ", + "tro-insert-eingefuegt": "\nTRO inserted: ID = %1, TYPE = %2" } } diff --git a/menu/SSG_LIB.mnu b/menu/SSG_LIB.mnu index 5393672..a8c03af 100644 --- a/menu/SSG_LIB.mnu +++ b/menu/SSG_LIB.mnu @@ -126,6 +126,7 @@ [<-~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 [->TRO] +[Marker einfuegen]^C^C(ssg-ensure "Tro_Edit") TRO_INSERT [Marker bearbeiten]^C^C(ssg-ensure "Tro_Edit") TRO_EDIT [<-Bearbeiten (Auto)]^C^C(ssg-ensure "SSG_LIB_Commands") SSG_BLOCKEDIT [->Export]