# -*- coding: utf-8 -*- """Tests fuer den Lagebezug ueber die TeileId (dxf_registration.derive_from_ids). Nachbau der Dematic-Befunde: dieselbe Anlage einmal als gemeinsame Zeichnung (Versatz 0) und einmal als verschobene Mechanik-Zeichnung (~163 m in y). Die Separator-Bloecke sitzen je nach Drehung +-60 mm neben der CSV-Position, die Scanner-Bloecke 360 mm - die automatische Abstimmung rastete dort auf den Scannern ein und lag 360 mm daneben. """ import ezdxf import pytest import tro_annotate from dxf_registration import MIN_INLIERS, derive_from_ids SHIFT = (-466.1, 163549.3) # DXF = CSV + SHIFT (Dematic Mechanik) def _csv(n=11): seps = {f"{38 + i:04d}": ("Separator", 3000.0 + i * 800.0, 12120.0) for i in range(n)} scans = {f"{60 + i:04d}": ("Scanner", 3000.0 + i * 900.0, 25000.0) for i in range(7)} return {**seps, **scans} def _dxf(csv_points, shift=SHIFT): out = {} for i, (tid, (rolle, x, y)) in enumerate(csv_points.items()): if rolle == "Separator": bias = (-60.0 if i % 3 else 60.0, 0.0) else: bias = (0.0, -360.0) out[tid] = (rolle, x + shift[0] + bias[0], y + shift[1] + bias[1]) return out def test_verschobene_zeichnung_ueber_die_separatoren(): csv_points = _csv() t = derive_from_ids(csv_points, _dxf(csv_points), "x.csv", "mech.dxf") assert t is not None and t.source == "ids" # DXF -> CSV: Gegenrichtung des Verschubs, Separator-Bias hoechstens 60 mm assert abs(t.dx - (-SHIFT[0])) <= 60.0 + 1e-6 assert t.dy == pytest.approx(-SHIFT[1]) assert "Separator" in t.anchor def test_gemeinsame_zeichnung_versatz_null(): csv_points = _csv() t = derive_from_ids(csv_points, _dxf(csv_points, shift=(0.0, 0.0))) assert abs(t.dx) <= 60.0 + 1e-6 and t.dy == pytest.approx(0.0) def test_ohne_genug_separatoren_die_scanner(): csv_points = _csv(n=MIN_INLIERS - 1) t = derive_from_ids(csv_points, _dxf(csv_points)) assert t is not None and "Scanner" in t.anchor assert t.dy == pytest.approx(-SHIFT[1] + 360.0) # Scanner-Bias bleibt drin def test_ohne_ids_kein_ergebnis(): assert derive_from_ids(_csv(), {}) is None def test_uneinheitlicher_versatz_wird_nicht_genommen(): csv_points = _csv() dxf = _dxf(csv_points) # die Haelfte der Separatoren weit daneben (falsche IDs) -> keine Rolle passt for tid in list(dxf)[:6]: rolle, x, y = dxf[tid] dxf[tid] = (rolle, x + 5000.0, y) for tid in [k for k, v in dxf.items() if v[0] == "Scanner"]: del dxf[tid] assert derive_from_ids(csv_points, dxf) is None def test_ids_aus_der_zeichnung(): doc = ezdxf.new() blk = doc.blocks.new("Separator_SP_3D") blk.add_attdef("ID", (0, 0)) andere = doc.blocks.new("KREISEL_1_STANDARD_3619") andere.add_attdef("ID", (0, 0)) msp = doc.modelspace() msp.add_blockref("Separator_SP_3D", (10, 20)).add_auto_attribs({"ID": "0038"}) msp.add_blockref("Separator_SP_3D", (30, 40)).add_auto_attribs({"ID": "0039"}) msp.add_blockref("Separator_SP_3D", (50, 60)).add_auto_attribs({"ID": "0039"}) msp.add_blockref("Separator_SP_3D", (70, 80)).add_auto_attribs({"ID": ""}) msp.add_blockref("KREISEL_1_STANDARD_3619", (0, 0)).add_auto_attribs({"ID": "0001"}) # nur eindeutige Ziffern-IDs von Anker-Bloecken assert tro_annotate.id_points_dxf(msp) == {"0038": ("Separator", 10.0, 20.0)}