Add TRO_INSERT command to hand-place new TRO markers

Lets the TRO menu insert a fresh TRO_SYM_<Typ> marker (point + type +
auto-suggested TROnn id) by reusing a block definition tro_annotate.py
already created, instead of only editing markers it placed.
This commit is contained in:
2026-08-03 15:56:13 +02:00
parent 47d1e8d395
commit 9c7dda8a37
6 changed files with 223 additions and 13 deletions
+172 -11
View File
@@ -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_<Typ> 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_<Typ> 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_<Typ>-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_<Typ>-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)