From 1a34a12ab4087c75b03ec6b33b6539c3b26b267c Mon Sep 17 00:00:00 2001 From: Samer Ayadi Date: Wed, 14 Oct 2026 10:51:52 +0200 Subject: [PATCH] [ADD] Testanlage test_system als Nachbau-Vorlage fuer sps_skel tests/testdata/test_system.json aus sps_skel/data/test_system.dxf (dxf_anlage_export.py --projekt TestSystem): 9 Kreisel, 10 Separatoren, BTMT Beladung, SC Entladung. Treiber tests/test_test_system.lsp (TEST_TEST_SYSTEM, Menue Tests -> Testanlage test_system) nutzt dematic_arvato:bau-datei, in alltests.json aktiv (save dxf). [FIX] dxf_anlage_export.py: doppelte Kreisel-IDs (Kreisel einzeln gebaut, NUMMER beginnt mehrmals bei 1) bekommen die naechste freie Nummer, mit Hinweis + Test. Co-Authored-By: Claude Opus 5.5 --- doc/json-input-lisp.md | 1 + doc/kommandos.md | 1 + lib/dxf_anlage_export.py | 22 ++++ menu/SSG_LIB.cui | 44 ++++--- menu/SSG_LIB.mnu | 1 + tests/alltests.json | 3 +- tests/test_dxf_anlage_export.py | 15 +++ tests/test_test_system.lsp | 56 ++++++++ tests/testdata/test_system.json | 218 ++++++++++++++++++++++++++++++++ 9 files changed, 344 insertions(+), 17 deletions(-) create mode 100644 tests/test_test_system.lsp create mode 100644 tests/testdata/test_system.json diff --git a/doc/json-input-lisp.md b/doc/json-input-lisp.md index 910a632..beaf872 100644 --- a/doc/json-input-lisp.md +++ b/doc/json-input-lisp.md @@ -426,6 +426,7 @@ ueberspringt sie. Passende Primitive waere `insert-hz-scaled-block-by-ks` | `mubea.json` | Gesamtanlage: Kreisel, VF Standard/Etage, GF-Template (20 Stueck), Separatoren, Scanner, BTMT, Eingang/Ausgang | `TEST_MUBEA` | | `dematic_arvato.json` | Vorlage aus `dxf_scan_components.py`: Kreisel, Einzelbloecke, `gerade` (Hoehen fehlen) | `TEST_DEMATIC_ARVATO` (abgeschaltet) | | `showroom_ils.json` | ILS-3.0-Showroom-Vorlage aus `dxf_scan_components.py` (Kreisel, Gefaellestrecken; Hoehen teils Platzhalter), gleicher Treiber wie `dematic_arvato.json` | `TEST_SHOWROOM_ILS` | +| `test_system.json` | Testanlage aus `dxf_anlage_export.py` (`sps_skel/data/test_system.dxf`): 9 Kreisel, 10 Separatoren, BTMT Beladung, SC Entladung - Vorlage fuer die sps_skel-Pipeline (CSV -> TRO -> SCL), gleicher Treiber wie `dematic_arvato.json` | `TEST_TEST_SYSTEM` | | `hundm05_linienzug_polylines.json` | Polylinien aus `extract_polylines.py` | kein Treiber (Analyse-Daten) | | `vfl_journal_hm05_abbruch.json` | rohes Journal (`kind`/`value`) eines abgebrochenen Baus | kein Treiber | diff --git a/doc/kommandos.md b/doc/kommandos.md index b903441..f4e3513 100644 --- a/doc/kommandos.md +++ b/doc/kommandos.md @@ -202,6 +202,7 @@ Aus dem Menue "Tests" bzw. der Kommandozeile; Details in `doc/LispTests.md`. | `TEST_MUBEA` | Mubea-Nachbau aus `tests/testdata/mubea.json` | | `TEST_DEMATIC_ARVATO` | Dematic/Arvato-Nachbau (Flowpuffer/Kreisel) | | `TEST_SHOWROOM_ILS` | ILS-3.0-Showroom-Nachbau (Kreisel, Gefaellestrecken; Hoehen noch Platzhalter) | +| `TEST_TEST_SYSTEM` | Testanlage `test_system` nachbauen (9 Kreisel, Separatoren, BTMT) - Vorlage fuer sps_skel | --- diff --git a/lib/dxf_anlage_export.py b/lib/dxf_anlage_export.py index 62ad022..bada8ba 100644 --- a/lib/dxf_anlage_export.py +++ b/lib/dxf_anlage_export.py @@ -336,6 +336,27 @@ def einzel_eintrag(e): ]) +def kreisel_ids_eindeutig(kreisel, projekt, hinweise): + """Doppelte Kreisel-IDs aufloesen. Die Nummer kommt aus NUMMER bzw. dem + Blocknamen; in einer Zeichnung, in der Kreisel einzeln gebaut wurden, + beginnt sie jedes Mal neu bei 1 (test_system: vier KREISEL_1_*). Der + erste behaelt seine ID, jeder weitere bekommt die naechste freie Nummer + oberhalb der hoechsten vergebenen. Die Reihenfolge ist die der Eingabe + (Blockname, x, y) und damit stabil.""" + muster = re.compile(r"^Kreisel_%s_(\d+)$" % re.escape(projekt)) + nummern = [int(m.group(1)) for m in (muster.match(k[sch.F_ID]) for k in kreisel) if m] + naechste = max(nummern, default=0) + 1 + vergeben = set() + for k in kreisel: + if k[sch.F_ID] in vergeben: + alt = k[sch.F_ID] + k[sch.F_ID] = "Kreisel_%s_%02d" % (projekt, naechste) + naechste += 1 + hinweise.append("%s doppelt - Kreisel bei %.2f/%.2f umbenannt in %s" + % (alt, k[sch.F_X], k[sch.F_Y], k[sch.F_ID])) + vergeben.add(k[sch.F_ID]) + + def baue_eintraege(inserts, block_inhalt, projekt): """Reihenfolge wie mubea.json: Kreisel, VF, GF, Einzelbloecke - die VF vor den GF, weil gf-init-bibliothek globale Elementmasse umsetzt.""" @@ -344,6 +365,7 @@ def baue_eintraege(inserts, block_inhalt, projekt): name = e["name"] or "" if name.startswith("KREISEL_"): kreisel.append(kreisel_eintrag(e, block_inhalt, projekt)) + kreisel_ids_eindeutig(kreisel, projekt, hinweise) geo = [kreisel_geo(k) for k in kreisel] for e in inserts: name = e["name"] or "" diff --git a/menu/SSG_LIB.cui b/menu/SSG_LIB.cui index 745d3c3..f50a606 100644 --- a/menu/SSG_LIB.cui +++ b/menu/SSG_LIB.cui @@ -861,48 +861,54 @@ + + Testanlage test_system + ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_test_system.lsp")) (c:TEST_TEST_SYSTEM) + + + KS 2D/3D pruefen (CSV) ^C^C(load (strcat (getenv "DXFMAKRO") "/Lisp/ks_pruefung.lsp")) KS_PRUEFEN - + Kreisel bearbeiten (ssg-ensure "KreiselInsert") KreiselEdit - + Omniflo Element bearbeiten (ssg-ensure "OmniModulInsert") OMNI_EDIT - + Gefaellestrecke bearbeiten (ssg-ensure "Gefaellestrecke") GEFAELLESTRECKE_EDIT - + VarioFoerderer bearbeiten (ssg-ensure "VarioFoerderer") VARIOFOERDERER_EDIT - + TRO-Marker bearbeiten (ssg-ensure "Tro_Edit") TRO_EDIT - + Verbindung bearbeiten (ssg-ensure "Connection_Edit") CONNECTION_EDIT - + SSG Bearbeiten (Auto) (ssg-ensure "SSG_LIB_Commands") SSG_BLOCKEDIT @@ -1891,56 +1897,62 @@ - KS 2D/3D pruefen (CSV) + Testanlage test_system + + KS 2D/3D pruefen (CSV) + + + + - + POP501 SSG_LIB Edit Context Kreisel bearbeiten - + Omniflo Element bearbeiten - + Gefaellestrecke bearbeiten - + VarioFoerderer bearbeiten - + TRO-Marker bearbeiten - + Verbindung bearbeiten - + SSG Bearbeiten (Auto) - + diff --git a/menu/SSG_LIB.mnu b/menu/SSG_LIB.mnu index 023d66a..dd265b2 100644 --- a/menu/SSG_LIB.mnu +++ b/menu/SSG_LIB.mnu @@ -183,6 +183,7 @@ [HundM05 Kreisel-Abschnitt]^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_hundm05.lsp")) (c:TEST_HUNDM05) [Dematic/Arvato Flowpuffer (Vorlage)]^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_dematic_arvato.lsp")) (c:TEST_DEMATIC_ARVATO) [ILS 3.0 Showroom (Vorlage)]^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_showroom_ils.lsp")) (c:TEST_SHOWROOM_ILS) +[Testanlage test_system]^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_test_system.lsp")) (c:TEST_TEST_SYSTEM) [<-KS 2D/3D pruefen (CSV)]^C^C(load (strcat (getenv "DXFMAKRO") "/Lisp/ks_pruefung.lsp")) KS_PRUEFEN ***DOUBLECLICK diff --git a/tests/alltests.json b/tests/alltests.json index d0caa14..32d0ac3 100644 --- a/tests/alltests.json +++ b/tests/alltests.json @@ -12,5 +12,6 @@ { "name": "hundm05", "save": "dxf", "module": "VarioFoerderer" }, { "name": "dematic_arvato", "save": "dxf", "module": "VarioFoerderer", "disabled": true }, { "name": "hm_recformat", "save": "dxf", "module": "VarioFoerderer", "disabled": true }, - { "name": "showroom_ils", "save": "dxf", "module": "VarioFoerderer", "disabled": true } + { "name": "showroom_ils", "save": "dxf", "module": "VarioFoerderer", "disabled": true }, + { "name": "test_system", "save": "dxf", "module": "VarioFoerderer" } ] diff --git a/tests/test_dxf_anlage_export.py b/tests/test_dxf_anlage_export.py index 22fb36f..6c6b83c 100644 --- a/tests/test_dxf_anlage_export.py +++ b/tests/test_dxf_anlage_export.py @@ -145,3 +145,18 @@ def test_reihenfolge_vf_vor_gf(): art = ["K" if "abstand" in e else "GF" if "modus" in e else "VF" if "typ" in e else e["block"] for e in eintraege] assert art == ["K", "K", "VF", "GF", "Scanner"] + + +def test_doppelte_kreisel_nummern_werden_eindeutig(): + # test_system.dxf: Kreisel einzeln gebaut, NUMMER beginnt jedes Mal bei 1 + eins_a = _insert("KREISEL_1_STANDARD_2300", (-3561.74, 994.84, 2000.0), 0.0, + {"NUMMER": "1"}) + eins_b = _insert("KREISEL_1_STANDARD_2900", (4940.59, -2303.25, 0.0), 90.0, + {"NUMMER": "1"}) + zwei = _insert("KREISEL_2_STANDARD_4500", (4940.03, -7603.25, 0.0), 90.0, + {"NUMMER": "2"}) + eintraege, hinweise = dae.baue_eintraege([eins_a, eins_b, zwei], {}, "T") + ids = {k["id"]: k["x"] for k in eintraege} + assert sorted(ids) == ["Kreisel_T_01", "Kreisel_T_02", "Kreisel_T_03"] + assert ids["Kreisel_T_03"] == 4940.59 # der zweite KREISEL_1 weicht aus + assert any("Kreisel_T_03" in h for h in hinweise) diff --git a/tests/test_test_system.lsp b/tests/test_test_system.lsp new file mode 100644 index 0000000..3e8bc1c --- /dev/null +++ b/tests/test_test_system.lsp @@ -0,0 +1,56 @@ +;; ============================================================ +;; test_test_system.lsp - Nachbau der Testanlage "test_system". +;; +;; Datenquelle: tests/testdata/test_system.json. Die Zeichnung wurde mit +;; unseren Makros gebaut (KREISEL_n-Wrapper, Separatoren, BTMT), die Testdaten +;; kommen darum aus dem Rueckleser, nicht aus dem Scanner: +;; python lib/dxf_anlage_export.py \ +;; C:/develop/sps_skel/data/test_system.dxf \ +;; tests/testdata/test_system.json --projekt TestSystem +;; +;; Inhalt: 9 Kreisel (STANDARD, Ebenen 0 / 2000 / 3000), 10 Separatoren, +;; BTMT Beladung und SC Entladung - keine Gefaellestrecken, keine VF. +;; - Die Kreisel wurden in der Zeichnung einzeln gebaut, die Nummer begann +;; dabei mehrmals neu bei 1 (vier KREISEL_1_*). dxf_anlage_export.py +;; vergibt fuer die Doppelten Kreisel_TestSystem_07..09 - die Nummern der +;; gebauten Zeichnung weichen also von der Vorlage ab. +;; +;; Zweck: Vorlage fuer sps_skel. Nachbau -> EXPORTCSV -> CSV, auf die dort +;; material_flow.py / tro_flow.py / scl_skeleton.py angewendet werden. +;; +;; Keine eigene Bau-Logik: Eintragsschema und Lauf wie TEST_DEMATIC_ARVATO +;; (dematic_arvato:bau-datei aus tests/test_dematic_arvato.lsp). +;; +;; Aufruf in BricsCAD: +;; (load (strcat (getenv "DXFMAKRO") "/tests/test_test_system.lsp")) +;; TEST_TEST_SYSTEM +;; ============================================================ + +(if (not (boundp '*test-system-records*)) (setq *test-system-records* nil)) + +;; Beim LADEN holen (siehe test_dematic_arvato.lsp: per load definierte +;; Funktionen sind erst nach Rueckkehr zum Top-Level sichtbar). +(if (null (car (atoms-family 1 '("DEMATIC_ARVATO:BAU-DATEI")))) + (load (strcat (getenv "DXFMAKRO") "/tests/test_dematic_arvato.lsp"))) + +(defun test_system:datei () + (strcat (getenv "DXFMAKRO") "/tests/testdata/test_system.json")) + +(defun c:TEST_TEST_SYSTEM () + (setq *test-system-records* + (dematic_arvato:bau-datei "TEST_TEST_SYSTEM" "Testanlage test_system" + (test_system:datei))) + (princ)) + +;; Ergebnis-Export (Konvention :export-results fuer test_run_all.lsp) +(defun test_system:export-results (out-dir / pfad) + (if (null *test-system-records*) + (princ "\n Keine test_system-Ergebnisse vorhanden.") + (progn + (vl-mkdir out-dir) + (setq pfad (strcat out-dir "/test_system_results.json")) + (vsp-results-schreiben *test-system-records* pfad))) + (princ)) + +(princ "\nTEST_TEST_SYSTEM geladen. Aufruf: TEST_TEST_SYSTEM") +(princ) diff --git a/tests/testdata/test_system.json b/tests/testdata/test_system.json new file mode 100644 index 0000000..934681f --- /dev/null +++ b/tests/testdata/test_system.json @@ -0,0 +1,218 @@ +[ + { + "id": "Kreisel_TestSystem_01", + "function": "insert", + "x": -3561.74, + "y": 994.84, + "z": 2000.0, + "abstand": 2300.0, + "rotation": 0.0, + "typ": "STANDARD", + "drehrichtung": "UZS", + "comment": "aus Zeichnung: KREISEL_1_STANDARD_2300 (ID 0028), abstand aus Blockdefinition (AN8 -> SP8)" + }, + { + "id": "Kreisel_TestSystem_02", + "function": "insert", + "x": 4940.03, + "y": -7603.25, + "z": 0.0, + "abstand": 4500.0, + "rotation": 90.0, + "typ": "STANDARD", + "drehrichtung": "UZS", + "comment": "aus Zeichnung: KREISEL_2_STANDARD_4500 (ID 0033), abstand aus Blockdefinition (AN8 -> SP8)" + }, + { + "id": "Kreisel_TestSystem_03", + "function": "insert", + "x": 5739.13, + "y": -12898.65, + "z": 0.0, + "abstand": 5295.71, + "rotation": 90.0, + "typ": "STANDARD", + "drehrichtung": "GUZ", + "comment": "aus Zeichnung: KREISEL_3_STANDARD_5296 (ID 0034), abstand aus Blockdefinition (AN8 -> SP8)" + }, + { + "id": "Kreisel_TestSystem_04", + "function": "insert", + "x": 6533.6, + "y": -7603.44, + "z": 3000.0, + "abstand": 7889.42, + "rotation": 90.0, + "typ": "STANDARD", + "drehrichtung": "UZS", + "comment": "aus Zeichnung: KREISEL_4_STANDARD_7889 (ID 0035), abstand aus Blockdefinition (AN8 -> SP8)" + }, + { + "id": "Kreisel_TestSystem_05", + "function": "insert", + "x": 6133.6, + "y": 1485.99, + "z": 2000.0, + "abstand": 9783.58, + "rotation": 0.0, + "typ": "STANDARD", + "drehrichtung": "GUZ", + "comment": "aus Zeichnung: KREISEL_5_STANDARD_9784 (ID 0036), abstand aus Blockdefinition (AN8 -> SP8)" + }, + { + "id": "Kreisel_TestSystem_06", + "function": "insert", + "x": 6533.6, + "y": 1885.99, + "z": 2000.0, + "abstand": 3718.63, + "rotation": 90.0, + "typ": "STANDARD", + "drehrichtung": "UZS", + "comment": "aus Zeichnung: KREISEL_6_STANDARD_3719 (ID 0037), abstand aus Blockdefinition (AN8 -> SP8)" + }, + { + "id": "Kreisel_TestSystem_07", + "function": "insert", + "x": 4940.59, + "y": -2303.25, + "z": 0.0, + "abstand": 2900.0, + "rotation": 90.0, + "typ": "STANDARD", + "drehrichtung": "GUZ", + "comment": "aus Zeichnung: KREISEL_1_STANDARD_2900 (ID 0031), abstand aus Blockdefinition (AN8 -> SP8)" + }, + { + "id": "Kreisel_TestSystem_08", + "function": "insert", + "x": 340.85, + "y": 505.79, + "z": 0.0, + "abstand": 3400.0, + "rotation": 0.0, + "typ": "STANDARD", + "drehrichtung": "UZS", + "comment": "aus Zeichnung: KREISEL_1_STANDARD_3400 (ID 0030), abstand aus Blockdefinition (AN8 -> SP8)" + }, + { + "id": "Kreisel_TestSystem_09", + "function": "insert", + "x": -61.76, + "y": -974.08, + "z": 0.0, + "abstand": 4000.0, + "rotation": 90.0, + "typ": "STANDARD", + "drehrichtung": "GUZ", + "comment": "aus Zeichnung: KREISEL_1_STANDARD_4000 (ID 0032), abstand aus Blockdefinition (AN8 -> SP8)" + }, + { + "function": "insert", + "block": "Separator_SP", + "x": -461.76, + "y": 1466.18, + "z": 0.0, + "rotation": 90.0, + "comment": "aus Zeichnung: Separator_SP_3D (ID 0015, ZUORDNUNG 0032, ARTINR 200000077)" + }, + { + "function": "insert", + "block": "Separator_SP", + "x": 1184.44, + "y": 105.79, + "z": 0.0, + "rotation": 0.0, + "comment": "aus Zeichnung: Separator_SP_3D (ID 0017, ZUORDNUNG 0030, ARTINR 200000077)" + }, + { + "function": "insert", + "block": "Separator_SP", + "x": 3759.38, + "y": 905.79, + "z": 0.0, + "rotation": 180.0, + "comment": "aus Zeichnung: Separator_SP_3D (ID 0018, ZUORDNUNG 0030, ARTINR 200000077)" + }, + { + "function": "insert", + "block": "Separator_SP", + "x": 4540.59, + "y": -1553.42, + "z": 0.0, + "rotation": 90.0, + "comment": "aus Zeichnung: Separator_SP_3D (ID 0019, ZUORDNUNG 0031, ARTINR 200000077)" + }, + { + "function": "insert", + "block": "Separator_SP", + "x": 4540.03, + "y": -3109.7, + "z": 0.0, + "rotation": 270.0, + "comment": "aus Zeichnung: Separator_SP_3D (ID 0020, ZUORDNUNG 0033, ARTINR 200000077)" + }, + { + "function": "insert", + "block": "Separator_SP", + "x": 5340.03, + "y": -6594.16, + "z": 0.0, + "rotation": 90.0, + "comment": "aus Zeichnung: Separator_SP_3D (ID 0021, ZUORDNUNG 0033, ARTINR 200000077)" + }, + { + "function": "insert", + "block": "Separator_SP", + "x": 6933.6, + "y": -6678.18, + "z": 3000.0, + "rotation": 90.0, + "comment": "aus Zeichnung: Separator_SP_3D (ID 0022, ZUORDNUNG 0035, ARTINR 200000077)" + }, + { + "function": "insert", + "block": "Separator_SP", + "x": 6133.6, + "y": 362.53, + "z": 3000.0, + "rotation": 270.0, + "comment": "aus Zeichnung: Separator_SP_3D (ID 0023, ZUORDNUNG 0035, ARTINR 200000077)" + }, + { + "function": "insert", + "block": "Separator_SP", + "x": 7089.23, + "y": 1885.99, + "z": 2000.0, + "rotation": 0.0, + "comment": "aus Zeichnung: Separator_SP_3D (ID 0024, ZUORDNUNG 0036, ARTINR 200000077)" + }, + { + "function": "insert", + "block": "Separator_SP", + "x": 6933.6, + "y": 2848.54, + "z": 2000.0, + "rotation": 90.0, + "comment": "aus Zeichnung: Separator_SP_3D (ID 0025, ZUORDNUNG 0037, ARTINR 200000077)" + }, + { + "function": "insert", + "block": "BTMT-Beladung", + "x": 14617.77, + "y": 1085.99, + "z": 2000.0, + "rotation": 0.0, + "comment": "aus Zeichnung: BTMT-Beladung_3D (ID 0026, ARTINR 829662012)" + }, + { + "function": "insert", + "block": "SC_Entladung", + "x": -2246.43, + "y": 581.63, + "z": 1958.39, + "rotation": 179.49, + "comment": "aus Zeichnung: SC_Entladung_3D (ID 0027, ARTINR 400100156)" + } +]