[FIX] Lagerbereiche für GOH werden nun korrekt gezählt und in die yaml geschrieben

This commit is contained in:
Simon Hensch committed 2026-11-02 09:56:03 +01:00
1 parent d9043ebca5
commit b324362351
14 files changed
+98 -615

No files matched your search

+12 -88
View File
@@ -5,10 +5,8 @@
;; - zwei Geschosse auf derselben 2D-Kontur (EG Hallenboden, OG 3100 mm)
;; - einen Lagerbereich 10000 x 6000 im OG mit Auto-Fuellung
;; und prueft Bloecke, Attribute, Layer, Neuberechnung (keine Verdopplung),
;; den Neuaufbau einer geaenderten Reihe und die Rohdaten von LAGER_EXPORT.
;; Zum Schluss Regression der goh_rack-Erkennung (lg-racks-sammeln) gegen
;; tests/testdata/goh_storage_test.dwg (Referenzwerte aus
;; goh_storage_test_regal_report.txt: 38946.39 mm / 77892.78 mm).
;; den Neuaufbau einer geaenderten Reihe, die Rohdaten von LAGER_EXPORT und
;; die Zaehlung von LG_REGALE.
;;
;; Aufruf in BricsCAD:
;; (load (strcat (getenv "DXFMAKRO") "/tests/test_lager.lsp"))
@@ -83,8 +81,8 @@
(vl-remove-if-not '(lambda (ed) (= (cdr (assoc 0 ed)) "ATTDEF")) (lg-blockdef-objekte bname))))
(defun lager:tests ( / k0 k1 g0 g1 kb bereich reihen gaenge r0 neu raw daten pfad f
racks laengen kap tr kb2 b2 kinder mg mg2 hg alt eb
r1 gg1 n-alt g2 r2 gg2 ids b2k n-kinder bb gr rg grp rk kand zl
kb2 b2 kinder mg mg2 hg alt eb
r1 gg1 n-alt g2 r2 gg2 ids b2k n-kinder bb rg rk zl
b3 rh3 mg3 ge3 ag3 n3 mr3 alt3)
(setvar "CMDECHO" 0)
(ssg-gui-aus)
@@ -366,88 +364,14 @@
(tlg-eq "rechteck-befehl: fase abgelehnt" 'kein-rechteck (lg-rechteck-ecken-aus-poly (entlast)))
(entdel (entlast))
;; --- Rack-Erkennung: direkt, verschachtelt + gedreht, MINSERT ---
;; eigener Testblock (Parameter als Attribut bzw. ATTDEF-Vorgabe), damit
;; die Suche nach goh_rack davon unberuehrt bleibt
(lg-blockdef "TLG_RACK" (list (lg-geom-linie '(0.0 0.0 0.0) '(1000.0 0.0 0.0))
(lg-geom-attdef "Laenge" "500" '(0.0 0.0 0.0) 50.0 nil)
(lg-geom-attdef "Ebenen" "3" '(0.0 0.0 0.0) 50.0 nil)))
(lg-blockdef "TLG_GRUPPE" (list '((0 . "INSERT") (8 . "0") (2 . "TLG_RACK") (10 0.0 0.0 0.0))
'((0 . "INSERT") (8 . "0") (2 . "TLG_RACK") (10 0.0 2000.0 0.0))))
(lg-block-einfuegen "TLG_RACK" '(-100000.0 0.0 0.0) 0.0 "0" '(("Laenge" . "100 cm") ("Ebenen" . "2")))
(setq grp (lg-block-einfuegen "TLG_GRUPPE" '(-200000.0 0.0 0.0) (/ pi 2.0) "0" nil))
(vla-AddMInsertBlock (lg-modelspace) (vlax-3d-point '(-300000.0 0.0 0.0)) "TLG_RACK"
1.0 1.0 1.0 0.0 1 3 1000.0 3000.0)
(setq rk (lg-racks-finden "TLG_RACK" "Laenge" "Ebenen"))
(tlg-eq "racks: anzahl" 6 (length rk))
(tlg-eq "racks: laenge (attribut mit einheit + vorgaben)" 3500.0
(apply '+ (mapcar '(lambda (r) (cond ((lg-rk-laenge r)) (0.0))) rk)))
(tlg-eq "racks: ebenen" 17.0 (apply '+ (mapcar '(lambda (r) (cond ((lg-rk-ebenen r)) (0.0))) rk)))
(tlg-eq "racks: verschachtelt top" 2
(length (vl-remove-if-not '(lambda (r) (equal (lg-rk-top r) grp)) rk)))
;; Gruppe um 90 Grad gedreht: zweites Rack (lokal y = 2000) liegt bei x = -202000
(tlg-eq "racks: verschachtelt gedreht" T
(equal (vl-sort (mapcar '(lambda (r) (car (lg-rk-mitte r)))
(vl-remove-if-not '(lambda (r) (equal (lg-rk-top r) grp)) rk))
'<)
'(-202000.0 -200000.0) 100.0))
;; MINSERT 1 Zeile x 3 Spalten, Abstand 3000: Mitten = Einfuegepunkte
(tlg-eq "racks: minsert" '(-300000.0 -297000.0 -294000.0)
(vl-sort (mapcar '(lambda (r) (car (lg-rk-mitte r)))
(vl-remove-if-not '(lambda (r) (< (car (lg-rk-mitte r)) -250000.0)) rk))
'<))
;; --- goh_rack-Regression (Referenzwerte goh_storage_test_regal_report.txt) ---
(setq pfad (strcat (getenv "DXFMAKRO") "/tests/testdata/goh_storage_test.dwg"))
(if (findfile pfad)
(progn
;; "*" = aufgeloest einfuegen: die goh_rack-Bloecke liegen danach
;; direkt im Modellbereich wie in der Originalzeichnung
(command "_.-INSERT" (strcat "*" pfad) '(50000.0 0.0 0.0) 1 0)
(setq racks (lg-export-goh-racks nil))
(tlg-eq "goh_rack anzahl" 4 (length (car racks)))
(setq laengen (tlg-summe (car racks) "laenge_mm"))
(setq kap 0.0)
(foreach t1 (car racks)
(setq tr (ssg-json-parse t1))
(setq kap (+ kap (* (ssg-json-get tr "laenge_mm") (ssg-json-get tr "ebenen")))))
(tlg-eq "goh_rack laenge gesamt" T (equal laengen 38946.39 0.1))
(tlg-eq "goh_rack laenge x ebenen" T (equal kap 77892.78 0.1))
(princ (strcat "\n goh_rack: " (rtos laengen 2 2) " mm / " (rtos kap 2 2) " mm"))
;; --- Geschoss mit goh_racks kopieren (deckungsgleich, 2D) ---
;; Geschosskontur um die Racks legen (Mitten aus lg-racks-sammeln + Rand)
(setq bb (ssg-poly-bbox (mapcar '(lambda (p) (list (car p) (cadr p)))
(mapcar 'lg-rk-mitte (lg-racks-sammeln)))))
(setq gr (lg-geschoss-naechste-nr))
(lg-geschoss-anlegen (tlg-rechteck (- (car (car bb)) 20000.0) (- (cadr (car bb)) 20000.0)
(+ (car (cadr bb)) 20000.0) (+ (cadr (cadr bb)) 20000.0))
(append (list (cons "HOEHE_BELAG_mm" "20000")) (lg-geschoss-vorgaben gr)))
(setq neu (lg-geschosse-kopieren (list (cons "QUELLE" (itoa gr)) (cons "ANZAHL" "1")
(cons "ABSTAND_mm" "3000") (cons "BELAG_ART" "spanplatte"))))
(setq racks (lg-export-goh-racks (lg-geschoss-kandidaten)))
(tlg-eq "rack-kopie: anzahl" 8 (length (car racks)))
(tlg-eq "rack-kopie: quelle" 4
(length (vl-remove-if-not '(lambda (t1) (equal (ssg-json-get (ssg-json-parse t1) "geschoss") gr))
(car racks))))
(tlg-eq "rack-kopie: kopie" 4
(length (vl-remove-if-not '(lambda (t1) (equal (ssg-json-get (ssg-json-parse t1) "geschoss") (car neu)))
(car racks))))
(tlg-eq "rack-kopie: keine warnung" nil (cadr racks))
(tlg-eq "rack-kopie: laenge kopie" T
(equal (tlg-summe (car racks) "laenge_mm") (* 2 38946.39) 0.2))
(tlg-eq "rack-kopie: layer" T (if (tblsearch "LAYER" (strcat "LG_Regal_G" (itoa (car neu)))) T nil))
;; Auswertung je Geschoss wie LG_REGALE: je 4 Racks in Quelle und Kopie
(setq kand (lg-geschoss-kandidaten))
(setq zl (lg-racks-auswerten
(mapcar '(lambda (r) (list (lg-rack-geschoss (lg-ent-layer (lg-rk-top r)) (lg-rk-mitte r) kand)
(lg-rk-laenge r) (lg-rk-ebenen r)))
(lg-racks-sammeln))))
(tlg-eq "lg_regale: geschosse" (list gr (car neu)) (mapcar 'car zl))
(tlg-eq "lg_regale: anzahl" '(4 4) (mapcar 'cadr zl))
(tlg-eq "lg_regale: laenge x ebenen" T (equal (cadddr (car zl)) 77892.78 0.2))
(tlg-eq "lg_regale: befehl laeuft" nil (vl-catch-all-error-p (vl-catch-all-apply 'c:LG_REGALE nil))))
(tlg-eq "goh_storage_test.dwg vorhanden" T nil))
;; --- LG_REGALE: zaehlt die Regalreihen aus den Makros (LG_REIHE_*) je Geschoss ---
(setq zl (lg-reihen-auswerten (mapcar '(lambda (e) (lg-reihe-eintrag (ssg-attrib-read e)))
(lg-alle-bloecke "LG_REIHE_*"))))
(tlg-eq "lg_regale: reihen gezaehlt" (length (lg-alle-bloecke "LG_REIHE_*"))
(apply '+ (mapcar 'cadr zl)))
(tlg-eq "lg_regale: reihen vorhanden" T (> (apply '+ (mapcar 'cadr zl)) 0))
(tlg-eq "lg_regale: reihen mit geschoss" nil (assoc nil zl))
(tlg-eq "lg_regale: befehl laeuft (reihen)" nil (vl-catch-all-error-p (vl-catch-all-apply 'c:LG_REGALE nil)))
;; --- Von Hand Gesetztes bleibt: Einfuegen loest keine Neuberechnung aus ---
(setq kb (tlg-rechteck 600000.0 0.0 610000.0 6000.0))
+9 -11
View File
@@ -7,8 +7,8 @@ Laeuft ohne BricsCAD: die Rohdaten sind von Hand nachgestellt, im Format von
LAGER_EXPORT (Lisp/LagerInsert.lsp, lg-export-json). Geprueft wird:
1. levels: Belagshoehen, lichte Hoehe aus dem Geschoss darueber,
Haengeebenen (Summe aller Reihen je Schienenhoehe/Warenlaenge, inkl.
goh_rack-Bloecke), Belag/Gitterrost nur auf Buehnen.
Haengeebenen (Summe aller Reihen je Schienenhoehe/Warenlaenge),
Belag/Gitterrost nur auf Buehnen.
2. layout: Bereichsparameter, Ganganzahl/-laenge, Huelle.
3. Provenienz: jeder Overlay-Wert hat einen Herkunfts-Eintrag.
4. Abgleich gegen cfg/example_goh_storage.yaml: Abweichungen -> Konflikte,
@@ -73,8 +73,6 @@ def raw():
"gaenge": [_gang(0, 10000), _gang(1, 10000),
_gang(1, 700, breite=1200, art="quergang"),
_gang(1, 500, breite=1200, art="quergang", belag="gitterrost")],
"goh_racks": [{"geschoss": 1, "name": "goh_rack", "laenge_mm": 5000, "ebenen": 2,
"tiefe_mm": 700, "haengeebenen": EBENEN_OG, "haengeebenen_quelle": "vorgabe"}],
"warnungen": ["Testwarnung"],
}
@@ -90,15 +88,15 @@ def test_levels_sortiert_und_hoehen(raw):
assert "clear_height_m" not in lv[1]
def test_haengeebenen_summe_inkl_goh_rack(raw):
def test_haengeebenen_summe(raw):
overlay, _ = lye.aggregiere(raw)
eg, og = overlay["levels"]
assert eg["hanging_levels"] == [
{"rail_height_m": 2.3, "rack_length_m": 20.0, "goods_length_m": 1.2},
{"rail_height_m": 1.1, "rack_length_m": 20.0, "goods_length_m": 1.1},
]
# 2 Reihen a 10 m + goh_rack 5 m, oberste Schiene zuerst
assert [h["rack_length_m"] for h in og["hanging_levels"]] == [25.0, 25.0]
# 2 Reihen a 10 m, oberste Schiene zuerst
assert [h["rack_length_m"] for h in og["hanging_levels"]] == [20.0, 20.0]
assert og["hanging_levels"][0]["rail_height_m"] == 2.8
@@ -109,16 +107,16 @@ def test_belag_nur_auf_buehne(raw):
# Belag: Hauptgang 10 m2 + Quergang Spanplatte 0,84 m2
assert og["walkway"]["area_m2"] == pytest.approx(10.8)
assert og["walkway"]["spec"] == "chipboard"
# Gitterrost: Quergang 0,6 m2 + Reihen 2 x 7 m2 + goh_rack 3,5 m2
assert og["grating"] == pytest.approx(18.1)
# Gitterrost: Quergang 0,6 m2 + Reihen 2 x 7 m2
assert og["grating"] == pytest.approx(14.6)
def test_belag_ohne_gaenge_aus_kontur(raw):
raw["gaenge"] = []
overlay, s = lye.aggregiere(raw)
og = overlay["levels"][1]
# 60 m2 Kontur - (2 x 7 + 3,5) m2 Reihen
assert og["walkway"]["area_m2"] == pytest.approx(42.5)
# 60 m2 Kontur - 2 x 7 m2 Reihen
assert og["walkway"]["area_m2"] == pytest.approx(46.0)
assert "Konturflaeche" in s.provenance["levels[1].walkway.area_m2"]["formel"]
+10 -47
View File
@@ -3145,8 +3145,6 @@
(tu-nil "lg-haengeebenen-parse/ungueltig" (lg-haengeebenen-parse "x"))
(tu-eq "lg-haengeebenen-string" "2300/1200;1100/1100"
(lg-haengeebenen-string '((2300.0 1200.0) (1100.0 1100.0))))
(tu-eq "lg-haengeebenen-n/1" "2300/1200" (lg-haengeebenen-n "2300/1200;1100/1100" 1))
(tu-eq "lg-haengeebenen-n/zuviel" "2300/1200;1100/1100" (lg-haengeebenen-n "2300/1200;1100/1100" 5))
(tu-eq "lg-feld-pruefen/mm" "1000" (lg-feld-pruefen "mm" " 1000 "))
(tu-nil "lg-feld-pruefen/mm-neg" (lg-feld-pruefen "mm" "-5"))
(tu-nil "lg-feld-pruefen/mm-leer" (lg-feld-pruefen "mm" ""))
@@ -3300,19 +3298,7 @@
(tu-eq "lg-geschoss-punkt/3d-unten" 1 (lg-geschoss-fuer-punkt-kern '(50.0 50.0 100.0) _kand))
;; --- Geschoss kopieren ---
(tu-eq "lg-geschoss-aus-layer/regal" 2 (lg-geschoss-aus-layer "LG_Regal_G2"))
(tu-eq "lg-geschoss-aus-layer/12" 12 (lg-geschoss-aus-layer "LG_Reihe_G12"))
(tu-nil "lg-geschoss-aus-layer/ohne" (lg-geschoss-aus-layer "LG_Reihe"))
(tu-nil "lg-geschoss-aus-layer/0" (lg-geschoss-aus-layer "0"))
(tu-nil "lg-geschoss-aus-layer/suffix" (lg-geschoss-aus-layer "LG_X_G2a"))
(tu-nil "lg-geschoss-aus-layer/nil" (lg-geschoss-aus-layer nil))
;; 2D uebereinander: Kontur mehrdeutig, Layer entscheidet
(setq _kand2 (list (list 1 0.0 _sq0) (list 2 3100.0 _sq0)))
(tu-eq "lg-rack-geschoss/layer" 2 (lg-rack-geschoss "LG_Regal_G2" '(50.0 50.0 0.0) _kand2))
(tu-nil "lg-rack-geschoss/mehrdeutig" (lg-rack-geschoss "0" '(50.0 50.0 0.0) _kand2))
(tu-eq "lg-rack-geschoss/kontur" 1 (lg-rack-geschoss "0" '(50.0 50.0 0.0) (list (list 1 0.0 _sq0))))
;; Layer eines nicht vorhandenen Geschosses zaehlt nicht
(tu-eq "lg-rack-geschoss/layer-fremd" 1 (lg-rack-geschoss "LG_Regal_G7" '(50.0 50.0 0.0) (list (list 1 0.0 _sq0))))
(tu-eq "lg-kopie-belag/folgt" "spanplatte" (lg-kopie-belag "hallenboden" "hallenboden" "spanplatte"))
(tu-eq "lg-kopie-belag/eigen" "gitterrost" (lg-kopie-belag "gitterrost" "hallenboden" "spanplatte"))
(tu-nil "lg-kopie-belag/nil" (lg-kopie-belag nil "hallenboden" "spanplatte"))
@@ -3387,41 +3373,18 @@
'(((300.0 -500.0) (10000.0 -500.0) (10000.0 500.0) (300.0 500.0))) 500.0))
(tu-eq "lg-quelle-rang" '(2 1 0 0)
(mapcar 'lg-quelle-rang '("manuell" "auto_geaendert" "auto" nil)))
;; --- goh_rack-Erkennung: Parameterwerte, Namen, Transformationen ---
(tu-eqf "lg-zahl-einheit/mm" 700.0 (lg-zahl-einheit "700 mm"))
(tu-eqf "lg-zahl-einheit/cm" 718.752 (lg-zahl-einheit "71.8752 cm"))
(tu-eqf "lg-zahl-einheit/m" 12900.0 (lg-zahl-einheit "12,9 m"))
(tu-eqf "lg-zahl-einheit/ohne" 2.0 (lg-zahl-einheit "2"))
(tu-eqf "lg-zahl-einheit/zahl" 3.0 (lg-zahl-einheit 3))
(tu-nil "lg-zahl-einheit/km" (lg-zahl-einheit "5 km"))
(tu-nil "lg-zahl-einheit/text" (lg-zahl-einheit "abc"))
(tu-nil "lg-zahl-einheit/leer" (lg-zahl-einheit ""))
(tu-nil "lg-zahl-einheit/nil" (lg-zahl-einheit nil))
(tu-eqf "lg-racks-auswerten"
(tu-eqf "lg-reihen-auswerten"
'((1 2 3000.0 6000.0) (2 1 500.0 1500.0) (nil 2 700.0 1400.0))
(lg-racks-auswerten '((2 500.0 3.0) (nil 700.0 2.0) (1 1000.0 2.0)
(lg-reihen-auswerten '((2 500.0 3.0) (nil 700.0 2.0) (1 1000.0 2.0)
(1 2000.0 2.0) (nil nil 2.0))))
(tu-nil "lg-racks-auswerten/leer" (lg-racks-auswerten nil))
(tu-eq "lg-name-brauchbar-p/name" T (lg-name-brauchbar-p "goh_rack"))
(tu-nil "lg-name-brauchbar-p/anonym" (lg-name-brauchbar-p "*U29"))
(tu-nil "lg-name-brauchbar-p/leer" (lg-name-brauchbar-p ""))
;; Einfuegung bei (100,0), 90 Grad, x-Skalierung 2: lokales (1,0,0) -> (100,2,0)
(tu-eqf "lg-insert-tf/drehung-skalierung" '(100.0 2.0 0.0)
(lg-tf-pkt (lg-insert-tf (list '(2 . "TU_KEIN_BLOCK") '(10 100.0 0.0 0.0)
(cons 50 (/ pi 2.0)) '(41 . 2.0))
0 0)
'(1.0 0.0 0.0)))
;; MINSERT-Spalte 2 bei Spaltenabstand 3000, gedreht um 90 Grad -> entlang +Y
(tu-eqf "lg-insert-tf/minsert" '(0.0 6000.0 0.0)
(car (lg-insert-tf (list '(2 . "TU_KEIN_BLOCK") '(10 0.0 0.0 0.0) (cons 50 (/ pi 2.0))
'(70 . 3) '(44 . 3000.0))
2 0)))
;; verschachtelt: Container bei (1000,0) um 90 Grad, Kind bei lokal (0,2000)
(tu-eqf "lg-tf-verketten" '(-1000.0 0.0 0.0)
(car (lg-tf-verketten
(lg-insert-tf (list '(2 . "TU_KEIN_BLOCK") '(10 1000.0 0.0 0.0) (cons 50 (/ pi 2.0))) 0 0)
(lg-insert-tf (list '(2 . "TU_KEIN_BLOCK") '(10 0.0 2000.0 0.0)) 0 0))))
(tu-nil "lg-reihen-auswerten/leer" (lg-reihen-auswerten nil))
(tu-eqf "lg-reihe-eintrag"
'(2 4500.0 2.0)
(lg-reihe-eintrag '(("GESCHOSS" . "2") ("LAENGE" . "4500")
("HAENGEEBENEN" . "2300/1200;1100/1100"))))
(tu-eqf "lg-reihe-eintrag/leer"
'(nil nil 0.0)
(lg-reihe-eintrag '(("GESCHOSS" . "") ("HAENGEEBENEN" . ""))))
(tu-nil "lg-gang-aus-ecken/entartet"
(lg-gang-aus-ecken '((0.0 0.0) (4000.0 0.0) (4000.0 0.0) (0.0 0.0))))