1a34a12ab4
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 <noreply@anthropic.com>
163 lines
7.1 KiB
Python
163 lines
7.1 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
test_dxf_anlage_export.py - Gebaute Anlage -> Nachbau-Testdaten
|
|
(lib/dxf_anlage_export.py). Laeuft ohne BricsCAD und ohne DXF: die
|
|
Wrapper-Daten sind die Werte aus Dematic_TST.dxf, von Hand nachgestellt
|
|
(Form wie lese_zeichnung sie liefert).
|
|
|
|
1. Kreisel: abstand exakt aus der Blockdefinition (AN8 -> SP8), nicht aus
|
|
dem ganzzahligen ABSTAND-Attribut.
|
|
2. GF auf zwei Kreiselketten: Endhoehe = Hoehe des Kreisels am Ende,
|
|
der (falsch) gebaute Winkel wird NICHT uebernommen.
|
|
3. GF ohne Kreisel am Ende: gebauter Winkel bleibt.
|
|
4. VF "standard": Parameter wie vfs-edit-basis-lesen, L_GF1 aus L_GF_m.
|
|
5. VF "linienzug": Journal unveraendert als Token-Liste.
|
|
6. Einzelblock: _2D/_3D-Suffix entfaellt.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
|
|
import pytest
|
|
|
|
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
|
"..", "lib"))
|
|
import dxf_anlage_export as dae # noqa: E402
|
|
|
|
|
|
def _insert(name, p, rot=0.0, attribs=None, xdata=None):
|
|
return {"name": name, "handle": "1", "p": list(p), "rot": rot,
|
|
"attribs": attribs or {}, "xdata": xdata or {}, "ps": 0}
|
|
|
|
|
|
KREISEL_OBEN = _insert("KREISEL_2_STANDARD_33044", (35860.37, 12519.72, 2437.0),
|
|
180.0, {"ID": "0002", "NUMMER": "2", "ABSTAND": "33044",
|
|
"KREISELART": "STANDARD"})
|
|
KREISEL_UNTEN = _insert("KREISEL_3_STANDARD_33470", (36661.24, 24878.8, 1826.0),
|
|
180.0, {"ID": "0003", "NUMMER": "3", "ABSTAND": "33470",
|
|
"KREISELART": "STANDARD"})
|
|
BLOCK_INHALT = {
|
|
"KREISEL_2_STANDARD_33044": [{"name": "AN8_3D", "p": [400.0, 0.0, 0.0]},
|
|
{"name": "SP8_3D", "p": [33444.28, 0.0, 0.0]}],
|
|
"KREISEL_3_STANDARD_33470": [{"name": "AN8_3D", "p": [400.0, 0.0, 0.0]},
|
|
{"name": "SP8_3D", "p": [33870.18, 0.0, 0.0]}],
|
|
}
|
|
|
|
|
|
def _geo():
|
|
return [dae.kreisel_geo(dae.kreisel_eintrag(k, BLOCK_INHALT, "T"))
|
|
for k in (KREISEL_OBEN, KREISEL_UNTEN)]
|
|
|
|
|
|
def test_kreisel_abstand_aus_blockdefinition():
|
|
k = dae.kreisel_eintrag(KREISEL_OBEN, BLOCK_INHALT, "T")
|
|
assert k["id"] == "Kreisel_T_02"
|
|
assert k["abstand"] == pytest.approx(33044.28, abs=0.01)
|
|
assert (k["x"], k["y"], k["z"], k["rotation"]) == (35860.37, 12519.72, 2437.0, 180.0)
|
|
ohne_block = dae.kreisel_eintrag(KREISEL_OBEN, {}, "T")
|
|
assert ohne_block["abstand"] == 33044.0
|
|
assert k["drehrichtung"] == "UZS" # Attribut fehlt -> Vorgabe
|
|
|
|
|
|
def test_kreisel_drehrichtung_aus_attribut():
|
|
guz = _insert("KREISEL_4_STANDARD_3619", (42563.78, 1703.66, 2177.0), 90.0,
|
|
{"NUMMER": "4", "DREHRICHTUNG": "GUZ"})
|
|
assert dae.kreisel_eintrag(guz, {}, "T")["drehrichtung"] == "GUZ"
|
|
|
|
|
|
def test_gf_zwischen_zwei_kreiseln_bekommt_endhoehe():
|
|
gf = _insert("GF_1", (5833.56, 12919.72, 2437.0), 0.0,
|
|
{"ID": "0005", "SEITE_AS": "links", "SEITE_ES": "links",
|
|
"HOEHE_BIS_mm": "1568"},
|
|
{"SSG_GF_EDIT": ["90", "3.7929", "90", "90", "2437", "11559.08"]})
|
|
hinweise = []
|
|
e = dae.gf_eintrag(gf, _geo(), "T", hinweise)
|
|
assert e["test_id"] == "GF_T_01"
|
|
assert e["start_mm"] == [5833.56, 12919.72, 2437.0]
|
|
assert e["deltaL_mm"] == 11559.08 and e["hz_grad"] == 90.0
|
|
assert (e["kreisel_start"], e["kreisel_ende"]) == ("Kreisel_T_02", "Kreisel_T_03")
|
|
assert e["hoehe_ende_mm"] == 1826.0
|
|
assert "winkel_grad" not in e
|
|
assert hinweise == []
|
|
|
|
|
|
def test_gf_ohne_kreisel_behaelt_gebauten_winkel():
|
|
gf = _insert("GF_7", (0.0, 0.0, 1000.0), 0.0, {},
|
|
{"SSG_GF_EDIT": ["0", "3", "90", "30", "1000", "5000"]})
|
|
e = dae.gf_eintrag(gf, _geo(), "T", [])
|
|
assert e["winkel_grad"] == 3.0
|
|
assert "hoehe_ende_mm" not in e and "kreisel_ende" not in e
|
|
assert e["es_winkel"] == "30"
|
|
|
|
|
|
def test_gf_ohne_xdata_wird_gemeldet():
|
|
hinweise = []
|
|
assert dae.gf_eintrag(_insert("GF_9", (0, 0, 0)), [], "T", hinweise) is None
|
|
assert "SSG_GF_EDIT" in hinweise[0]
|
|
|
|
|
|
def test_vf_standard():
|
|
vf = _insert("VF_2", (3314.07, 24478.8, 1826.0), 0.0,
|
|
{"ID": "0082", "DELTA_L_mm": "11559", "DELTA_H_mm": "611",
|
|
"ANTRIEBFAHRTRICHTUNG": "Auf", "SEITE_AS": "links",
|
|
"MOTORSEITE": "rechts", "VF_WINKEL": "15",
|
|
"L_GF_m": "1.907,1.907"},
|
|
{"SSG_VF_EDIT": ["standard", "270"]})
|
|
e = dae.vf_standard_eintrag(vf, "T", "standard")
|
|
assert e["test_id"] == "VF_T_02"
|
|
assert (e["richtung"], e["deltaL"], e["deltaH"], e["winkel"]) == ("Auf", 11559.0, 611.0, 15)
|
|
assert e["L_GF1"] == 1907.0 and e["hz"] == 270.0
|
|
assert (e["seite"], e["motorseite"]) == ("links", "rechts")
|
|
assert (e["x"], e["y"], e["z"]) == (3314.07, 24478.8, 1826.0)
|
|
|
|
|
|
def test_vf_linienzug_journal_unveraendert():
|
|
roh = ["linienzug", "PT:42161.679193,2448.319538,0^JREAL:2177^JSTR:1^JSTR:9",
|
|
"0^JSTEP:Linie-VF^JDL:9370.410886"]
|
|
vf = _insert("VF_26", (42161.68, 2448.32, 2177.0), 0.0, {"ID": "0184"},
|
|
{"SSG_VF_EDIT": roh})
|
|
e = dae.vf_journal_eintrag(vf, "T", 1)
|
|
assert e["typ"] == "linienzug_journal" and e["test_id"] == "VF_T_LZ_01"
|
|
# Chunk-Grenze mitten im Token ("STR:9" + "0") wird korrekt zusammengesetzt
|
|
assert e["journal"] == ["PT:42161.679193,2448.319538,0", "REAL:2177", "STR:1",
|
|
"STR:90", "STEP:Linie-VF", "DL:9370.410886"]
|
|
|
|
|
|
def test_einzelblock_ohne_dimensionssuffix():
|
|
e = dae.einzel_eintrag(_insert("Separator_SP_3D", (3038.72, 12119.73, 2473.0),
|
|
0.0, {"ID": "0043", "ZUORDNUNG": "0002"}))
|
|
assert e["block"] == "Separator_SP"
|
|
assert e["function"] == "insert" and e["z"] == 2473.0
|
|
assert "ID 0043" in e["comment"]
|
|
|
|
|
|
def test_reihenfolge_vf_vor_gf():
|
|
inserts = [
|
|
_insert("GF_1", (5833.56, 12919.72, 2437.0), 0.0, {},
|
|
{"SSG_GF_EDIT": ["90", "3", "90", "90", "2437", "11559.08"]}),
|
|
_insert("Scanner_3D", (1, 2, 3)),
|
|
_insert("VF_2", (0, 0, 0), 0.0, {}, {"SSG_VF_EDIT": ["standard", "0"]}),
|
|
KREISEL_OBEN, KREISEL_UNTEN,
|
|
_insert("*U12", (0, 0, 0)),
|
|
]
|
|
eintraege, _ = dae.baue_eintraege(inserts, BLOCK_INHALT, "T")
|
|
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)
|