#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ test_export_separator_bbox.py - Feste Separator-Symbol-Bounding-Box. Laeuft komplett ohne BricsCAD (reine Python-Logik). Regressionstest fuer einen realen Mubea-Befund: die meisten Separatoren blieben ohne "Nachbarn", weil in ihrem export_raw.json KEINE Bounding-Box stand. Zwei Ursachen: 1. In eine VF_n/GF_n-Kette EINGEBETTETE Separatoren sind seit der Umstellung auf die "sepliste"-XDATA kein reales INSERT mehr - vla-getboundingbox kann fuer sie keine Box liefern. 2. Frei platzierte Separator_SP-INSERTs, deren vla-getboundingbox beim Export scheiterte (z.B. eingefrorener Layer). Beide bekommen jetzt eine feste Symbol-Box aus cfg [Boundingbox] separator_box_* (siehe export_neighbors.separator_bbox / load_separator_box_mm), damit sie ein "_bbox" haben und an der Nachbarschafts-/Umlauf-/Zuordnungs- erkennung teilnehmen. """ import os import sys sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib")) from export_neighbors import ( # noqa: E402 separator_bbox, load_separator_box_mm, SEPARATOR_BOX_LAENGE_MM, SEPARATOR_BOX_BREITE_MM, SEPARATOR_BOX_HOEHE_MM, ) from export_csv import ( # noqa: E402 bbox_columns, _fallback_separator_bbox, ) class TestSeparatorBboxGeometrie: def test_unrotiert(self): box = (210.0, 150.0, 14.0) bb = separator_bbox(1000.0, 2000.0, 0.0, separator_box_mm=box) assert bb["cx"] == 1000.0 and bb["cy"] == 2000.0 assert abs(bb["dx"] - 210.0) < 1e-6, "Laenge liegt bei Drehung 0 entlang X" assert abs(bb["dy"] - 150.0) < 1e-6, "Breite liegt bei Drehung 0 entlang Y" assert abs(bb["dz"] - 14.0) < 1e-6 def test_um_90_grad_gedreht_vertauscht_dx_dy(self): box = (210.0, 150.0, 14.0) bb = separator_bbox(0.0, 0.0, 90.0, separator_box_mm=box) assert abs(bb["dx"] - 150.0) < 1e-6, "bei 90 Grad liegt die Breite entlang X" assert abs(bb["dy"] - 210.0) < 1e-6, "bei 90 Grad liegt die Laenge entlang Y" def test_default_masse_aus_cfg(self): # load_separator_box_mm liest cfg/export.cfg; die Werte muessen positiv # und plausibel sein (Symbol ~210 x 150 x 14). laenge, breite, hoehe = load_separator_box_mm() assert laenge > 0 and breite > 0 and hoehe > 0 # Fallback-Konstanten muessen mit dem gemessenen Symbol uebereinstimmen assert (SEPARATOR_BOX_LAENGE_MM, SEPARATOR_BOX_BREITE_MM, SEPARATOR_BOX_HOEHE_MM) == (210.0, 150.0, 14.0) class TestFallbackSeparatorBbox: def test_fehlende_bbox_wird_ergaenzt(self): """Ein Separator-INSERT ohne bbox (vla-getboundingbox scheiterte) bekommt aus Position/Drehung + fester Box eine _bbox.""" block = {"block_name": "Separator_SP_3D", "x": 5000.0, "y": -3000.0, "z": 100.0, "rotation": 90.0, "attribs": {"ID": "0050"}} cols = bbox_columns(block) assert cols["_bbox"] is None, "Vorbedingung: Block hat keine bbox" cols = _fallback_separator_bbox(cols, block, separator_box_mm=(210.0, 150.0, 14.0)) assert cols["_bbox"] is not None, "Fallback hat keine _bbox gesetzt" assert cols["_bbox"]["cx"] == 5000.0 and cols["_bbox"]["cy"] == -3000.0 # 90 Grad -> dx=Breite, dy=Laenge assert abs(cols["_bbox"]["dx"] - 150.0) < 1e-6 assert abs(cols["_bbox"]["dy"] - 210.0) < 1e-6 assert cols["boundingbox"] != "", "Boundingbox-Spalte muss nun gefuellt sein" def test_vorhandene_bbox_bleibt_unveraendert(self): """Hat der Block bereits eine echte bbox (vla-getboundingbox erfolgreich), darf der Fallback sie NICHT ueberschreiben.""" block = {"block_name": "Separator_SP_3D", "x": 5000.0, "y": -3000.0, "rotation": 90.0, "bbox": {"cx": 5001.0, "cy": -3002.0, "cz": 7.0, "dx": 209.9, "dy": 150.0, "dz": 3.0}} cols = bbox_columns(block) assert cols["_bbox"] is not None original = dict(cols["_bbox"]) cols2 = _fallback_separator_bbox(cols, block) assert cols2["_bbox"] == original, "echte bbox wurde vom Fallback ueberschrieben"