fix beim csv Export des Eckrades. Bild der gf für Doku war noch veraltet. Erste Fassung einer Lisp Funktion zur Erzeugung der Stückliste in der Szene

This commit is contained in:
2026-10-09 16:22:57 +02:00
parent 9b920b0825
commit bf2601a932
3 changed files with 286 additions and 2 deletions
+281
View File
@@ -0,0 +1,281 @@
;; ============================================================
;; SSG_STUECKLISTE.LSP - Positionsfaehnchen + Stuecklistentabelle
;;
;; Befehl:
;; SSG_FAEHNCHEN_STUECKLISTE Setzt an jedem gewaehlten ILS-/Omniflo-/
;; Geruest-Element ein Positions-Faehnchen und
;; zeichnet die zugehoerige Stuecklistentabelle
;; auf die Zeichnung.
;;
;; Alles entsteht AUS DER ZEICHNUNG - es wird keine Datei eingelesen.
;; Zum Vergleich der frueheren Walz-Loesung (MENU/POSITION.LSP): dort vergab
;; ein externes Clipper-Warenwirtschaftssystem die Positionsnummern und
;; lieferte spaltenfixe .pos-/.zei-Dateien zurueck, die AutoCAD nur noch
;; abgezeichnet hat. Dieser Umweg ist hier bewusst nicht nachgebaut: die
;; Positionsnummern und Mengen entstehen in dieser Funktion, die
;; Stuecklisten-AUSGABE fuer Sivas/CSV liefern EXPORTSIVAS/EXPORTCSV aus
;; denselben Block-Attributen.
;;
;; Setzt ssg_core.lsp, ssg_lang.lsp und ssg_input.lsp voraus, dazu
;; csv:get-bbox/csv:get-attrib aus export.lsp und ssg-bt-effname aus
;; ssg_blocktools.lsp - MUSS daher nach beiden geladen werden (siehe
;; ssg-ensure-Reihenfolge in SSG_LIB.mnl und ssg_load.lsp).
;; ============================================================
(vl-load-com)
;; ------------------------------------------------------------
;; POSITIONSFAEHNCHEN
;; ------------------------------------------------------------
;; Ein Faehnchen bei pt0 mit Positionsnummer posnr zeichnen (Layer muss
;; bereits aktiv sein). umrand = "1" rechteckig, "2" Kreis, "3" Automation.
;; Geometrie und Masse aus der Walz-Vorlage (posfahne) uebernommen.
(defun ssg-sl-faehnchen (pt0 posnr faktor umrand / pt1 pt2 pt3 pt4 pt5 pt6 x y z)
(setq x (car pt0) y (cadr pt0) z (caddr pt0))
(cond
((= umrand "2")
(setq pt1 (list (+ x (* faktor 100)) (+ y (* faktor 150)) z))
(setq pt5 (list (+ x (* faktor 125)) (+ y (* faktor 175)) z))
(setq pt6 (list (+ (car pt1) (* faktor 125)) (+ (cadr pt1) (* faktor 68)) z))
(command "_line" pt0 pt1 "")
(command "_circle" pt6 (* faktor 153))
(command "_text" pt5 (rtos (* faktor 75)) "0" (itoa posnr))
)
((= umrand "3")
(setq x (- x 15) y (- y 15))
(setq pt0 (list x y z))
(setq pt1 (list (- x (* faktor 250)) y z))
(setq pt2 (list (car pt1) (+ (cadr pt1) (* faktor 150)) z))
(setq pt3 (list x (+ y (* faktor 150)) z))
(setq pt5 (list (- x (* faktor 225)) (+ y (* faktor 25)) z))
(command "_pline" pt0 "_w" "0" "0" pt1 pt2 pt3 pt0 "")
(command "_text" pt5 (rtos (* faktor 75)) "0" (itoa posnr))
)
(t
(setq pt1 (list (+ x (* faktor 100)) (+ y (* faktor 150)) z))
(setq pt2 (list (+ (car pt1) (* faktor 250)) (cadr pt1) (caddr pt1)))
(setq pt3 (list (car pt2) (+ (cadr pt2) (* faktor 125)) (caddr pt1)))
(setq pt4 (list (car pt1) (cadr pt3) (caddr pt1)))
(setq pt5 (list (+ x (* faktor 125)) (+ y (* faktor 175)) z))
(command "_pline" pt0 "_w" "0" "0" pt1 "")
(command "_pline" pt1 pt2 pt3 pt4 pt1 "")
(command "_text" pt5 (rtos (* faktor 75)) "0" (itoa posnr))
)
)
)
;; ------------------------------------------------------------
;; STUECKLISTENTABELLE
;; ------------------------------------------------------------
;; Stuecklistentabelle (Kopf + Rahmen + Zeilen) ab p1 (obere linke Ecke der
;; ersten Zeile) zeichnen. zeilen = Liste von (POS MENGE LAENGE ARTNR BEZ),
;; alle Felder als String. Layer muss bereits aktiv sein. Rueckgabe: Anzahl
;; gezeichneter Zeilen. Spaltenraster aus der Walz-Vorlage (stcklimp).
(defun ssg-sl-tabelle-zeichnen (p1 zeilen / p11 p12 p91 p92 p93 p94 p95
tsize lspace daten n)
(setq tsize 100.0
lspace 200.0)
(setq p11 (list (- (car p1) 100.0) (+ (cadr p1) 250.0)))
(setq p12 (list (+ (car p1) 9000.0) (+ (cadr p1) 250.0)))
(command "_line" p11 p12
(list (car p12) (+ (cadr p12) 350.0))
(list (car p11) (+ (cadr p11) 350.0)) p11 "")
(setq p91 (list (+ (car p11) 400.0) (+ (cadr p11) 100.0)))
(setq p92 (list (+ (car p11) 800.0) (+ (cadr p11) 100.0)))
(setq p93 (list (+ (car p11) 1450.0) (+ (cadr p11) 100.0)))
(setq p94 (list (+ (car p11) 2050.0) (+ (cadr p11) 100.0)))
(setq p95 (list (+ (car p11) 3250.0) (+ (cadr p11) 100.0)))
(command "_text" p91 tsize "0" (ssg-text "sl-stkl-kopf-pos"))
(command "_text" p92 tsize "0" (ssg-text "sl-stkl-kopf-menge"))
(command "_text" p93 tsize "0" (ssg-text "sl-stkl-kopf-laenge"))
(command "_text" p94 tsize "0" (ssg-text "sl-stkl-kopf-artikel"))
(command "_text" p95 tsize "0" (ssg-text "sl-stkl-kopf-bezeichnung"))
(setq n 0)
(foreach daten zeilen
(command "_text" p1 tsize "0" (nth 0 daten))
(command "_text" (list (+ (car p1) 400.0) (cadr p1)) tsize "0" (nth 1 daten))
(command "_text" (list (+ (car p1) 1000.0) (cadr p1)) tsize "0" (nth 2 daten))
(command "_text" (list (+ (car p1) 1900.0) (cadr p1)) tsize "0" (nth 3 daten))
(command "_text" (list (+ (car p1) 3000.0) (cadr p1)) tsize "0" (nth 4 daten))
(command "_line" (list (- (car p1) 100.0) (- (cadr p1) 50.0))
(list (+ (car p1) 9000.0) (- (cadr p1) 50.0)) "")
(setq p1 (list (car p1) (- (cadr p1) lspace)))
(setq n (1+ n))
)
(command "_line" p11 p12
(list (+ (car p1) 9000.0) (- (cadr p1) 50.0))
(list (- (car p1) 100.0) (- (cadr p1) 50.0)) p11 "")
n
)
;; ------------------------------------------------------------
;; ELEMENTE AUS DER ZEICHNUNG ERKENNEN UND GRUPPIEREN
;; ------------------------------------------------------------
;;
;; Erfasst dieselben Elementarten wie der alte Walz-c:stueckl, aber aus der
;; Zeichnung statt aus Linienlaengen auf Spezial-Layern: ILS Kreisel/Eckrad
;; (KREISEL_*/ECKRAD_*), ILS Streckengruppen (VF_*/GF_*), Rohrgeruest (GR_*)
;; und Omniflo-Geraden (AP60*/AP110*/AP_110*/APG110*).
;;
;; Gruppierung bewusst GROB je Elementklasse (keine Sivas-Artikelaufloesung
;; wie export_sivas.py) - eine Tabellenzeile pro Klasse mit Anzahl und,
;; soweit vorhanden, Laengensumme aus dem LAENGE-Attribut. Jedes einzelne
;; erkannte Element bekommt ein Positions-Faehnchen an seiner Bounding-Box-
;; Ecke mit der Positionsnummer seiner Tabellenzeile; mehrere gleichartige
;; Elemente tragen daher dieselbe Nummer.
;; Elementklasse eines Blocknamens oder nil, wenn nicht erkannt.
;; Rueckgabe: (schluessel . bezeichnung) oder nil.
(defun ssg-sl-klasse (bname / b)
(setq b (strcase bname))
(cond
((or (wcmatch b "KREISEL_*") (wcmatch b "ECKRAD_*"))
(cons "ils_kreisel" (ssg-text "sl-erk-kreisel")))
((or (wcmatch b "VF_*") (wcmatch b "GF_*"))
(cons "ils_strecke" (ssg-text "sl-erk-strecke")))
((wcmatch b "GR_*")
(cons "geruest" (ssg-text "sl-erk-geruest")))
((wcmatch b "AP60*")
(cons "ap60" (ssg-text "sl-erk-ap60")))
((wcmatch b "APG110*")
(cons "apg110" (ssg-text "sl-erk-apg110")))
((or (wcmatch b "AP110*") (wcmatch b "AP_110*"))
(cons "ap110" (ssg-text "sl-erk-ap110")))
(t nil)
)
)
;; Aus einem Auswahlsatz die Elemente heraussuchen, die ssg-sl-klasse erkennt.
;; Nicht erkannte Objekte (fremde Bloecke, Linien, Texte) fallen still weg -
;; der Benutzer darf also grosszuegig ein Fenster aufziehen.
;; Rueckgabe: Liste von (ENAME . KLASSE), KLASSE = (schluessel . bez).
(defun ssg-sl-elemente-aus-ss (ss / i ename bname klasse res)
(if ss
(progn
(setq i 0)
(while (setq ename (ssname ss i))
(setq bname (ssg-bt-effname ename))
(if (setq klasse (ssg-sl-klasse bname))
(setq res (cons (cons ename klasse) res))
)
(setq i (1+ i))
)
)
)
(reverse res)
)
;; Elemente fuer Faehnchen/Stueckliste bestimmen: zuerst wird eine Auswahl
;; erfragt; Enter ohne Auswahl nimmt alle erkannten Elemente des aktuellen
;; Layouts. Rueckgabe wie ssg-sl-elemente-aus-ss.
(defun ssg-sl-erkannte-elemente ( / ss)
(prompt (ssg-text "sl-erk-auswahl"))
(setq ss (ssget '((0 . "INSERT"))))
(if (null ss)
(setq ss (ssget "_X" (list '(0 . "INSERT") (cons 410 (getvar "CTAB"))))))
(ssg-sl-elemente-aus-ss ss)
)
;; Laenge eines Elements aus dem LAENGE-Attribut (mm) oder 0.0, falls keines.
(defun ssg-sl-elem-laenge (ename / wert)
(setq wert (csv:get-attrib ename "LAENGE"))
(if wert (atof wert) 0.0)
)
;; Erkannte Elemente nach Klassenschluessel gruppieren. elemente = Liste von
;; (ENAME . (SCHLUESSEL . BEZ)), wie ssg-sl-erkannte-elemente liefert. Die
;; LAENGE je Element wird HIER per ssg-sl-elem-laenge aus der Zeichnung
;; gelesen - daher nicht ohne Zeichnung testbar; siehe
;; ssg-sl-gruppieren-werte fuer den file-freien Kern.
;; Rueckgabe: Liste von (schluessel bezeichnung anzahl laenge-mm) in der
;; Reihenfolge des ersten Auftretens.
(defun ssg-sl-gruppieren (elemente / werte)
(setq werte
(mapcar '(lambda (e) (list (car (cdr e)) (cdr (cdr e)) (ssg-sl-elem-laenge (car e))))
elemente))
(ssg-sl-gruppieren-werte werte)
)
;; Reiner Kern von ssg-sl-gruppieren, ohne Zeichnungszugriff: werte = Liste
;; von (schluessel bezeichnung laenge-mm) je Element. Rueckgabe wie dort.
(defun ssg-sl-gruppieren-werte (werte / gruppen eintrag schluessel bez laenge)
(foreach w werte
(setq schluessel (nth 0 w)
bez (nth 1 w)
laenge (nth 2 w))
(setq eintrag (assoc schluessel gruppen))
(if eintrag
(setq gruppen (subst
(list schluessel bez (1+ (nth 2 eintrag)) (+ (nth 3 eintrag) laenge))
eintrag gruppen))
(setq gruppen (append gruppen (list (list schluessel bez 1 laenge))))
)
)
gruppen
)
;; ------------------------------------------------------------
;; BEFEHL
;; ------------------------------------------------------------
(defun c:SSG_FAEHNCHEN_STUECKLISTE ( / layer faktor umrand elemente gruppen
posnr-map pos g bbox min-pt zeilen n p1)
(ssg-start (ssg-text "sl-erk-titel") nil)
(setq elemente (ssg-sl-erkannte-elemente))
(if (null elemente)
(prompt (ssg-text "sl-erk-keine"))
(progn
(setq gruppen (ssg-sl-gruppieren elemente))
(setq layer (ssg-in-string (ssg-text "sl-pos-layer") "ZZ_Position")
faktor (ssg-in-real (ssg-text "sl-pos-faktor") 1.0)
umrand (ssg-in-keyword (ssg-text "sl-pos-umrand") "Rechteck Kreis Automation" "Rechteck"))
(setq umrand (cond ((= umrand "Kreis") "2") ((= umrand "Automation") "3") (t "1")))
(ssg-make-layer layer "7" T)
;; Positionsnummer je Gruppenschluessel (1-basiert, Reihenfolge der
;; Gruppenliste).
(setq posnr-map nil pos 0)
(foreach g gruppen
(setq pos (1+ pos))
(setq posnr-map (cons (cons (car g) pos) posnr-map))
)
;; Faehnchen je einzelnem Element an der unteren linken Ecke seiner
;; Bounding-Box. csv:get-bbox liefert (cx cy cz dx dy dz) - Zentrum +
;; Abmessungen, keine Eckpunkte - die Ecke wird daraus berechnet.
(foreach e elemente
(setq bbox (csv:get-bbox (car e)))
(if bbox
(progn
(setq min-pt (list (- (nth 0 bbox) (/ (nth 3 bbox) 2.0))
(- (nth 1 bbox) (/ (nth 4 bbox) 2.0))
(- (nth 2 bbox) (/ (nth 5 bbox) 2.0))))
(setq pos (cdr (assoc (car (cdr e)) posnr-map)))
(ssg-sl-faehnchen min-pt pos faktor umrand)
)
)
)
;; Stuecklistentabelle: eine Zeile je Gruppe.
(setq zeilen nil)
(foreach g gruppen
(setq pos (cdr (assoc (car g) posnr-map)))
(setq zeilen (cons
(list (itoa pos) (itoa (nth 2 g))
(if (> (nth 3 g) 0.0) (rtos (nth 3 g) 2 0) "")
"" (nth 1 g))
zeilen))
)
(setq zeilen (reverse zeilen))
(setq p1 (getpoint (ssg-text "sl-stkl-einfuegepunkt")))
(setq n (ssg-sl-tabelle-zeichnen p1 zeilen))
(prompt (ssg-textf "sl-erk-ergebnis" (list (length elemente) n)))
)
)
(ssg-end)
(princ)
)
(princ)