Merge remote-tracking branch 'origin/master'

This commit is contained in:
2026-10-09 16:18:04 +02:00
9 changed files with 125 additions and 79 deletions
+1 -1
View File
File diff suppressed because one or more lines are too long
+72 -31
View File
@@ -1553,43 +1553,81 @@
(list (car p) (cadr p) (if (caddr p1) (caddr p1) 0.0))
)
;; Positionen der Querstreben entlang der Traegerlinie (Abstand ab Linienanfang).
;; Regeln: Abstand zwischen zwei Streben hoechstens abstand-max, beide
;; Endabstaende gleich und in [rand-min, rand-max], so wenige Streben wie
;; moeglich.
;; netto <= 2*rand-max -> eine Strebe in der Mitte
;; sonst -> k = aufgerundet (netto - 2*rand-max) / abstand-max
;; Felder (= wenigste Streben). Rand
;; r = max(rand-min, (netto - k*abstand-max) / 2):
;; der Abstand ist damit GENAU abstand-max, solange der
;; Rand >= rand-min bleibt; nur sonst bleibt der Rand
;; bei rand-min und der Abstand wird etwas kleiner.
;; Mit genau abstand-max geht nicht jede Laenge auf (1100 mm: 2 Streben ->
;; Rand 300, 3 Streben -> Rand 50) - dort ergibt sich 100 | 450 | 450 | 100.
;; r <= rand-max ist durch die Wahl von k garantiert.
;; Kuerzer als 2*rand-min -> keine Strebe (der Mindestrand waere verletzt).
(defun geruest-traeger-streben (netto abstand-max rand-min rand-max / k r s i erg)
(cond
((or (null netto) (< netto (- (* 2.0 rand-min) 1e-6))) nil)
((<= netto (+ (* 2.0 rand-max) 1e-6)) (list (/ netto 2.0)))
(T
(setq k (/ (- netto (* 2.0 rand-max)) abstand-max))
;; aufrunden, Rundungsrauschen (z.B. 2.0000000001) nicht mitzaehlen
(setq k (if (equal k (fix k) 1e-6) (fix k) (1+ (fix k))))
(setq r (max rand-min (/ (- netto (* k abstand-max)) 2.0)))
(setq s (/ (- netto (* 2.0 r)) k))
(setq erg nil i k)
;; Abweichung eines Randes vom erlaubten Bereich [rand-min, rand-max]
;; (0 = innerhalb).
(defun geruest-rand-abweichung (r rand-min rand-max)
(cond ((< r rand-min) (- rand-min r))
((> r rand-max) (- r rand-max))
(T 0.0))
)
;; Querstreben-Plan: (rand positionen). Regel: der Abstand zwischen zwei
;; Streben ist IMMER genau abstand, beide Raender sind gleich:
;; netto = k * abstand + 2 * rand (k = Felder, k+1 Streben)
;; Gewaehlt wird das k, dessen Rand am naechsten am Bereich [rand-min,
;; rand-max] liegt (bei Gleichstand das mit weniger Streben). Weil der
;; Bereich schmaler ist als abstand, geht nicht jede Laenge auf: mit 500/
;; 100..250 liegt der Rand genau dann im Bereich, wenn netto mod 500 = 0 oder
;; in [200, 500) ist - bei 1001..1199 mm oder unter 200 mm z.B. nicht. Der Plan
;; wird dann trotzdem geliefert, die Pruefung (geruest-rand-abweichung) und
;; die Meldung uebernimmt der Aufrufer. netto <= 0 -> nil.
(defun geruest-traeger-streben-plan (netto abstand rand-min rand-max
/ k kmax r dev best-k best-r best-dev i erg)
(if (and netto (> netto 1e-6) abstand (> abstand 1e-6))
(progn
(setq kmax (fix (+ (/ netto abstand) 1e-9)) k 0 best-k nil)
(while (<= k kmax)
(setq r (/ (- netto (* k abstand)) 2.0))
(if (>= r -1e-9)
(progn
(setq dev (geruest-rand-abweichung r rand-min rand-max))
;; strikt kleiner: bei Gleichstand bleibt das kleinere k
(if (or (null best-k) (< dev (- best-dev 1e-6)))
(setq best-k k best-r (max r 0.0) best-dev dev))
)
)
(setq k (1+ k))
)
(setq erg nil i best-k)
(while (>= i 0)
(setq erg (cons (+ r (* i s)) erg))
(setq erg (cons (+ best-r (* i abstand)) erg))
(setq i (1- i))
)
erg
(list best-r erg)
)
)
)
;; Rand des Streben-Plans gegen [rand-min, rand-max] pruefen und bei
;; Abweichung den Benutzer informieren (Messagebox, ohne GUI auf die
;; Konsole). strebe = Ergebnis von geruest-traeger-strebe-cfg.
;; Rueckgabe: T = Rand im Bereich.
(defun geruest-traeger-rand-pruefen (netto strebe / plan txt)
(setq plan (geruest-traeger-streben-plan netto (nth 3 strebe) (nth 4 strebe) (nth 5 strebe)))
(if (and plan
(> (geruest-rand-abweichung (car plan) (nth 4 strebe) (nth 5 strebe)) 1e-6))
(progn
(setq txt (ssg-textf "gr-tr-strebe-rand"
(list (geruest-mm-string netto)
(geruest-mm-string (car plan))
(geruest-mm-string (nth 4 strebe))
(geruest-mm-string (nth 5 strebe))
(geruest-mm-string (nth 3 strebe))
(itoa (length (cadr plan))))))
(if (ssg-gui-p) (alert txt) (princ (strcat "\n" txt)))
nil
)
T
)
)
;; Nur die Positionen der Querstreben (Abstand ab Linienanfang).
(defun geruest-traeger-streben (netto abstand rand-min rand-max)
(cadr (geruest-traeger-streben-plan netto abstand rand-min rand-max))
)
;; Querstreben-Konfiguration (Variante vor Baugruppe) als
;; (dummy laenge querlinie abstand-max rand-min rand-max) oder nil, wenn keine
;; (dummy laenge querlinie abstand rand-min rand-max) oder nil, wenn keine
;; "querstrebe" definiert ist.
;; dummy = DWG unter data/geruest (Basispunkt Strebenmitte, 30 mm laengs
;; X) oder nil
@@ -1605,7 +1643,7 @@
(mapcar '(lambda (feld std)
(setq w (ssg-json-get q feld))
(if (numberp w) (float w) std))
'("laenge" "querlinie" "abstand_max" "rand_min" "rand_max")
'("laenge" "querlinie" "abstand" "rand_min" "rand_max")
'(30.0 25.0 500.0 100.0 250.0)))
)
)
@@ -1863,7 +1901,7 @@
(ssg-make-layer lay (ssg-layer-farbe-fuer-name lay) T)
(entmake (list '(0 . "LINE") (cons 8 lay)
'(10 0.0 0.0 0.0) (list 11 netto 0.0 0.0)))
;; strebe = (dummy laenge querlinie abstand-max rand-min rand-max)
;; strebe = (dummy laenge querlinie abstand rand-min rand-max)
(if strebe
(foreach x (geruest-traeger-streben netto (nth 3 strebe) (nth 4 strebe) (nth 5 strebe))
(if strebe-pfad
@@ -1969,6 +2007,9 @@
(if min-l (geruest-mm-string min-l) "0")
(if max-l (geruest-mm-string max-l) "-")))))
(T
;; Streben-Rand ausserhalb der Grenzen: informieren, aber trotzdem
;; einfuegen (der Abstand zwischen den Streben bleibt immer exakt)
(if strebe (geruest-traeger-rand-pruefen netto strebe))
(setq werte (cons (cons "LAENGE" (geruest-mm-string netto)) werte-basis))
(ssg-start nil '(("OSMODE") ("ATTREQ") ("ATTDIA")
("ANGBASE") ("ANGDIR") ("AUNITS")))
Binary file not shown.
Binary file not shown.
+2 -20
View File
@@ -6,13 +6,10 @@
"dummy": "Rohrabhaenger_dummy.dwg",
"attribute": {
"LAENGE": {
"typ": "number",
"min": 0,
"max": 6000,
"einheit": "mm"
"max": 6000
},
"TEILEFARBE": {
"typ": "auswahl",
"optionen": [
"RAL7035",
"RAL7030"
@@ -225,13 +222,10 @@
"dummy": "821006051.dwg",
"attribute": {
"LAENGE": {
"typ": "number",
"min": 0,
"max": 6000,
"einheit": "mm"
"max": 6000
},
"TEILEFARBE": {
"typ": "auswahl",
"optionen": [
"RAL7035",
"RAL7030"
@@ -240,18 +234,6 @@
"frei_option": "Individuell"
}
},
"einbauwinkel": {
"Platte": [
0,
90
],
"Arm": [
0,
90,
180,
270
]
},
"geometrie_varianten": [
{
"name": "R 2\"",
+1 -1
View File
@@ -5,7 +5,7 @@
"teileart": "Geruest Traeger",
"querstrebe": {
"dummy": "dummy_Strebe_30x4.dwg",
"abstand_max": 500,
"abstand": 500,
"rand_min": 100,
"rand_max": 250
},
+1
View File
@@ -1010,6 +1010,7 @@
"gr-tr-beschr-ausrichtung": "\nUnbekannte Ausrichtung %1 fuer die Traeger-Beschriftung - verwende BC.",
"gr-tr-beschr-ergebnis": "\n%1 Traeger beschriftet (davon %2 ohne bekannte Variante), %3 nicht beschriftbar, %4 verwaiste Beschriftungen entfernt.",
"gr-tr-beschr-keine": "\nKeine Rohr-Geruest-Traeger in der Zeichnung.",
"gr-tr-strebe-rand": "Traeger %1 mm: Der Randabstand der Querstreben betraegt %2 mm und liegt ausserhalb des erlaubten Bereichs %3 bis %4 mm (Strebenabstand %5 mm, %6 Streben). Der Traeger wird trotzdem eingefuegt.",
"in-yesno-keys": "Ja Nein",
"in-keys-bereich": "Alle Auswahl",
"in-keys-modus": "Teil Gesamt",
+1
View File
@@ -1010,6 +1010,7 @@
"gr-tr-beschr-ausrichtung": "\nUnknown justification %1 for beam label - using BC.",
"gr-tr-beschr-ergebnis": "\n%1 beam(s) labelled (%2 without known variant), %3 not labellable, %4 orphaned label(s) removed.",
"gr-tr-beschr-keine": "\nNo pipe scaffold beams in the drawing.",
"gr-tr-strebe-rand": "Beam %1 mm: the edge distance of the cross braces is %2 mm, outside the allowed range %3 to %4 mm (brace spacing %5 mm, %6 braces). The beam is inserted anyway.",
"in-yesno-keys": "Yes No",
"in-keys-bereich": "All Selection",
"in-keys-modus": "Part Whole",
+47 -26
View File
@@ -1048,36 +1048,57 @@
(geruest-traeger-start '(100.0 200.0 0.0) (/ pi 2.0) 20.0))
(tu-eqf "geruest-traeger-start/2d-punkt" '(5.0 0.0 0.0)
(geruest-traeger-start '(5.0 0.0) 0.0 0.0))
;; Querstreben: Abstand max. 500, Rand 100..250 beidseitig gleich,
;; so wenige wie moeglich
;; Abstand genau 500, solange der Rand in 100..250 bleibt
(tu-eqf "geruest-traeger-streben/1200" '(100.0 600.0 1100.0)
(geruest-traeger-streben 1200.0 500.0 100.0 250.0))
(tu-eqf "geruest-traeger-streben/1300" '(150.0 650.0 1150.0)
(geruest-traeger-streben 1300.0 500.0 100.0 250.0))
;; 1100 geht mit genau 500 nicht auf -> Rand 100, Abstand 450
(tu-eqf "geruest-traeger-streben/1100" '(100.0 550.0 1000.0)
(geruest-traeger-streben 1100.0 500.0 100.0 250.0))
(tu-eqf "geruest-traeger-streben/1500" '(250.0 750.0 1250.0)
(geruest-traeger-streben 1500.0 500.0 100.0 250.0))
(tu-eqf "geruest-traeger-streben/1000" '(250.0 750.0)
(geruest-traeger-streben 1000.0 500.0 100.0 250.0))
(tu-eqf "geruest-traeger-streben/eine" '(200.0)
(geruest-traeger-streben 400.0 500.0 100.0 250.0))
(tu-eqf "geruest-traeger-streben/grenze-500" '(250.0)
(geruest-traeger-streben 500.0 500.0 100.0 250.0))
(tu-eqf "geruest-traeger-streben/501" '(100.0 401.0)
(geruest-traeger-streben 501.0 500.0 100.0 250.0))
(tu-nil "geruest-traeger-streben/zu-kurz"
(geruest-traeger-streben 150.0 500.0 100.0 250.0))
(tu-eqf "geruest-traeger-streben/min-200" '(100.0)
(geruest-traeger-streben 200.0 500.0 100.0 250.0))
;; Querstreben: Abstand IMMER genau 500, beide Raender gleich; gewaehlt
;; wird die Strebenzahl mit dem Rand am naechsten an 100..250
;; (Gleichstand -> weniger Streben). Plan = (rand positionen).
;; Im Bereich:
(tu-eqf "geruest-traeger-plan/1000" '(250.0 (250.0 750.0))
(geruest-traeger-streben-plan 1000.0 500.0 100.0 250.0))
(tu-eqf "geruest-traeger-plan/1200" '(100.0 (100.0 600.0 1100.0))
(geruest-traeger-streben-plan 1200.0 500.0 100.0 250.0))
(tu-eqf "geruest-traeger-plan/1300" '(150.0 (150.0 650.0 1150.0))
(geruest-traeger-streben-plan 1300.0 500.0 100.0 250.0))
(tu-eqf "geruest-traeger-plan/1500" '(250.0 (250.0 750.0 1250.0))
(geruest-traeger-streben-plan 1500.0 500.0 100.0 250.0))
(tu-eqf "geruest-traeger-plan/400" '(200.0 (200.0))
(geruest-traeger-streben-plan 400.0 500.0 100.0 250.0))
(tu-eqf "geruest-traeger-plan/500" '(250.0 (250.0))
(geruest-traeger-streben-plan 500.0 500.0 100.0 250.0))
(tu-eqf "geruest-traeger-plan/200" '(100.0 (100.0))
(geruest-traeger-streben-plan 200.0 500.0 100.0 250.0))
;; Ausserhalb (netto mod 500 in (0, 200) oder netto < 200) - der Plan
;; kommt trotzdem, der Abstand bleibt 500:
;; 1100: Rand 300 (k=1) oder 50 (k=2), beide 50 daneben -> weniger Streben
(tu-eqf "geruest-traeger-plan/1100" '(300.0 (300.0 800.0))
(geruest-traeger-streben-plan 1100.0 500.0 100.0 250.0))
;; 1050: Rand 275 (25 daneben) schlaegt 25 (75 daneben)
(tu-eqf "geruest-traeger-plan/1050" '(275.0 (275.0 775.0))
(geruest-traeger-streben-plan 1050.0 500.0 100.0 250.0))
;; 1150: Rand 75 (25 daneben) schlaegt 325 (75 daneben)
(tu-eqf "geruest-traeger-plan/1150" '(75.0 (75.0 575.0 1075.0))
(geruest-traeger-streben-plan 1150.0 500.0 100.0 250.0))
(tu-eqf "geruest-traeger-plan/501" '(250.5 (250.5))
(geruest-traeger-streben-plan 501.0 500.0 100.0 250.0))
(tu-eqf "geruest-traeger-plan/kurz-150" '(75.0 (75.0))
(geruest-traeger-streben-plan 150.0 500.0 100.0 250.0))
(tu-nil "geruest-traeger-plan/null"
(geruest-traeger-streben-plan 0.0 500.0 100.0 250.0))
;; Abstand zwischen zwei Streben ist in jedem Fall exakt 500
(foreach _l '(700.0 1100.0 1150.0 2345.0 5999.0)
(setq _rec (geruest-traeger-streben _l 500.0 100.0 250.0))
(tu-true (strcat "geruest-traeger-streben/abstand-" (rtos _l 2 0))
(vl-every '(lambda (a b) (equal (- b a) 500.0 1e-6))
_rec (cdr _rec))))
;; Rand-Abweichung
(tu-eqf "geruest-rand-abweichung/innen" 0.0 (geruest-rand-abweichung 150.0 100.0 250.0))
(tu-eqf "geruest-rand-abweichung/unten" 25.0 (geruest-rand-abweichung 75.0 100.0 250.0))
(tu-eqf "geruest-rand-abweichung/oben" 50.0 (geruest-rand-abweichung 300.0 100.0 250.0))
;; 6000 mm: 11 Felder a 500 -> 12 Streben, letzte bei 5750
(setq _rec (geruest-traeger-streben 6000.0 500.0 100.0 250.0))
(tu-eq "geruest-traeger-streben/6000-anzahl" 12 (length _rec))
(tu-eqf "geruest-traeger-streben/6000-letzte" 5750.0 (last _rec))
;; Konfiguration: fehlende Felder -> Standard, ohne querstrebe -> nil
;; Ergebnis (dummy laenge querlinie abstand-max rand-min rand-max)
;; Ergebnis (dummy laenge querlinie abstand rand-min rand-max)
(tu-eqf "geruest-traeger-strebe-cfg/standard" '(nil 30.0 25.0 500.0 100.0 250.0)
(geruest-traeger-strebe-cfg nil
(ssg-json-parse "{\"querstrebe\": {\"rand_min\": 100}}")))
@@ -1086,7 +1107,7 @@
(ssg-json-parse "{\"querstrebe\": {\"dummy\": \"s.dwg\"}}")))
(tu-eqf "geruest-traeger-strebe-cfg/wert" '(nil 30.0 25.0 400.0 100.0 250.0)
(geruest-traeger-strebe-cfg nil
(ssg-json-parse "{\"querstrebe\": {\"abstand_max\": 400}}")))
(ssg-json-parse "{\"querstrebe\": {\"abstand\": 400}}")))
;; Querlinien an Anfang und Ende der 30 mm langen Strebe
(tu-eqf "geruest-traeger-strebe-enden" '(235.0 265.0)
(geruest-traeger-strebe-enden 250.0 30.0))