utils.py mit eingecheckt. Beispieldatei aus Config erzeugen.
This commit is contained in:
+146
-8
@@ -10,6 +10,7 @@ für verschiedene Testfälle (Nummerierung, SPS, Erdung, etc.).
|
||||
import argparse
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
from pathlib import Path
|
||||
import ezdxf
|
||||
from ezdxf.math import Vec3
|
||||
@@ -17,16 +18,44 @@ from ezdxf.math import Vec3
|
||||
# Umgebungsvariablen
|
||||
PROJECT = os.getenv('PROJECT', Path(__file__).parent.parent.absolute())
|
||||
PROJECT_TEST = os.getenv('PROJECT_TEST', os.path.join(PROJECT, 'testdata'))
|
||||
PROJECT_CFG = os.getenv('PROJECT_CFG', os.path.join(PROJECT, 'cfg'))
|
||||
|
||||
|
||||
class TestDataGenerator:
|
||||
"""Generiert Test-DXF-Dateien für verschiedene Szenarien"""
|
||||
|
||||
def __init__(self, filename, test_type):
|
||||
def __init__(self, filename, test_type, config_file=None):
|
||||
self.filename = filename
|
||||
self.test_type = test_type
|
||||
self.doc = None
|
||||
self.msp = None
|
||||
self.config = None
|
||||
|
||||
# Lade Config-Datei falls angegeben
|
||||
if config_file:
|
||||
self.load_config(config_file)
|
||||
|
||||
def load_config(self, config_file):
|
||||
"""
|
||||
Lädt die JSON-Konfigurationsdatei
|
||||
|
||||
Args:
|
||||
config_file: Pfad zur JSON-Config-Datei
|
||||
"""
|
||||
config_path = Path(config_file)
|
||||
if not config_path.is_absolute():
|
||||
config_path = Path(PROJECT_CFG) / config_file
|
||||
|
||||
try:
|
||||
with open(config_path, 'r', encoding='utf-8') as f:
|
||||
self.config = json.load(f)
|
||||
print(f"Config geladen: {config_path}")
|
||||
except FileNotFoundError:
|
||||
print(f"Warnung: Config-Datei nicht gefunden: {config_path}")
|
||||
self.config = None
|
||||
except json.JSONDecodeError as e:
|
||||
print(f"Fehler beim Parsen der Config-Datei: {e}")
|
||||
self.config = None
|
||||
|
||||
def create_document(self):
|
||||
"""Erstellt ein neues DXF-Dokument"""
|
||||
@@ -437,11 +466,7 @@ class TestDataGenerator:
|
||||
"""
|
||||
Generiert Testdaten für Nummerierung-Szenario
|
||||
|
||||
Layout:
|
||||
- 3x MA-1@@ rechts oben nebeneinander
|
||||
- 1x MA-1@@ links unten
|
||||
- 3x MA-2@@ rechts unten (leicht versetzt)
|
||||
- 3 Renamer-Rahmen (2x Rechteck, 1x Polylinie)
|
||||
Verwendet entweder die JSON-Config oder Hard-coded Defaults
|
||||
"""
|
||||
print("Generiere Nummerierung-Testdaten...")
|
||||
|
||||
@@ -452,6 +477,113 @@ class TestDataGenerator:
|
||||
print("Fehler: io-Block konnte nicht erstellt werden")
|
||||
return
|
||||
|
||||
# Wenn Config geladen ist, verwende sie, ansonsten Hard-coded Defaults
|
||||
if self.config and 'test_scenes' in self.config and 'Nummerierung1' in self.config['test_scenes']:
|
||||
print("Verwende JSON-Config für Nummerierung1...")
|
||||
self._generate_nummerierung_from_config()
|
||||
else:
|
||||
print("Verwende Hard-coded Defaults für Nummerierung...")
|
||||
self._generate_nummerierung_hardcoded()
|
||||
|
||||
def _generate_ma_group(self, group, ma_defaults, width_per_char, fixed_height, spacing_factor, y_offsets_list):
|
||||
"""
|
||||
Generiert eine Gruppe von MA-Symbolen
|
||||
|
||||
Args:
|
||||
group: Dict mit Gruppen-Config (name, count, layout_type, base_x, base_y, spacing)
|
||||
ma_defaults: Dict mit MA-Default-Attributen
|
||||
width_per_char: Breite pro Zeichen
|
||||
fixed_height: Fixe Symbol-Höhe
|
||||
spacing_factor: Spacing-Faktor zwischen Symbolen
|
||||
y_offsets_list: Liste von Y-Offsets für horizontal_offset Layout
|
||||
"""
|
||||
name = group['name']
|
||||
count = group['count']
|
||||
layout_type = group['layout_type']
|
||||
base_x = group['base_x']
|
||||
base_y = group['base_y']
|
||||
|
||||
# Extrahiere IO-Pattern aus Name (z.B. "MA-1@@_top" -> "MA-1@@")
|
||||
io_pattern = name.split('_')[0]
|
||||
|
||||
# Berechne Symbol-Ausdehnung
|
||||
symbol_width = len(io_pattern) * width_per_char
|
||||
|
||||
# Berechne Spacing
|
||||
if layout_type in ['horizontal', 'horizontal_offset']:
|
||||
actual_spacing = symbol_width * spacing_factor
|
||||
else:
|
||||
actual_spacing = 0
|
||||
|
||||
# Hole Attribute aus ma_defaults
|
||||
attributes = ma_defaults.get('attributes', {})
|
||||
layer = ma_defaults.get('layer', 'ILS_MOTOR')
|
||||
|
||||
# Generiere Symbole basierend auf Layout-Typ
|
||||
for i in range(count):
|
||||
if layout_type == 'single':
|
||||
x, y = base_x, base_y
|
||||
elif layout_type == 'horizontal':
|
||||
x = base_x + i * actual_spacing
|
||||
y = base_y
|
||||
elif layout_type == 'horizontal_offset':
|
||||
x = base_x + i * actual_spacing
|
||||
y_offset = y_offsets_list[i % len(y_offsets_list)]
|
||||
y = base_y + y_offset
|
||||
else:
|
||||
print(f"Unbekannter Layout-Typ: {layout_type}")
|
||||
continue
|
||||
|
||||
# Erstelle Block-Referenz
|
||||
blockref = self.msp.add_blockref(
|
||||
'io',
|
||||
insert=(x, y),
|
||||
dxfattribs={'layer': layer}
|
||||
)
|
||||
|
||||
# Setze Attribute (dynamisch IO und BEZEICHNUNG)
|
||||
attrib_values = attributes.copy()
|
||||
attrib_values['IO'] = io_pattern
|
||||
attrib_values['BEZEICHNUNG'] = f"Motor {io_pattern}"
|
||||
|
||||
blockref.add_auto_attribs(attrib_values)
|
||||
|
||||
def _generate_nummerierung_from_config(self):
|
||||
"""Generiert Nummerierung-Testdaten aus JSON-Config"""
|
||||
scene = self.config['test_scenes']['Nummerierung1']
|
||||
ma_defaults = self.config.get('ma_defaults', {})
|
||||
general = self.config.get('general', {})
|
||||
|
||||
# Hole Dimensions aus Config
|
||||
dimensions = ma_defaults.get('dimensions', {})
|
||||
width_per_char = dimensions.get('width_per_char', 201.49)
|
||||
fixed_height = dimensions.get('fixed_height', 380.94)
|
||||
|
||||
# Hole Layout-Einstellungen
|
||||
layout = general.get('layout', {})
|
||||
spacing_factor = layout.get('symbol_spacing_factor', 1.2)
|
||||
y_offsets_list = layout.get('horizontal_offset_y_offsets', [0, -50, 50])
|
||||
|
||||
# Generiere MA-Gruppen aus Config
|
||||
for group in scene.get('ma_groups', []):
|
||||
self._generate_ma_group(group, ma_defaults, width_per_char, fixed_height, spacing_factor, y_offsets_list)
|
||||
|
||||
# Generiere Renamer-Rahmen aus Config
|
||||
for frame_config in scene.get('renaming_frames', []):
|
||||
self.create_renamer_frame(
|
||||
insert_point=(frame_config['x'], frame_config['y']),
|
||||
width=frame_config['width'],
|
||||
height=frame_config['height'],
|
||||
name=frame_config['name'],
|
||||
kennzeichnung=frame_config['kennzeichnung'],
|
||||
layer_name=frame_config['layer_name'],
|
||||
direction=frame_config['direction'],
|
||||
use_polyline=frame_config.get('use_polyline', False)
|
||||
)
|
||||
|
||||
def _generate_nummerierung_hardcoded(self):
|
||||
"""Generiert Nummerierung-Testdaten mit Hard-coded Werten (Fallback)"""
|
||||
|
||||
# Berechne Symbol-Ausdehnung für korrekte Positionierung
|
||||
ma1_width, ma1_height = self.calculate_symbol_extent('MA-1@@')
|
||||
ma2_width, ma2_height = self.calculate_symbol_extent('MA-2@@')
|
||||
@@ -535,7 +667,6 @@ class TestDataGenerator:
|
||||
'ARTIKELBEZEICHN': 'E-Teile für SEW Motor ASE1-HAN10ES-BG',
|
||||
'KENNZEICHNUNG': '=A01+UH00',
|
||||
'TEXT-D': '',
|
||||
'TEXT-E': '',
|
||||
'TEXT-ES': '',
|
||||
'TEXT-F': '',
|
||||
'ID': '',
|
||||
@@ -642,6 +773,13 @@ def main():
|
||||
help='Ausgabeverzeichnis (Standard: testdata)'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--config',
|
||||
type=str,
|
||||
default='create_tests.json',
|
||||
help='JSON-Konfigurationsdatei (Standard: create_tests.json)'
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Stelle sicher, dass Dateiname .dxf Endung hat
|
||||
@@ -649,7 +787,7 @@ def main():
|
||||
args.filename += '.dxf'
|
||||
|
||||
# Generiere Testdaten
|
||||
generator = TestDataGenerator(args.filename, args.type)
|
||||
generator = TestDataGenerator(args.filename, args.type, config_file=args.config)
|
||||
|
||||
if generator.generate():
|
||||
generator.save(args.output_dir)
|
||||
|
||||
Reference in New Issue
Block a user