fix(kreisel): Mindestabstand 800mm gegen beruehrende Endkreise

Unterhalb des Kreisel-Durchmessers (*kreisel-durchmesser*, Default 800mm)
wuerden sich AN8/SP8 beruehren bzw. ueberschneiden. draw-module prueft das
als harte Sperre fuer alle Aufrufer; KreiselInsert/-Connect/-Redraw fragen
bei Unterschreitung erneut ab statt abzubrechen, KreiselEdit zeigt den
Dialog erneut (Projektmuster wie GERUEST).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-10-28 11:02:44 +01:00
parent 9e3e8e16ae
commit c3b4bf9db3
3 changed files with 145 additions and 91 deletions
+143 -91
View File
@@ -420,6 +420,18 @@
att-entity att-data att-tag new-value
beforeAtt)
;; Mindestabstand: unterhalb des Durchmessers wuerden sich die Endkreise
;; (AN8/SP8) beruehren bzw. ueberschneiden - harte Sperre fuer alle Aufrufer
;; (Insert/Connect/Redraw/Edit/Script), da draw-module der einzige
;; gemeinsame Zeichenpfad ist.
(if (< abstand *kreisel-durchmesser*)
(progn
(ssg-emsg (ssg-textf "kreisel-emsg-abstand-zu-klein"
(list (rtos abstand 2 0) (rtos *kreisel-durchmesser* 2 0))))
(exit)
)
)
;; Attribute vorbereiten
(setq attribs (ssg-attrib-merge attribs *kreisel-attrib-defs*))
(setq attribs (subst (cons "ABSTAND" (rtos abstand 2 0))
@@ -695,11 +707,23 @@
)
;; 2. Abstand (Tangentenlaenge) - Linie gibt auch den Winkel vor
(setq p2 (getpoint pt (ssg-textf "kreisel-prompt-abstand"
(list (rtos *kreisel-default-laenge* 2 0)))))
(setq erg (kreisel-insert-richtung pt p2 *kreisel-default-laenge*)
abstand (car erg)
rotation (cadr erg))
;; Mindestabstand = Kreisel-Durchmesser (sonst beruehren/ueberschneiden
;; sich die Endkreise) - bei Unterschreitung erneut abfragen.
(setq abstand nil)
(while (null abstand)
(setq p2 (getpoint pt (ssg-textf "kreisel-prompt-abstand"
(list (rtos *kreisel-default-laenge* 2 0)))))
(setq erg (kreisel-insert-richtung pt p2 *kreisel-default-laenge*)
abstand (car erg)
rotation (cadr erg))
(if (< abstand *kreisel-durchmesser*)
(progn
(ssg-emsg (ssg-textf "kreisel-emsg-abstand-zu-klein"
(list (rtos abstand 2 0) (rtos *kreisel-durchmesser* 2 0))))
(setq abstand nil)
)
)
)
(princ (ssg-textf "kreisel-abstand-ausgabe" (list (rtos abstand 2 0))))
;; 3. Hoehe (Z-Koordinate)
@@ -747,24 +771,29 @@
(progn (ssg-end) (princ (ssg-text "kreisel-abgebrochen")) (princ) (exit))
)
;; 2. Endpunkt (aeusserster Punkt SP-Seite) mit Gummiband
(setq ptEnd (getpoint ptStart (ssg-text "kreisel-prompt-endpunkt")))
(if (null ptEnd)
(progn (ssg-end) (princ (ssg-text "kreisel-abgebrochen")) (princ) (exit))
)
;; 2. Endpunkt (aeusserster Punkt SP-Seite) mit Gummiband - der Abstand
;; (Kreismitten-Tangentenlaenge = dist - Durchmesser) muss mindestens dem
;; Durchmesser entsprechen, sonst beruehren/ueberschneiden sich die
;; Endkreise; bei Unterschreitung erneut abfragen statt abzubrechen.
(setq abstand nil)
(while (null abstand)
(setq ptEnd (getpoint ptStart (ssg-text "kreisel-prompt-endpunkt")))
(if (null ptEnd)
(progn (ssg-end) (princ (ssg-text "kreisel-abgebrochen")) (princ) (exit))
)
;; 3. Geometrie berechnen
(setq dx (- (car ptEnd) (car ptStart))
dy (- (cadr ptEnd) (cadr ptStart)))
(setq dist (sqrt (+ (* dx dx) (* dy dy))))
(setq abstand (- dist *kreisel-durchmesser*))
;; 3. Geometrie berechnen
(setq dx (- (car ptEnd) (car ptStart))
dy (- (cadr ptEnd) (cadr ptStart)))
(setq dist (sqrt (+ (* dx dx) (* dy dy))))
(setq abstand (- dist *kreisel-durchmesser*))
(if (<= abstand 0.0)
(progn
(ssg-emsg (ssg-textf "kreisel-emsg-distanz-klein"
(list (rtos dist 2 0) (rtos *kreisel-durchmesser* 2 0))))
(ssg-end)
(exit)
(if (< abstand *kreisel-durchmesser*)
(progn
(ssg-emsg (ssg-textf "kreisel-emsg-distanz-klein"
(list (rtos dist 2 0) (rtos (* 2.0 *kreisel-durchmesser*) 2 0))))
(setq abstand nil)
)
)
)
@@ -883,7 +912,7 @@
;; geaendertem) Abstand neu. Alle Attribute bleiben
;; erhalten.
;; -----------------------------------------------
(defun c:KreiselRedraw ( / sel ent ed attribs basePoint rotation newAbstand)
(defun c:KreiselRedraw ( / sel ent ed attribs basePoint rotation newAbstand gueltig)
(ssg-start (ssg-text "kreisel-start-redraw") '(("CECOLOR")))
@@ -910,11 +939,20 @@
(cdr (assoc "HOEHE" attribs))
(cdr (assoc "KREISELART" attribs)))))
;; 3. Neuen Abstand abfragen (Enter = beibehalten)
(initget 6)
(setq newAbstand (getdist (ssg-textf "kreisel-prompt-neuer-abstand" (list (cdr (assoc "ABSTAND" attribs))))))
(if (null newAbstand)
(setq newAbstand (atof (cdr (assoc "ABSTAND" attribs))))
;; 3. Neuen Abstand abfragen (Enter = beibehalten); Mindestabstand =
;; Kreisel-Durchmesser, sonst beruehren/ueberschneiden sich die Endkreise.
(setq newAbstand nil gueltig nil)
(while (not gueltig)
(initget 6)
(setq newAbstand (getdist (ssg-textf "kreisel-prompt-neuer-abstand" (list (cdr (assoc "ABSTAND" attribs))))))
(if (null newAbstand)
(setq newAbstand (atof (cdr (assoc "ABSTAND" attribs))))
)
(if (< newAbstand *kreisel-durchmesser*)
(ssg-emsg (ssg-textf "kreisel-emsg-abstand-zu-klein"
(list (rtos newAbstand 2 0) (rtos *kreisel-durchmesser* 2 0))))
(setq gueltig T)
)
)
;; NEU - Neue Höhe abfragen:
(setq newHoehe (getreal (ssg-textf "kreisel-prompt-neue-hoehe" (list (cdr (assoc "HOEHE" attribs))))))
@@ -991,7 +1029,7 @@
;; 3. Bei OK: Block loeschen und mit neuen Werten neu zeichnen
;; -----------------------------------------------
(defun c:KreiselEdit ( / sel ss ent ed attribs basePoint rotation
dcl-pfad dat ergebnis
dcl-pfad dat ergebnis fertig
dlg-name dlg-abstand dlg-hoehe dlg-ausrichtung
dlg-drehrichtung dlg-kreiselart dlg-geruest-einzelmodul
dlg-geruest-typ
@@ -1049,73 +1087,87 @@
(princ (ssg-textf "kreisel-edit-bestehend"
(list (cdr (assoc "ABSTAND" attribs)) (rtos rotation 2 1) (cdr (assoc "KREISELART" attribs)))))
;; 3. DCL-Dialog laden
(setq dcl-pfad (strcat (getenv "DXFM_DCL") "/kreisel_edit.dcl"))
(setq dat (load_dialog dcl-pfad))
(if (not (new_dialog "kreisel_edit" dat))
(progn (alert (ssg-textf "kreisel-edit-dialog-fehlt" (list dcl-pfad))) (ssg-end) (exit))
)
;; 3. DCL-Dialog laden; bei zu kleinem Abstand (< Kreisel-Durchmesser,
;; sonst beruehren/ueberschneiden sich die Endkreise) erneut anzeigen,
;; statt den fehlerhaften Wert zu uebernehmen (Projektmuster wie GERUEST).
(setq dlg-abstand (cdr (assoc "ABSTAND" attribs)))
(setq fertig nil)
(while (not fertig)
(setq dcl-pfad (strcat (getenv "DXFM_DCL") "/kreisel_edit.dcl"))
(setq dat (load_dialog dcl-pfad))
(if (not (new_dialog "kreisel_edit" dat))
(progn (alert (ssg-textf "kreisel-edit-dialog-fehlt" (list dcl-pfad))) (ssg-end) (exit))
)
;; Ausrichtungs-Labels fuer popup_list aufbauen
(setq ausrichtLabels "")
(foreach entry *kreisel-ausrichtungen*
(if (= ausrichtLabels "")
(setq ausrichtLabels (car entry))
(setq ausrichtLabels (strcat ausrichtLabels "\n" (car entry)))
;; Ausrichtungs-Labels fuer popup_list aufbauen
(setq ausrichtLabels "")
(foreach entry *kreisel-ausrichtungen*
(if (= ausrichtLabels "")
(setq ausrichtLabels (car entry))
(setq ausrichtLabels (strcat ausrichtLabels "\n" (car entry)))
)
)
;; Tiles initialisieren (Abstand aus vorherigem Versuch uebernehmen)
(set_tile "name" (cdr (assoc "Bezeichnung" attribs)))
(set_tile "abstand" dlg-abstand)
(set_tile "hoehe" (cdr (assoc "HOEHE" attribs)))
(start_list "ausrichtung")
(foreach entry *kreisel-ausrichtungen*
(add_list (car entry))
)
(end_list)
(set_tile "ausrichtung" (itoa (kreisel-rotation-to-idx rotation)))
(start_list "drehrichtung")
(add_list "UZS")
(add_list "GUZ")
(end_list)
(set_tile "drehrichtung" (if (equal (cdr (assoc "DREHRICHTUNG" attribs)) "GUZ") "1" "0"))
(start_list "kreiselart")
(add_list "STANDARD")
(add_list "PIN")
(end_list)
(set_tile "kreiselart" (if (equal (cdr (assoc "KREISELART" attribs)) "PIN") "1" "0"))
(set_tile "geruest_einzelmodul"
(if (equal (cdr (assoc "GERUEST_EINZELMODUL" attribs)) "1") "1" "0"))
(start_list "geruest_typ")
(foreach opt *ssg-geruest-optionen* (add_list opt))
(end_list)
(set_tile "geruest_typ" (itoa (ssg-geruest-typ-to-idx (cdr (assoc "GERUEST_TYP" attribs)))))
;; Actions
(action_tile "accept"
(strcat
"(setq dlg-name (get_tile \"name\"))"
"(setq dlg-abstand (get_tile \"abstand\"))"
"(setq dlg-hoehe (get_tile \"hoehe\"))"
"(setq dlg-ausrichtung (get_tile \"ausrichtung\"))"
"(setq dlg-drehrichtung (get_tile \"drehrichtung\"))"
"(setq dlg-kreiselart (get_tile \"kreiselart\"))"
"(setq dlg-geruest-einzelmodul (get_tile \"geruest_einzelmodul\"))"
"(setq dlg-geruest-typ (get_tile \"geruest_typ\"))"
"(done_dialog 1)"
)
)
(action_tile "cancel" "(done_dialog 0)")
(setq ergebnis (start_dialog))
(unload_dialog dat)
(cond
((/= ergebnis 1) (setq fertig T))
((< (atof dlg-abstand) *kreisel-durchmesser*)
(ssg-emsg (ssg-textf "kreisel-emsg-abstand-zu-klein"
(list (rtos (atof dlg-abstand) 2 0) (rtos *kreisel-durchmesser* 2 0)))))
(t (setq fertig T))
)
)
;; Tiles initialisieren
(set_tile "name" (cdr (assoc "Bezeichnung" attribs)))
(set_tile "abstand" (cdr (assoc "ABSTAND" attribs)))
(set_tile "hoehe" (cdr (assoc "HOEHE" attribs)))
(start_list "ausrichtung")
(foreach entry *kreisel-ausrichtungen*
(add_list (car entry))
)
(end_list)
(set_tile "ausrichtung" (itoa (kreisel-rotation-to-idx rotation)))
(start_list "drehrichtung")
(add_list "UZS")
(add_list "GUZ")
(end_list)
(set_tile "drehrichtung" (if (equal (cdr (assoc "DREHRICHTUNG" attribs)) "GUZ") "1" "0"))
(start_list "kreiselart")
(add_list "STANDARD")
(add_list "PIN")
(end_list)
(set_tile "kreiselart" (if (equal (cdr (assoc "KREISELART" attribs)) "PIN") "1" "0"))
(set_tile "geruest_einzelmodul"
(if (equal (cdr (assoc "GERUEST_EINZELMODUL" attribs)) "1") "1" "0"))
(start_list "geruest_typ")
(foreach opt *ssg-geruest-optionen* (add_list opt))
(end_list)
(set_tile "geruest_typ" (itoa (ssg-geruest-typ-to-idx (cdr (assoc "GERUEST_TYP" attribs)))))
;; Actions
(action_tile "accept"
(strcat
"(setq dlg-name (get_tile \"name\"))"
"(setq dlg-abstand (get_tile \"abstand\"))"
"(setq dlg-hoehe (get_tile \"hoehe\"))"
"(setq dlg-ausrichtung (get_tile \"ausrichtung\"))"
"(setq dlg-drehrichtung (get_tile \"drehrichtung\"))"
"(setq dlg-kreiselart (get_tile \"kreiselart\"))"
"(setq dlg-geruest-einzelmodul (get_tile \"geruest_einzelmodul\"))"
"(setq dlg-geruest-typ (get_tile \"geruest_typ\"))"
"(done_dialog 1)"
)
)
(action_tile "cancel" "(done_dialog 0)")
(setq ergebnis (start_dialog))
(unload_dialog dat)
;; 4. Bei OK: Block loeschen und neu zeichnen
(if (= ergebnis 1)
(progn