fix: KF_EDIT baute gedrehte Foerderer ungedreht neu

Der Drehwinkel wird beim Bau in die Geometrie eingerechnet, die Blockreferenz
selbst hat immer Drehung 0 (ssg-block-wrap-welt). KF_EDIT las die Drehung nur
aus Gruppencode 50 und baute einen mit z.B. 90 Grad gebauten Foerderer beim
Bearbeiten daher ungedreht neu.

Der gebaute Winkel steht jetzt als XDATA (SSG_KF_EDIT) am Block. KF_EDIT
addiert eine spaeter von Hand vorgenommene Drehung der Referenz
(Gruppencode 50); Altbestand ohne XDATA verhaelt sich wie bisher.

- kf-block-erstellen: neuer Parameter drehung, beide Aufrufer angepasst
- reiner Kern kf-drehung-gesamt (auf -180..180 normalisiert) mit Unit-Tests

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-23 15:43:36 +02:00
parent 833a4b60a6
commit f8b8a4175b
2 changed files with 69 additions and 4 deletions
+48 -4
View File
@@ -526,6 +526,45 @@
(list bname (rtos laenge 2 0) (rtos winkel 2 1)))) (list bname (rtos laenge 2 0) (rtos winkel 2 1))))
laenge))))))))) laenge)))))))))
;; ============================================================
;; DREHWINKEL DES BLOCKS (XDATA)
;; ============================================================
;; Der Drehwinkel der Baugruppe wird beim Bau in die GEOMETRIE eingerechnet
;; (kf-matrix-aufrecht), nicht ueber die Drehung der Blockreferenz:
;; ssg-block-wrap-welt fuegt den fertigen Block immer mit Drehung 0 ein. Die
;; Referenz traegt damit nirgends mehr, wie die Kette gedreht wurde - KF_EDIT
;; wuerde sie beim Neuaufbau ungedreht neu bauen. Darum steht der Winkel als
;; XDATA am Block (Projektregel: Editierdaten gehoeren in XDATA, nicht in
;; .dbg). Eine spaetere Drehung der Referenz von Hand kommt ueber
;; Gruppencode 50 hinzu und wird addiert.
(setq *kf-xdata-app* "SSG_KF_EDIT")
;; Gesamtdrehung = gebauter Winkel (XDATA, Grad) + Drehung der Referenz
;; (Gruppencode 50, Bogenmass), auf -180..180 Grad normalisiert. Reiner
;; Rechenkern; fehlende Werte zaehlen als 0 (Altbestand ohne XDATA).
(defun kf-drehung-gesamt (xdata-grad dxf50-rad / g r)
(setq g (cond (xdata-grad (float xdata-grad)) (0.0)))
(setq r (cond (dxf50-rad (float dxf50-rad)) (0.0)))
(ks-winkel-normalisieren (+ g (/ (* 180.0 r) pi))))
(defun kf-xdata-schreiben (ent drehung-grad / eintrag)
(regapp *kf-xdata-app*)
(setq eintrag (list *kf-xdata-app*
(cons 1000 "kf-edit")
(cons 1040 (float drehung-grad))))
(entmod (append (entget ent) (list (list -3 eintrag))))
ent)
;; Gebauter Drehwinkel (Grad) aus der XDATA, nil wenn keine vorhanden ist.
(defun kf-xdata-lesen (ent / xd daten paar)
(setq xd (entget ent (list *kf-xdata-app*)))
(setq daten (cdr (assoc -3 xd)))
(if daten
(progn
(setq paar (assoc 1040 (cdr (car daten))))
(if paar (cdr paar) nil))
nil))
;; ============================================================ ;; ============================================================
;; BLOCK ABSCHLIESSEN ;; BLOCK ABSCHLIESSEN
;; ============================================================ ;; ============================================================
@@ -534,7 +573,7 @@
;; Vorbild: gf-block-erstellen (Gefaellestrecke.lsp). ;; Vorbild: gf-block-erstellen (Gefaellestrecke.lsp).
(defun kf-block-erstellen (variante geo hoehe laenge verbindung (defun kf-block-erstellen (variante geo hoehe laenge verbindung
startpunkt last-ent kf-nummer startpunkt last-ent kf-nummer
farbe antriebsmotor movimot steuerung / farbe antriebsmotor movimot steuerung drehung /
kf-bname kf-ss ent kf-insert winkel-str) kf-bname kf-ss ent kf-insert winkel-str)
(setq kf-bname (strcat "KF_" (itoa kf-nummer))) (setq kf-bname (strcat "KF_" (itoa kf-nummer)))
;; Winkel als nackte Ganzzahl ("26"/"30") - bewusst ueber itoa/fix statt ;; Winkel als nackte Ganzzahl ("26"/"30") - bewusst ueber itoa/fix statt
@@ -567,6 +606,8 @@
;; abgeschaltet, siehe ssg-block-wrap-welt) ;; abgeschaltet, siehe ssg-block-wrap-welt)
(ssg-block-wrap-welt kf-bname startpunkt kf-ss) (ssg-block-wrap-welt kf-bname startpunkt kf-ss)
(setq kf-insert (entlast)) (setq kf-insert (entlast))
;; Gebauten Drehwinkel festhalten, damit KF_EDIT ihn wiederfindet
(kf-xdata-schreiben kf-insert drehung)
(ssg-layer-setzen kf-insert (cond ((ssg-json-get variante "layer")) (ssg-layer-setzen kf-insert (cond ((ssg-json-get variante "layer"))
((ssg-json-get (kf-daten) "layer")) ((ssg-json-get (kf-daten) "layer"))
("kettenfoerderer"))) ("kettenfoerderer")))
@@ -965,7 +1006,7 @@
(kf-ansicht-2d-bauen daten startpunkt endpunkt drehung) (kf-ansicht-2d-bauen daten startpunkt endpunkt drehung)
(setq ent (kf-block-erstellen variante geo hoehe laenge verbindung (setq ent (kf-block-erstellen variante geo hoehe laenge verbindung
startpunkt last-ent kf-nummer farbe antriebsmotor movimot startpunkt last-ent kf-nummer farbe antriebsmotor movimot
steuerung)) steuerung drehung))
(ssg-end) (ssg-end)
(princ (ssg-textf "kf-fertig" (princ (ssg-textf "kf-fertig"
(list (strcat "KF_" (itoa kf-nummer)) (list (strcat "KF_" (itoa kf-nummer))
@@ -1058,7 +1099,10 @@
(progn (progn
(setq attribs (ssg-attrib-read ent)) (setq attribs (ssg-attrib-read ent))
(setq startpunkt (cdr (assoc 10 ed))) (setq startpunkt (cdr (assoc 10 ed)))
(setq drehung (/ (* 180.0 (cond ((cdr (assoc 50 ed))) (0.0))) pi)) ;; Der gebaute Winkel steckt in der XDATA, eine nachtraegliche
;; Drehung der Referenz in Gruppencode 50 - beides zaehlt.
(setq drehung (kf-drehung-gesamt (kf-xdata-lesen ent)
(cdr (assoc 50 ed))))
(kf-dlg-aus-attributen daten attribs) (kf-dlg-aus-attributen daten attribs)
(setq lmin (kf-zahl (ssg-json-get (ssg-json-get daten "laenge") "min")) (setq lmin (kf-zahl (ssg-json-get (ssg-json-get daten "laenge") "min"))
lmax (kf-zahl (ssg-json-get (ssg-json-get daten "laenge") "max"))) lmax (kf-zahl (ssg-json-get (ssg-json-get daten "laenge") "max")))
@@ -1096,7 +1140,7 @@
(kf-ansicht-2d-bauen daten startpunkt endpunkt drehung) (kf-ansicht-2d-bauen daten startpunkt endpunkt drehung)
(kf-block-erstellen variante geo hoehe laenge verbindung (kf-block-erstellen variante geo hoehe laenge verbindung
startpunkt last-ent kf-nummer farbe antriebsmotor startpunkt last-ent kf-nummer farbe antriebsmotor
movimot steuerung) movimot steuerung drehung)
(ssg-end) (ssg-end)
(princ (ssg-textf "kf-edit-fertig" (princ (ssg-textf "kf-edit-fertig"
(list bname (strcat "KF_" (itoa kf-nummer))))))))))))))) (list bname (strcat "KF_" (itoa kf-nummer)))))))))))))))
+21
View File
@@ -2667,6 +2667,27 @@
(tu-nil "kf-antriebsart/kein-komma" (tu-nil "kf-antriebsart/kein-komma"
(vl-string-search "," (kf-antriebsart '(("titel" . "x"))))) (vl-string-search "," (kf-antriebsart '(("titel" . "x")))))
;; --- kf-drehung-gesamt: Drehwinkel fuer KF_EDIT ---
;; Regression: der Drehwinkel wird beim Bau in die Geometrie eingerechnet,
;; die Blockreferenz selbst hat IMMER Drehung 0 (ssg-block-wrap-welt).
;; KF_EDIT las nur Gruppencode 50 und baute eine mit 90 Grad gebaute
;; Kette ungedreht neu. Der gebaute Winkel steht jetzt als XDATA.
(tu-eqf "kf-drehung/nur-xdata" 90.0 (kf-drehung-gesamt 90.0 0.0))
;; Referenz nachtraeglich von Hand um 90 Grad gedreht (Gruppencode 50 in
;; Bogenmass) -> beides addiert sich
(tu-eqf "kf-drehung/xdata-plus-referenz" 180.0
(kf-drehung-gesamt 90.0 (/ pi 2.0)))
;; Altbestand ohne XDATA: nur die Referenzdrehung (bisheriges Verhalten)
(tu-eqf "kf-drehung/ohne-xdata" 45.0 (kf-drehung-gesamt nil (/ pi 4.0)))
;; nichts bekannt -> 0, kein Absturz und kein nil
(tu-eqf "kf-drehung/nichts" 0.0 (kf-drehung-gesamt nil nil))
(tu-true "kf-drehung/ist-zahl" (numberp (kf-drehung-gesamt nil nil)))
;; Summe ueber 180 Grad wird auf -180..180 gefaltet (270 = -90)
(tu-eqf "kf-drehung/normalisiert" -90.0
(kf-drehung-gesamt 180.0 (/ pi 2.0)))
;; ganze Zahl aus der XDATA (nicht real) darf nicht abstuerzen
(tu-eqf "kf-drehung/ganzzahl" 30.0 (kf-drehung-gesamt 30 0.0))
;; --- kf-neigung-aus-punkten: Kern der 3D-Aufrichtung --- ;; --- kf-neigung-aus-punkten: Kern der 3D-Aufrichtung ---
;; Liefert (Schraeglaenge Neigungswinkel) aus Ketten-Start und -Ende. ;; Liefert (Schraeglaenge Neigungswinkel) aus Ketten-Start und -Ende.
;; Die Kette wird AUFGERICHTET eingebaut, die Hoehe laeuft also in Z. ;; Die Kette wird AUFGERICHTET eingebaut, die Hoehe laeuft also in Z.