This commit is contained in:
2026-10-15 10:35:16 +02:00
20 changed files with 1103 additions and 42 deletions
+2 -1
View File
@@ -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" }
]
+15
View File
@@ -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)
+48
View File
@@ -538,3 +538,51 @@ class TestAsEsUeberEinlaufpunkt:
umlauf = compute_kreisel_umlauf(
items, tolerance_mm=200.0, durchmesser_mm=DURCHMESSER_MM)
assert "0071" not in [p[0] for p in umlauf["0001"]]
class TestZuordnungAttributVorBBox:
"""Realer Fall test_system, Separator 0018: er sitzt an der Kreisel-
Kreisel-Weiche zweier Kreisel und ragt mit Toleranz in die Box BEIDER.
Die BBox-Suche nahm den ersten Kreisel in der Item-Liste (den falschen);
das ZUORDNUNG-Attribut aus der Zeichnung (cs-zuordnung-lauf) nennt den
richtigen und hat Vorrang."""
def _anlage(self, attr):
# Kreisel 0006 senkrecht (Achse +Y), AN8-Mitte bei (0, 400);
# Kreisel 0005 waagerecht (Achse +X), AN8-Mitte bei (0, -400):
# AN8/AN8 beruehren sich bei (0, 0). Separator auf der Oberkante von
# Kreisel 0005, 615 mm rechts der Weiche.
k6 = _kreisel("0006", 0.0, 0.0, 90.0, abstand=2000.0)
k5 = _kreisel("0005", -400.0, -400.0, 0.0, abstand=8000.0)
sep = _separator("0018", 615.0, 0.0)
sep["_zuordnung_attr"] = attr
sep["merkmale"] = {}
return [sep, k6, k5]
def test_umlauf_folgt_attribut(self):
items = self._anlage("0005")
umlauf = compute_kreisel_umlauf(items, tolerance_mm=200.0,
durchmesser_mm=DURCHMESSER_MM)
assert "0018" in [p[0] for p in umlauf["0005"]]
assert "0018" not in [p[0] for p in umlauf["0006"]]
def test_ohne_attribut_bbox_rueckfall(self):
items = self._anlage("")
umlauf = compute_kreisel_umlauf(items, tolerance_mm=200.0,
durchmesser_mm=DURCHMESSER_MM)
alle = [p[0] for pts in umlauf.values() for p in pts]
assert alle.count("0018") == 1
def test_sensor_zuordnung_folgt_attribut(self):
from export_neighbors import compute_sensor_zuordnung
items = self._anlage("0005")
zuo = compute_sensor_zuordnung(items, 200.0,
kreisel_durchmesser_mm=DURCHMESSER_MM)
assert zuo[0].startswith("0005")
def test_unbekanntes_attribut_bbox_rueckfall(self):
from export_neighbors import compute_sensor_zuordnung
items = self._anlage("9999")
zuo = compute_sensor_zuordnung(items, 200.0,
kreisel_durchmesser_mm=DURCHMESSER_MM)
assert zuo[0] != "9999" and zuo[0] != "nicht zugeordnet"
+61
View File
@@ -0,0 +1,61 @@
;; ============================================================
;; 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.
;; - Die x-Werte sind NACH dem Rueckleser von Hand korrigiert: in der
;; Zeichnung lagen die Kreisel bis zu 5.5 mm daneben, jetzt beruehren sich
;; alle 8 Weichenpaare exakt (1-9, 9-8, 8-7, 7-2, 2-3, 3-4, 4-5, 5-6;
;; Kreisel 1 fest, Separatoren/BTMT mit ihrem Kreisel verschoben). Ein
;; erneuter Lauf von dxf_anlage_export.py macht das rueckgaengig.
;;
;; 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 <name>: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)
+119 -1
View File
@@ -360,6 +360,95 @@
)
;; ------------------------------------------------------------
;; TESTS: vf_linienzug.lsp - ES-Fussabdruck entlang der Fahrtrichtung
;; ------------------------------------------------------------
;; vfl-es-laengs liefert die Laenge, die ein Segment fuer das ES-Element
;; reservieren muss. Getestet wird die Rueckfallkette: ohne sie wuerde ein
;; fehlender Messwert zu (- deltaL nil) und damit zum Absturz fuehren.
(defun tu-tests-vfl-es ( / _s-laengs _s-dx)
(princ "\n[vf_linienzug ES]")
;; globale Masse sichern - sie gehoeren dem laufenden Bau-Kontext
(setq _s-laengs ein-laengs _s-dx ein-dx)
;; Normalfall: ein-laengs ist gesetzt und wird genommen.
;; 576.2 = ES_Element_30_rechts entlang der Fahrtrichtung; (abs ein-dx)
;; waere 242.6 - genau die 333.65 mm, um die die Kette frueher zu weit ragte.
(setq ein-laengs 576.2 ein-dx -242.6)
(tu-eqf "vfl-es-laengs/nimmt-laengs-nicht-dx" 576.2 (vfl-es-laengs))
;; Vorzeichen: reserviert wird immer ein Betrag
(setq ein-laengs -576.2)
(tu-eqf "vfl-es-laengs/betrag" 576.2 (vfl-es-laengs))
;; Genulltes ein-dx gewinnt: die Null-Konvention der Bau-Pfade bedeutet
;; "ES anderswo schon beruecksichtigt - hier nichts reservieren". Ohne diese
;; Kopplung wuerde der Fix einen doppelten Abzug einbauen.
(setq ein-laengs 576.2 ein-dx 0.0)
(tu-eqf "vfl-es-laengs/genulltes-dx-gewinnt" 0.0 (vfl-es-laengs))
;; KS nicht lesbar -> Rueckfall auf das alte (zu kleine) Blockmass
(setq ein-laengs nil ein-dx -242.6)
(tu-eqf "vfl-es-laengs/fallback-auf-dx" 242.6 (vfl-es-laengs))
;; gar nichts gemessen -> 0.0, niemals nil (Absturzschutz)
(setq ein-dx nil)
(tu-eqf "vfl-es-laengs/fallback-null" 0.0 (vfl-es-laengs))
(setq ein-laengs _s-laengs ein-dx _s-dx)
)
;; ------------------------------------------------------------
;; TESTS: vf_linienzug.lsp - Laenge aus einer Ziellinie (X/Y)
;; ------------------------------------------------------------
;; Steht die Fahrtrichtung fest, ist die Laenge nicht mehr frei: die (ggf.
;; seitlich versetzte) Bahn trifft die Ziellinie in genau einem Punkt.
;; REIN PLANAR - die Hoehe kommt weiterhin aus dem Gefaellewinkel.
(defun tu-tests-vfl-ziellinie ( / _p0 _l _ks)
(princ "\n[vf_linienzug Ziellinie]")
(tu-eqf "vfl-kreuz2/einheitsachsen" 1.0 (vfl-kreuz2 1.0 0.0 0.0 1.0))
(tu-eqf "vfl-kreuz2/parallel" 0.0 (vfl-kreuz2 2.0 4.0 1.0 2.0))
(setq _p0 '(0.0 0.0 0.0))
;; Fahrtrichtung 0 Grad, senkrechte Ziellinie bei x=1000 -> L=1000
(tu-eqf "vfl-laenge-bis-ziellinie/senkrecht"
1000.0 (vfl-laenge-bis-ziellinie _p0 0.0 0.0 '(1000.0 -500.0 0.0) '(1000.0 500.0 0.0)))
;; Querversatz verschiebt die BAHN seitlich, nicht laengs: bei einer zur
;; Fahrtrichtung senkrechten Ziellinie bleibt L deshalb gleich.
(tu-eqf "vfl-laenge-bis-ziellinie/querversatz-ohne-wirkung"
1000.0 (vfl-laenge-bis-ziellinie _p0 0.0 52.5 '(1000.0 -500.0 0.0) '(1000.0 500.0 0.0)))
;; 45-Grad-Ziellinie durch (1000,0): die um +100 versetzte Bahn trifft sie
;; 100 frueher (y=100 wird bei x=1100 erreicht -> ohne Versatz 1000+100).
(tu-eqf "vfl-laenge-bis-ziellinie/schraege-linie"
1100.0 (vfl-laenge-bis-ziellinie _p0 0.0 100.0 '(1000.0 0.0 0.0) '(2000.0 1000.0 0.0)))
;; Ziellinie PARALLEL zur Fahrtrichtung -> kein eindeutiger Treffer -> nil
(tu-nil "vfl-laenge-bis-ziellinie/parallel"
(vfl-laenge-bis-ziellinie _p0 0.0 0.0 '(0.0 500.0 0.0) '(1000.0 500.0 0.0)))
;; Z der Ziellinie ist irrelevant (rein planare Rechnung, Nutzer-Vorgabe):
;; dieselbe Linie auf anderer Hoehe liefert dasselbe L.
(tu-eqf "vfl-laenge-bis-ziellinie/z-ignoriert"
1000.0 (vfl-laenge-bis-ziellinie _p0 0.0 0.0 '(1000.0 -500.0 7777.0) '(1000.0 500.0 -99.0)))
;; Realfall aus dem Nutzer-Log: nach dem 30-Grad-Bogen steht die Kette bei
;; (901.21,-2728.97) mit hz=-120; das ES-KS_AUS laeuft 52.51 mm versetzt und
;; landete bei (231.42,-3994.11). Eine Ziellinie durch diesen Punkt quer zur
;; Fahrtrichtung muss genau die damals gebaute Gesamtlaenge liefern.
(setq _ks '(231.42 -3994.11 0.0))
(setq _l (vfl-laenge-bis-ziellinie '(901.21 -2728.97 0.0) -120.0 52.51
_ks (list (+ (car _ks) (cos (/ pi 6.0))) ; 30 Grad = quer zu -120
(+ (cadr _ks) (sin (/ pi 6.0))) 0.0)))
(tu-true "vfl-laenge-bis-ziellinie/realfall-plausibel"
(and _l (> _l 1430.0) (< _l 1431.0)))
)
;; ------------------------------------------------------------
;; TESTS: export.lsp - CSV/KOS-Kodierung
;; ------------------------------------------------------------
@@ -846,6 +935,35 @@
(tu-bp-el "ECKRAD" 400.0 800.0 0.0 0.0 0.0 "B"))
1.0 1.0)))
(tu-eq "kreisel-bp/flanke-eckrad" 1 (length _ber))
;; Kreisel seitlich versetzt Ende an Ende (Raeder Flanke an Flanke, aber in
;; Gegenrichtung) -> Weiche, keine Seite-an-Seite-Kollision
(setq _erg (kreisel-bp-berechnen (list (tu-bp-el "KREISEL" 0.0 0.0 0.0 0.0 2000.0 "A")
(tu-bp-el "KREISEL" 2000.0 800.0 0.0 0.0 2000.0 "B"))
1.0 1.0))
(tu-eq "kreisel-bp/ende-an-ende-art" '("Kreis/Kreis") (tu-bp-arten (car _erg)))
(tu-eqf "kreisel-bp/ende-an-ende-punkt" '(2400.0 400.0) (cdr (assoc "p" (car (car _erg)))))
(tu-nil "kreisel-bp/ende-an-ende-keine-kollision" (cadr _erg))
;; Gleich ausgerichtete Raeder Flanke an Flanke (echtes Seite an Seite) -> keine Weiche
(setq _erg (kreisel-bp-berechnen (list (tu-bp-el "KREISEL" 0.0 0.0 0.0 0.0 2000.0 "A")
(tu-bp-el "KREISEL" 0.0 800.0 0.0 0.0 2000.0 "B"))
1.0 1.0))
(tu-nil "kreisel-bp/seite-an-seite-keine-weiche" (car _erg))
;; results/test.dxf (E3/C7): Kreisel 2/3/4 Ende an Ende (0.9 mm Ueberlappung bzw.
;; 5.5 mm), Kreisel 8 vor dem Profil von Kreisel 9 (2.6 mm Spalt) - mit 10 mm
;; Toleranz drei Weichen
(setq _erg (kreisel-bp-berechnen
(list (tu-bp-el "KREISEL" 4940.03 -7603.25 2000.0 90.0 4500.0 "2")
(tu-bp-el "KREISEL" 5739.13 -12898.65 2000.0 90.0 5296.0 "3")
(tu-bp-el "KREISEL" 6533.6 -7603.44 2000.0 90.0 7889.0 "4")
(tu-bp-el "KREISEL" -61.76 -974.08 2000.0 90.0 4000.0 "9")
(tu-bp-el "KREISEL" 340.85 505.79 2000.0 0.0 3400.0 "8"))
10.0 1.0))
(tu-eq "kreisel-bp/test-dxf-paare"
'(("2" "3") ("3" "4") ("9" "8"))
(mapcar '(lambda (tr) (list (cdr (assoc "id" (cdr (assoc "a" tr))))
(cdr (assoc "id" (cdr (assoc "b" tr))))))
(car _erg)))
(tu-nil "kreisel-bp/test-dxf-keine-kollision" (cadr _erg))
)
@@ -2138,7 +2256,7 @@
(princ "\n================================================================")
(foreach fn '("tu-tests-core" "tu-tests-lang" "tu-tests-id" "tu-tests-vfcore"
"tu-tests-etage"
"tu-tests-etage" "tu-tests-vfl-es" "tu-tests-vfl-ziellinie"
"tu-tests-export" "tu-tests-hoehen" "tu-tests-gf" "tu-tests-omni" "tu-tests-kreisel" "tu-tests-kreisel-bp"
"tu-tests-sepliste" "tu-tests-json" "tu-tests-geruest"
"tu-tests-sepscan" "tu-tests-vfl-segs" "tu-tests-vfl-abbruch"
+218
View File
@@ -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": 4938.26,
"y": -7603.25,
"z": 2000.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), x auf exakte Beruehrung korrigiert (-1.77)"
},
{
"id": "Kreisel_TestSystem_03",
"function": "insert",
"x": 5738.26,
"y": -12898.65,
"z": 2000.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), x auf exakte Beruehrung korrigiert (-0.87)"
},
{
"id": "Kreisel_TestSystem_04",
"function": "insert",
"x": 6538.26,
"y": -7603.44,
"z": 2000.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), x auf exakte Beruehrung korrigiert (+4.66)"
},
{
"id": "Kreisel_TestSystem_05",
"function": "insert",
"x": 6138.26,
"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), x auf exakte Beruehrung korrigiert (+4.66)"
},
{
"id": "Kreisel_TestSystem_06",
"function": "insert",
"x": 6538.26,
"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), x auf exakte Beruehrung korrigiert (+4.66)"
},
{
"id": "Kreisel_TestSystem_07",
"function": "insert",
"x": 4938.26,
"y": -2303.25,
"z": 2000.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), x auf exakte Beruehrung korrigiert (-2.33)"
},
{
"id": "Kreisel_TestSystem_08",
"function": "insert",
"x": 338.26,
"y": 505.79,
"z": 2000.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), x auf exakte Beruehrung korrigiert (-2.59)"
},
{
"id": "Kreisel_TestSystem_09",
"function": "insert",
"x": -61.74,
"y": -974.08,
"z": 2000.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), x auf exakte Beruehrung korrigiert (+0.02)"
},
{
"function": "insert",
"block": "Separator_SP",
"x": -461.74,
"y": 1466.18,
"z": 2000.0,
"rotation": 90.0,
"comment": "aus Zeichnung: Separator_SP_3D (ID 0015, ZUORDNUNG 0032, ARTINR 200000077), x mit Kreisel 09 verschoben (+0.02)"
},
{
"function": "insert",
"block": "Separator_SP",
"x": 1181.85,
"y": 105.79,
"z": 0.0,
"rotation": 0.0,
"comment": "aus Zeichnung: Separator_SP_3D (ID 0017, ZUORDNUNG 0030, ARTINR 200000077), x mit Kreisel 08 verschoben (-2.59)"
},
{
"function": "insert",
"block": "Separator_SP",
"x": 3756.79,
"y": 905.79,
"z": 2000.0,
"rotation": 180.0,
"comment": "aus Zeichnung: Separator_SP_3D (ID 0018, ZUORDNUNG 0030, ARTINR 200000077), x mit Kreisel 08 verschoben (-2.59)"
},
{
"function": "insert",
"block": "Separator_SP",
"x": 4538.26,
"y": -1553.42,
"z": 2000.0,
"rotation": 90.0,
"comment": "aus Zeichnung: Separator_SP_3D (ID 0019, ZUORDNUNG 0031, ARTINR 200000077), x mit Kreisel 07 verschoben (-2.33)"
},
{
"function": "insert",
"block": "Separator_SP",
"x": 4538.26,
"y": -3109.7,
"z": 2000.0,
"rotation": 270.0,
"comment": "aus Zeichnung: Separator_SP_3D (ID 0020, ZUORDNUNG 0033, ARTINR 200000077), x mit Kreisel 02 verschoben (-1.77)"
},
{
"function": "insert",
"block": "Separator_SP",
"x": 5338.26,
"y": -6594.16,
"z": 2000.0,
"rotation": 90.0,
"comment": "aus Zeichnung: Separator_SP_3D (ID 0021, ZUORDNUNG 0033, ARTINR 200000077), x mit Kreisel 02 verschoben (-1.77)"
},
{
"function": "insert",
"block": "Separator_SP",
"x": 6938.26,
"y": -6678.18,
"z": 2000.0,
"rotation": 90.0,
"comment": "aus Zeichnung: Separator_SP_3D (ID 0022, ZUORDNUNG 0035, ARTINR 200000077), x mit Kreisel 04 verschoben (+4.66)"
},
{
"function": "insert",
"block": "Separator_SP",
"x": 6138.26,
"y": 362.53,
"z": 2000.0,
"rotation": 270.0,
"comment": "aus Zeichnung: Separator_SP_3D (ID 0023, ZUORDNUNG 0035, ARTINR 200000077), x mit Kreisel 04 verschoben (+4.66)"
},
{
"function": "insert",
"block": "Separator_SP",
"x": 7093.89,
"y": 1885.99,
"z": 2000.0,
"rotation": 0.0,
"comment": "aus Zeichnung: Separator_SP_3D (ID 0024, ZUORDNUNG 0036, ARTINR 200000077), x mit Kreisel 05 verschoben (+4.66)"
},
{
"function": "insert",
"block": "Separator_SP",
"x": 6938.26,
"y": 2848.54,
"z": 2000.0,
"rotation": 90.0,
"comment": "aus Zeichnung: Separator_SP_3D (ID 0025, ZUORDNUNG 0037, ARTINR 200000077), x mit Kreisel 06 verschoben (+4.66)"
},
{
"function": "insert",
"block": "BTMT-Beladung",
"x": 14622.43,
"y": 1085.99,
"z": 2000.0,
"rotation": 0.0,
"comment": "aus Zeichnung: BTMT-Beladung_3D (ID 0026, ARTINR 829662012), x mit Kreisel 05 verschoben (+4.66)"
},
{
"function": "insert",
"block": "SC_Entladung",
"x": -2246.43,
"y": 581.63,
"z": 2000.0,
"rotation": 179.49,
"comment": "aus Zeichnung: SC_Entladung_3D (ID 0027, ARTINR 400100156)"
}
]