# -*- coding: utf-8 -*- """ placeblocks.py Erzeugt DXF-Elemente aus einer RuleDesigner-CSV. """ import os import sys import csv import argparse import configparser import ezdxf from ezdxf import units from ezdxf.entities import Line from pathlib import Path import math from utils import check_environment_var, setup_logger from handler_context import HandlerContext from Elemente import ( Kreisel, VarioFoerderer, Gefaellestrecke, Angetriebene_Kurve, Bt_element, Omniflo, Eckrad, ) import as_es_methoden import block_methoden import arbeiten_mit_csv # --------------------------------------------------------- Konstante Parameter ATTR_TAG = "TeileId" # Attributtag im Block RADIUS = 400 # Radius der Kreiselkreise (mm) # --------------------------------------------------------- Hilfsfunktionen def handle_ils_2_0_kreisel(ctx): """Erstellt ein Kreisel in der neuen Dxf""" kreisel = Kreisel.Kreisel.from_merkmale(ctx.teileid, ctx.x, ctx.y, ctx.merkmale) block_scanner = "SCAN" block_separatoren = "S-LP" scanner_x = kreisel.x scanner_y = kreisel.y separatoren_x = kreisel.x separatoren_y = kreisel.y + 160 block_methoden.import_block(block_scanner, ctx.lib_doc, ctx.doc) block_methoden.import_block(block_separatoren, ctx.lib_doc, ctx.doc) i = 0 while i < kreisel.anzahl_scanner: ctx.msp.add_blockref(block_scanner, (scanner_x, scanner_y, kreisel.hoehe)) scanner_x = scanner_x + 300 i = i + 1 i = 0 while i < kreisel.anzahl_separatoren: ctx.msp.add_blockref( block_separatoren, (separatoren_x, separatoren_y, kreisel.hoehe) ) separatoren_x = separatoren_x + 300 i = i + 1 # Die Koordinaten (x, y) sind die Mitte zwischen den beiden Blöcken (bereits transformiert) pos1 = kreisel.pos1 pos2 = kreisel.pos2 positions = [pos1, pos2] for i, sym in enumerate(ctx.symbols): blockname = sym["name"] offset = sym["offset"] rotation = sym["rotation"] if i < len(positions): pos = ( positions[i][0] + offset[0], positions[i][1] + offset[1], kreisel.hoehe, ) block_methoden.import_block(blockname, ctx.lib_doc, ctx.doc) blockref_layer, color = block_methoden.get_insert_color_layer( ctx.lib_doc, blockname ) bref = ctx.msp.add_blockref( blockname, pos, dxfattribs={"layer": blockref_layer} ) bref.add_auto_attribs({ATTR_TAG: ctx.teileid}) if ctx.verbose: print( f"[INFO] Block '{blockname}' (Kreisel) → {ctx.teileid} " f"({pos[0]:.1f}, {pos[1]:.1f}), rot={rotation}" ) # Linien zeichnen block_methoden.import_block("Pinbereich", ctx.lib_doc, ctx.doc) Kreisel.Kreisel.draw_kreisel_lines(ctx.msp, pos1, pos2, kreisel) Kreisel.Kreisel.draw_kreisel_drehrichtung_markierung( ctx.msp, pos1, pos2, kreisel, ctx.lib_doc, ctx.doc, ctx.verbose ) def handle_ils_2_0_eckrad(ctx): """Erstellt ein Eckrad in der neuen Dxf""" eckrad_rechts, eckrad_links, hight = Eckrad.Eckrad.erstellung_eckrad_richtung( ctx.merkmale, ctx.doc, ctx.lib_doc ) if ctx.merkmale.get("Drehrichtung") == "UZS": ctx.msp.add_blockref(eckrad_rechts, (ctx.x, ctx.y, hight)) elif ctx.merkmale.get("Drehrichtung") == "GUZS": ctx.msp.add_blockref(eckrad_links, (ctx.x, ctx.y, hight)) else: ctx.msp.add_blockref("AN8", (ctx.x, ctx.y, hight)) def handle_ils_2_0_gefaellestrecke(ctx): """Erstellt eine Gefällestrecke in der neuen Dxf""" # Vorbereitung der attributen gefaelle_objekt = Gefaellestrecke.Gefaellestrecke.from_merkmale( ctx.teileid, ctx.x, ctx.y, ctx.merkmale ) asoffset = float(ctx.config.get("ILS 2.0 Gefällestrecke", "asoffset")) esoffset = float(ctx.config.get("ILS 2.0 Gefällestrecke", "esoffset")) upper_hoehe_gefaelle = gefaelle_objekt.h1 lower_hoehe_gefaelle = gefaelle_objekt.h0 hoehe_gefaelle = gefaelle_objekt.hight_zwischen laenge = gefaelle_objekt.laenge halbe_laenge = laenge / 2 rotation = gefaelle_objekt.drehung winkel = math.radians(float(rotation)) dx = halbe_laenge * math.sin(winkel * -1) dy = halbe_laenge * math.cos(winkel) start = ctx.x + dx, ctx.y + dy, upper_hoehe_gefaelle if "6-SP" not in ctx.doc.layers: ctx.doc.layers.add(name="6-SP", color=7) gefaelle_layer = "6-SP" verbunden_am_einen = False richtung2 = "DEFAULT" unterschiedlich = False anzahl_seperatoren_oder_scan( ctx.msp, ctx.doc, ctx.lib_doc, gefaelle_objekt, ctx.config ) for nachbarn in ctx.strecken_nachbarn: if ctx.teileid == nachbarn.get("Id"): gefaellestrecke_nachbarn = nachbarn break # Fall verbunden mit exakt einem Kreisel if ( "Drehung0" in gefaellestrecke_nachbarn and "Drehung1" not in gefaellestrecke_nachbarn ): # Entnehmen der Attribute der Nacharn drehung0 = gefaellestrecke_nachbarn.get("Drehung0") x0_kreisel = float(gefaellestrecke_nachbarn.get("x0")) y0_kreisel = float(gefaellestrecke_nachbarn.get("y0")) hoehe0 = float(gefaellestrecke_nachbarn.get("Hoehe0")) richtung0 = float(gefaellestrecke_nachbarn.get("rotation0")) richtung_rad0 = math.radians(richtung0) abstand0 = float(gefaellestrecke_nachbarn.get("abstand0")) * 1000 # Austauch der höhen und dementsprechende Koorekur falls nötig, dieser Schritt ist notwendig für die Konsistzenz der Blockerstellung as_es_methoden.vertausch_der_höhe(gefaelle_objekt) # Übrerprüfung ob die Gefällestrecke einen Motor oder Umlenkstation braucht, wenn es mit einer angetriebenen Kurve verbunden ist upper_hoehe_gefaelle = gefaelle_objekt.h1 lower_hoehe_gefaelle = gefaelle_objekt.h0 rotation = gefaelle_objekt.drehung ( block_Vario_Umlenkstation_500mm, block_Vario_Motorstation_500mm, blockname_motor_links, blockname_umlenk_links, ) = block_methoden.rotatate_and_left_motor_umlenk( ctx.doc, ctx.lib_doc, ctx.config ) hat_zusatz = Gefaellestrecke.Gefaellestrecke.hat_motor_umlenk_station( gefaelle_objekt, gefaellestrecke_nachbarn ) hat_motor_0 = hat_zusatz.get("hat_motor_0") hat_umlenk_0 = hat_zusatz.get("hat_umlenk_0") tefkurve_0 = hat_zusatz.get("tefkurve_0") hat_motor_1 = hat_zusatz.get("hat_motor_1") hat_umlenk_1 = hat_zusatz.get("hat_umlenk_1") tefkurve_1 = hat_zusatz.get("tefkurve_1") umlenk_gerade = hat_zusatz.get("umlenk_gerade") motor_gerade = hat_zusatz.get("motor_gerade") verbunden_am_einen = True # Überprüfung ist die Gefällestrecke direkt mit dem Kreisel verbunden, anstelle des Stahlbandes am_kreisel, kreisel_verbunden = as_es_methoden.am_kreisel_direct_verbunden( ctx.x, ctx.y, upper_hoehe_gefaelle, lower_hoehe_gefaelle, x0_kreisel, y0_kreisel, richtung_rad0, abstand0, dx, dy, None, None, None, None, ) # Bearbeitung der Gefälle Strecke falls dies der Fall ist if am_kreisel == 1: if hat_motor_0 == False and hat_umlenk_0 == False: Gefaellestrecke.Gefaellestrecke.erstehlung_von_gefalle_ohne_aussnahmen( ctx.msp, ctx.x, ctx.y, upper_hoehe_gefaelle, lower_hoehe_gefaelle, halbe_laenge, winkel, ) return # Bearbeitung der Gefällestrecke die direkt am Kreisel hängt und eine Motor- Umlenkstation besitzt else: dy = halbe_laenge * math.cos(0) start = [ctx.x, ctx.y + dy, upper_hoehe_gefaelle] ende = [ctx.x, ctx.y - dy, lower_hoehe_gefaelle] blockname = f"Ils_2.0_Gefaellestrecke_{laenge}_{hoehe_gefaelle}_{hat_umlenk_0}_{hat_motor_0}_{tefkurve_0}_{umlenk_gerade}_{motor_gerade}" if blockname not in ctx.doc.blocks: block = ctx.doc.blocks.new(name=blockname, base_point=(0, 0, 0)) dy = halbe_laenge * math.cos(0) start = [ctx.x, ctx.y + dy, upper_hoehe_gefaelle] ende = [ctx.x, ctx.y - dy, lower_hoehe_gefaelle] start, ende = ( Gefaellestrecke.Gefaellestrecke.ein_motor_oder_eine_umlenk( ctx.x, ctx.y, start, ende, ctx.doc, ctx.lib_doc, hoehe_gefaelle, block_Vario_Umlenkstation_500mm, block_Vario_Motorstation_500mm, blockname_motor_links, blockname_umlenk_links, hat_motor_0, hat_umlenk_0, tefkurve_0, block, umlenk_gerade, motor_gerade, ) ) line = Line.new(dxfattribs={"start": start, "end": ende}) line.translate(-ctx.x, -ctx.y, -hoehe_gefaelle) block.add_entity(line) ctx.msp.add_blockref( blockname, (ctx.x, ctx.y, hoehe_gefaelle), dxfattribs={"rotation": rotation, "layer": gefaelle_layer}, ) return # Schauen ob die Gefällestrecke mit dem Höheren oder unterm Teil a, Kreisel Verbunden ist if upper_hoehe_gefaelle == hoehe0: hight = "higher" else: hight = "lower" # Erstelle den Block if hat_motor_0 == False and hat_umlenk_0 == False: blockname = f"Ils_2.0_Gefaellestrecke_{laenge}_{drehung0}_{hoehe_gefaelle}_{verbunden_am_einen}_{hight}" else: blockname = f"Ils_2.0_Gefaellestrecke_{laenge}_{drehung0}_{hoehe_gefaelle}_{verbunden_am_einen}_{hight}_{hat_umlenk_0}_{hat_motor_0}_{tefkurve_0}_{umlenk_gerade}_{motor_gerade}" if blockname in ctx.doc.blocks: bref = ctx.msp.add_blockref( blockname, (ctx.x, ctx.y, hoehe_gefaelle), dxfattribs={"rotation": rotation, "layer": gefaelle_layer}, ) a = bref.add_attrib( tag="NAME", text=ctx.merkmale.get("bezeichner"), insert=(ctx.x, ctx.y) ) a.is_invisible = True return if laenge > asoffset or laenge > esoffset: block = ctx.doc.blocks.new(name=blockname, base_point=(0, 0, 0)) else: block = None dy = halbe_laenge * math.cos(0) start = [ctx.x, ctx.y + dy, upper_hoehe_gefaelle] ende = [ctx.x, ctx.y - dy, lower_hoehe_gefaelle] start, ende = Gefaellestrecke.Gefaellestrecke.ein_motor_oder_eine_umlenk( ctx.x, ctx.y, start, ende, ctx.doc, ctx.lib_doc, hoehe_gefaelle, block_Vario_Umlenkstation_500mm, block_Vario_Motorstation_500mm, blockname_motor_links, blockname_umlenk_links, hat_motor_0, hat_umlenk_0, tefkurve_0, block, umlenk_gerade, motor_gerade, ) # Füge die AS- Eselemente ein, falls die Gefällestrecke größer ist als das jeweilige Element if richtung0 == 0.0 or richtung0 == -180: rotation_ersatz = "V" else: rotation_ersatz = "H" if rotation_ersatz == "H": if ctx.x > x0_kreisel: as_es_rotation = -90 else: as_es_rotation = -270 else: if ctx.y > y0_kreisel: as_es_rotation = 0 else: as_es_rotation = -180 # Fügt as oder es Element ein oder fügt nur as oder es element hinzu falls nötig only_es_or_as = as_es_methoden.erstellung_gefaelle_block_verbunden_an_einen( ctx.msp, ctx.x, ctx.y, ctx.doc, ctx.lib_doc, upper_hoehe_gefaelle, lower_hoehe_gefaelle, hoehe_gefaelle, drehung0, laenge, blockname, ctx.config, hight, None, None, None, block, start, ende, None, as_es_rotation, ) if only_es_or_as == False: bref = ctx.msp.add_blockref( blockname, (ctx.x, ctx.y, hoehe_gefaelle), dxfattribs={"rotation": rotation, "layer": gefaelle_layer}, ) a = bref.add_attrib( tag="NAME", text=ctx.merkmale.get("bezeichner"), insert=(ctx.x, ctx.y) ) a.is_invisible = True # Abarbeitung der Gefallestrecke falls es mit 2 Kreiseln verbunden ist elif ( "Drehung0" in gefaellestrecke_nachbarn and "Drehung1" in gefaellestrecke_nachbarn ): # Hollen der nötigen Atributte dx = halbe_laenge * math.sin(winkel * -1) dy = halbe_laenge * math.cos(winkel) drehung0 = gefaellestrecke_nachbarn.get("Drehung0") drehung1 = gefaellestrecke_nachbarn.get("Drehung1") hoehe0 = gefaellestrecke_nachbarn.get("Hoehe0") hoehe1 = gefaellestrecke_nachbarn.get("Hoehe1") x0_kreisel = float(gefaellestrecke_nachbarn.get("x0")) y0_kreisel = float(gefaellestrecke_nachbarn.get("y0")) x1_kreisel = float(gefaellestrecke_nachbarn.get("x1")) y1_kreisel = float(gefaellestrecke_nachbarn.get("y1")) richtung0 = float(gefaellestrecke_nachbarn.get("rotation0")) richtung1 = float(gefaellestrecke_nachbarn.get("rotation1")) richtung2 = "DEFAULT" richtung_rad0 = math.radians(richtung0) richtung_rad1 = math.radians(richtung1) abstand0 = float(gefaellestrecke_nachbarn.get("abstand0")) * 1000 abstand1 = float(gefaellestrecke_nachbarn.get("abstand1")) * 1000 rotation = float(ctx.merkmale.get("Drehung")) # Überprüfung ist die Gefällestrecke direkt mit eimen Kreisel verbunden, anstelle des Stahlbandes und wenn ja wie viele am_kreisel, kreisel_verbunden = as_es_methoden.am_kreisel_direct_verbunden( ctx.x, ctx.y, upper_hoehe_gefaelle, lower_hoehe_gefaelle, x0_kreisel, y0_kreisel, richtung_rad0, abstand0, dx, dy, x1_kreisel, y1_kreisel, richtung_rad1, abstand1, ) # falls beide enden direkt mit dem Kreisel verbunden sind zeichnen einfacher Linie if kreisel_verbunden == 2: Gefaellestrecke.Gefaellestrecke.erstehlung_von_gefalle_ohne_aussnahmen( ctx.msp, ctx.x, ctx.y, upper_hoehe_gefaelle, lower_hoehe_gefaelle, halbe_laenge, winkel, ) return # umbezeichnung von den geraden zu strings ob es Vertikal oder Horizontal ist if richtung0 == 90.0 or richtung0 == 270: richtung0 = "Vertikal" else: richtung0 = "Horizontal" if richtung1 == 90.0 or richtung1 == 270: richtung1 = "Vertikal" else: richtung1 = "Horizontal" richtung2, unterschiedlich = as_es_methoden.am_kreisel_direct_verbunden( ctx.x, ctx.y, upper_hoehe_gefaelle, lower_hoehe_gefaelle, x0_kreisel, y0_kreisel, richtung_rad0, abstand0, dx, dy, x1_kreisel, y1_kreisel, richtung_rad1, abstand1, kreisel_verbunden, richtung0, richtung1, richtung2, ) # Berechnung des Gefälles if hoehe0 > hoehe1: hight_position = "higher" else: hight_position = "lower" rotation, drehung0, drehung1, hight_position = ( Gefaellestrecke.Gefaellestrecke.rotation_mit_zwei_verbunden( gefaellestrecke_nachbarn, richtung2, richtung0, am_kreisel, kreisel_verbunden, hight_position, ) ) # geben der richtung2 eines wertes außer default wenn beide kreisel die gleiche richung haben if kreisel_verbunden == 1 and richtung2 == "DEFAULT": richtung2 = richtung0 if richtung2 == "DEFAULT": blockname = f"Ils_2.0_Gefaellestrecke_{laenge}_{hoehe_gefaelle}_{drehung0}_{drehung1}_{hight_position}_{verbunden_am_einen}" else: blockname = f"Ils_2.0_Gefaellestrecke_{laenge}_{hoehe_gefaelle}_{drehung0}_{drehung1}_{hight_position}_{unterschiedlich}_{richtung2}_{verbunden_am_einen}" as_es_methoden.gefaellegerade_erstellung( gefaelle_objekt, ctx.doc, ctx.lib_doc, richtung2, drehung0, drehung1, hight_position, blockname, ctx.config, ) bref = ctx.msp.add_blockref( blockname, (ctx.x, ctx.y, hoehe_gefaelle), dxfattribs={"rotation": rotation, "layer": gefaelle_layer}, ) a = bref.add_attrib( tag="NAME", text=ctx.merkmale.get("bezeichner"), insert=(ctx.x, ctx.y) ) a.is_invisible = True # falls eine gefällestrecke nicht mit einem kreisel verbunden ist else: # Schauen ob die Gefällestruktur mit einer Kurve verbunden ist und deswegen ein Motor und oder eine Umlenkstation braucht ( block_Vario_Umlenkstation_500mm, block_Vario_Motorstation_500mm, blockname_motor_links, blockname_umlenk_links, ) = block_methoden.rotatate_and_left_motor_umlenk( ctx.doc, ctx.lib_doc, ctx.config ) hat_zusatz = Gefaellestrecke.Gefaellestrecke.hat_motor_umlenk_station( gefaelle_objekt, gefaellestrecke_nachbarn ) hat_motor_0 = hat_zusatz.get("hat_motor_0") hat_umlenk_0 = hat_zusatz.get("hat_umlenk_0") tefkurve_0 = hat_zusatz.get("tefkurve_0") hat_motor_1 = hat_zusatz.get("hat_motor_1") hat_umlenk_1 = hat_zusatz.get("hat_umlenk_1") tefkurve_1 = hat_zusatz.get("tefkurve_1") umlenk_gerade = hat_zusatz.get("umlenk_gerade") motor_gerade = hat_zusatz.get("motor_gerade") blockname = f"Ils_2.0_Gefaellestrecke_{laenge}_{hoehe_gefaelle}_{hat_motor_0}_{hat_umlenk_0}_{tefkurve_0}_{hat_motor_1}_{hat_umlenk_1}_{tefkurve_1}_{umlenk_gerade}_{motor_gerade}" # behandlung der Gefällestrecke falls es keine Vario Kurve hat if ( hat_motor_0 == None and hat_umlenk_0 == None and hat_motor_1 == None and hat_umlenk_1 == None ): Gefaellestrecke.Gefaellestrecke.erstehlung_von_gefalle_ohne_aussnahmen( ctx.msp, ctx.x, ctx.y, upper_hoehe_gefaelle, lower_hoehe_gefaelle, halbe_laenge, winkel, ) return # Behandlung falls es mit einer odr zwei Vario kurve verbunden ist if blockname not in ctx.doc.blocks: rotation = float(ctx.merkmale.get("Drehung")) as_es_methoden.vertausch_der_höhe(gefaelle_objekt) upper_hoehe_gefaelle = gefaelle_objekt.h1 lower_hoehe_gefaelle = gefaelle_objekt.h0 rotation = gefaelle_objekt.drehung block = ctx.doc.blocks.new(name=blockname, base_point=(0, 0, 0)) dy = halbe_laenge * math.cos(0) start = [ctx.x, ctx.y + dy, upper_hoehe_gefaelle] ende = [ctx.x, ctx.y - dy, lower_hoehe_gefaelle] start, ende = Gefaellestrecke.Gefaellestrecke.ein_motor_oder_eine_umlenk( ctx.x, ctx.y, start, ende, ctx.doc, ctx.lib_doc, hoehe_gefaelle, block_Vario_Umlenkstation_500mm, block_Vario_Motorstation_500mm, blockname_motor_links, blockname_umlenk_links, hat_motor_0, hat_umlenk_0, tefkurve_0, block, umlenk_gerade, motor_gerade, ) start, ende = Gefaellestrecke.Gefaellestrecke.ein_motor_oder_eine_umlenk( ctx.x, ctx.y, start, ende, ctx.doc, ctx.lib_doc, hoehe_gefaelle, block_Vario_Umlenkstation_500mm, block_Vario_Motorstation_500mm, blockname_motor_links, blockname_umlenk_links, hat_motor_1, hat_umlenk_1, tefkurve_1, block, umlenk_gerade, motor_gerade, ) line = Line.new(dxfattribs={"start": start, "end": ende}) line.dxf.layer = "6-SP" line.translate(-ctx.x, -ctx.y, -hoehe_gefaelle) block.add_entity(line) ctx.msp.add_blockref( blockname, (ctx.x, ctx.y, hoehe_gefaelle), dxfattribs={"rotation": rotation, "layer": gefaelle_layer}, ) def handle_ils_2_0_variofoerderer(ctx): """Erstellt ein Vario Förderer in der neuen Dxf""" foerderer = VarioFoerderer.VarioFoerderer.from_merkmale( ctx.teileid, ctx.x, ctx.y, ctx.merkmale ) # für spätere Namens benenung der Vario forderer motor_vorhanden = foerderer.hat_motor umlenk_vorhanden = foerderer.hat_umlenk gefahellewinkel = foerderer.gefaelle_winkel gefaelle = foerderer.gefaelle_laenge # Offsets für die Vario Linie für ab 3 bogen, da es in diesem Fall keine bögen hat die sich mit den nachbarn Bögen für andere Vario Förderer verbinden kann winkel_VP_offset_vorne = None winkel_VP_offset_hinten = None # erstellung des Layers falls nicht vorhanden if "VARIO" not in ctx.doc.layers: ctx.doc.layers.add(name="VARIO", color=3) if "6-SP" not in ctx.doc.layers: ctx.doc.layers.add(name="6-SP", color=7) # Vorbereitung der Werte foerder_richtung = foerderer.foerderer_richtung winkel = int(foerderer.winkel) erster_kreisel_höher = False ein_kreisel_höher = False richtung2 = "DEFAULT" rotation = foerderer.drehung upper_hoehe_vario = foerderer.h1 lower_hoehe_vario = foerderer.h0 hoehe_vario = foerderer.hight_zwischen anzahl_seperatoren_oder_scan(ctx.msp, ctx.doc, ctx.lib_doc, foerderer, ctx.config) as_es_methoden.vertausch_der_höhe(foerderer) upper_hoehe_vario = foerderer.h1 lower_hoehe_vario = foerderer.h0 rotation = foerderer.drehung # Hollen der Information der Nachbarn strukturen ob diese Kreisel sind for nachbarn in ctx.strecken_nachbarn: if ctx.teileid == nachbarn.get("Id"): gefaellestrecke_vario = nachbarn break laenge = foerderer.laenge halbe_laenge = laenge / 2 # Ausrechnung der nötigen Offset falls der Vario Förderer ab mit drei grad mit einem anderen Verbunden ist winkel_VP_offset_vorne, winkel_VP_offset_hinten = ( VarioFoerderer.VarioFoerderer.get_offset_of_Vario_line( ctx.doc, ctx.lib_doc, foerderer, gefaellestrecke_vario ) ) # Für spätere berechnung schauen ob der erste Kreis in der Liste höher ist if upper_hoehe_vario == gefaellestrecke_vario.get("Hoehe0"): ein_kreisel_höher = True # Falls der Förderer mit einem Eckrad verbunden ist if ( "Eckrad_x" in gefaellestrecke_vario and "Eckrad_x_1" not in gefaellestrecke_vario ): x0_eckrad = gefaellestrecke_vario.get("Eckrad_x") y0_eckrad = gefaellestrecke_vario.get("Eckrad_y") hoehe_eckrad = gefaellestrecke_vario.get("Eckrad_höhe") if upper_hoehe_vario == hoehe_eckrad: ein_kreisel_höher = True else: ein_kreisel_höher = False mit_horizontal_verbunden = ( VarioFoerderer.VarioFoerderer.horizontale_ausrichtung( foerderer, x0_eckrad, y0_eckrad ) ) blockname = f"Vario_Foerderer_{winkel}_{foerder_richtung}_{laenge}_{hoehe_vario}_rechts_{ein_kreisel_höher}_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}_{mit_horizontal_verbunden}" block_name_links = f"Vario_Foerderer_{winkel}_{foerder_richtung}_{laenge}_{hoehe_vario}_links_{ein_kreisel_höher}_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}_{mit_horizontal_verbunden}" if blockname not in ctx.doc.blocks: block_vario = ctx.doc.blocks.new(blockname, base_point=(0, 0, 0)) dy_true = halbe_laenge * math.cos(0) start = (ctx.x, ctx.y + dy_true, upper_hoehe_vario) ende = (ctx.x, ctx.y - dy_true, lower_hoehe_vario) start, ende = VarioFoerderer.VarioFoerderer.vario_verbuden_am_kreisel( foerderer, block_vario, start, ende, mit_horizontal_verbunden, 1, 1, ein_kreisel_höher, ) VarioFoerderer.VarioFoerderer.vario_erstellung( foerderer, ctx.doc, ctx.lib_doc, ctx.config, block_vario, block_name_links, start, ende, foerder_richtung, winkel_VP_offset_vorne, winkel_VP_offset_hinten, ) # reintuen des förderes in den Modelspace if ctx.merkmale.get("Motorseite") == "links": ctx.msp.add_blockref( block_name_links, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) return elif ctx.merkmale.get("Motorseite") == "rechts": ctx.msp.add_blockref( blockname, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) return # Falls der Förderer mit zwei Eckrads verbunden ist if "Eckrad_x" in gefaellestrecke_vario and "Eckrad_x_1" in gefaellestrecke_vario: blockname = f"Vario_Foerderer_{winkel}_{foerder_richtung}_{laenge}_{hoehe_vario}_rechts_2_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}" block_name_links = f"Vario_Foerderer_{winkel}_{foerder_richtung}_{laenge}_{hoehe_vario}_links_2_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}" if blockname not in ctx.doc.blocks: block_vario = ctx.doc.blocks.new(blockname, base_point=(0, 0, 0)) dy_true = halbe_laenge * math.cos(0) start = (ctx.x, ctx.y + dy_true, upper_hoehe_vario) ende = (ctx.x, ctx.y - dy_true, lower_hoehe_vario) start, ende = VarioFoerderer.VarioFoerderer.vario_verbuden_am_kreisel( foerderer, block_vario, start, ende, None, 2, ) VarioFoerderer.VarioFoerderer.vario_erstellung( foerderer, ctx.doc, ctx.lib_doc, ctx.config, block_vario, block_name_links, start, ende, foerder_richtung, winkel_VP_offset_vorne, winkel_VP_offset_hinten, ) # reintuen des förderes in den Modelspace if ctx.merkmale.get("Motorseite") == "links": ctx.msp.add_blockref( block_name_links, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) return elif ctx.merkmale.get("Motorseite") == "rechts": ctx.msp.add_blockref( blockname, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) return # Aufruf falls nur mit einem Kreisel verbunden if "Drehung0" in gefaellestrecke_vario and "Drehung1" not in gefaellestrecke_vario: # Vorbereitund der Daten des Kreisel halbe_laenge = laenge / 2 zwischen_winkel = float(ctx.merkmale.get("Drehung")) richtung_rad = math.radians(zwischen_winkel) dx = halbe_laenge * math.sin(-1 * richtung_rad) dy = halbe_laenge * math.cos(richtung_rad) drehung0 = gefaellestrecke_vario.get("Drehung0") abstand0 = float(gefaellestrecke_vario.get("abstand0")) * 1000 x0_kreisel = float(gefaellestrecke_vario.get("x0")) y0_kreisel = float(gefaellestrecke_vario.get("y0")) richtung0 = float(gefaellestrecke_vario.get("rotation0")) richtung_rad0 = math.radians(richtung0) mit_horizontal_verbunden = ( VarioFoerderer.VarioFoerderer.horizontale_ausrichtung( foerderer, x0_kreisel, y0_kreisel ) ) am_kreisel, kreseil_verbunden = as_es_methoden.am_kreisel_direct_verbunden( ctx.x, ctx.y, upper_hoehe_vario, lower_hoehe_vario, x0_kreisel, y0_kreisel, richtung_rad0, abstand0, dx, dy, None, None, None, None, ) if am_kreisel == 1: # Erstellung der blockname für wenn die Motorstation rechts und links blockname = f"Vario_Foerderer_{winkel}_{foerder_richtung}_{laenge}_{hoehe_vario}_rechts_{ein_kreisel_höher}_{drehung0}_True_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}_{mit_horizontal_verbunden}" block_name_links = f"Vario_Foerderer_{winkel}_{foerder_richtung}_{laenge}_{hoehe_vario}_links_{ein_kreisel_höher}_{drehung0}_True_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}_{mit_horizontal_verbunden}" # Falls der Block bereits in dem ctx.doc ist platziere diesen einfach if blockname in ctx.doc.blocks: if ctx.merkmale.get("Motorseite") == "links": ctx.msp.add_blockref( block_name_links, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) return elif ctx.merkmale.get("Motorseite") == "rechts": ctx.msp.add_blockref( blockname, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) return # Erstellung des Blocks und diesen in die Modelspace tuen. Die Linke version wird bei der vario erstellung selber am ende gemacht block_vario = ctx.doc.blocks.new(blockname, base_point=(0, 0, 0)) dy_true = halbe_laenge * math.cos(0) start = (ctx.x, ctx.y + dy_true, upper_hoehe_vario) ende = (ctx.x, ctx.y - dy_true, lower_hoehe_vario) # Erstellung einer Gefällestrecke von 500 mm in der Vario rein, wo es verbunden ist start, ende = VarioFoerderer.VarioFoerderer.vario_verbuden_am_kreisel( foerderer, block_vario, start, ende, mit_horizontal_verbunden, kreseil_verbunden, am_kreisel, ein_kreisel_höher, ) # Erstellung des Vario_förderes selber VarioFoerderer.VarioFoerderer.vario_erstellung( foerderer, ctx.doc, ctx.lib_doc, ctx.config, block_vario, block_name_links, start, ende, foerder_richtung, winkel_VP_offset_vorne, winkel_VP_offset_hinten, ) # reintuen des förderes in den Modelspace if ctx.merkmale.get("Motorseite") == "links": ctx.msp.add_blockref( block_name_links, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) return elif ctx.merkmale.get("Motorseite") == "rechts": ctx.msp.add_blockref( blockname, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) return # Abschnitt falls der Vario nur mit einem Kreisel verbunden ist und nicht an dem Kreisel direkt verbunden ist # Erstellung der blockname für wenn die Motorstation rechts und links blockname = f"Vario_Foerderer_{winkel}_{foerder_richtung}_{laenge}_{hoehe_vario}_rechts_{ein_kreisel_höher}_{drehung0}_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}_{mit_horizontal_verbunden}" block_name_links = f"Vario_Foerderer_{winkel}_{foerder_richtung}_{laenge}_{hoehe_vario}_links_{ein_kreisel_höher}_{drehung0}_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}_{mit_horizontal_verbunden}" # Falls der Block bereits in dem ctx.doc ist platziere diesen einfach if blockname in ctx.doc.blocks: if ctx.merkmale.get("Motorseite") == "links": ctx.msp.add_blockref( block_name_links, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) return elif ctx.merkmale.get("Motorseite") == "rechts": ctx.msp.add_blockref( blockname, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) return # Erstellung des Blocks und diesen in die Modelspace tuen. Die Linke version wird bei der vario erstellung selber am ende gemacht block_vario = ctx.doc.blocks.new(blockname, base_point=(0, 0, 0)) dy_true = halbe_laenge * math.cos(0) # Schauen welches as oder es element man wo verbinden muss und bereits in den block tuen, der None wert ist ein Wert der für die Gefällestrecke notwendig ist # Entnehmen von start und end Werte für spätere vario erstellung start, ende = as_es_methoden.erstellung_gefaelle_block_verbunden_an_einen( ctx.msp, ctx.x, ctx.y, ctx.doc, ctx.lib_doc, upper_hoehe_vario, lower_hoehe_vario, hoehe_vario, drehung0, laenge, blockname, ctx.config, None, block_vario, foerder_richtung, ein_kreisel_höher, None, None, None, mit_horizontal_verbunden, ) # Erstellung des Varios selber VarioFoerderer.VarioFoerderer.vario_erstellung( foerderer, ctx.doc, ctx.lib_doc, ctx.config, block_vario, block_name_links, start, ende, foerder_richtung, winkel_VP_offset_vorne, winkel_VP_offset_hinten, ) # reintuen des förderes in den Modelspace if ctx.merkmale.get("Motorseite") == "links": ctx.msp.add_blockref( block_name_links, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) if ctx.merkmale.get("Motorseite") == "rechts": ctx.msp.add_blockref( blockname, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) # Erstellung einer Vario förderes wenn es mit zwei Kreisel verbunden ist elif "Drehung0" in gefaellestrecke_vario and "Drehung1" in gefaellestrecke_vario: # Vorbereitung der Werte für beide Kreisel halbe_laenge = laenge / 2 zwischen_winkel = float(ctx.merkmale.get("Drehung")) richtung_rad = math.radians(zwischen_winkel) dx = halbe_laenge * math.sin(-1 * richtung_rad) dy = halbe_laenge * math.cos(richtung_rad) drehung0 = gefaellestrecke_vario.get("Drehung0") abstand0 = float(gefaellestrecke_vario.get("abstand0")) * 1000 x0_kreisel = float(gefaellestrecke_vario.get("x0")) y0_kreisel = float(gefaellestrecke_vario.get("y0")) richtung0 = float(gefaellestrecke_vario.get("rotation0")) richtung_rad0 = math.radians(richtung0) kreisel_hoehe0 = float(gefaellestrecke_vario.get("Hoehe0")) drehung1 = gefaellestrecke_vario.get("Drehung1") abstand1 = float(gefaellestrecke_vario.get("abstand1")) * 1000 x1_kreisel = float(gefaellestrecke_vario.get("x1")) y1_kreisel = float(gefaellestrecke_vario.get("y1")) richtung1 = float(gefaellestrecke_vario.get("rotation1")) richtung_rad1 = math.radians(richtung1) kreisel_hoehe1 = float(gefaellestrecke_vario.get("Hoehe1")) # Anpassung der Kreisel, damit der Höhere Kreisel immer zuerst ist if kreisel_hoehe0 < kreisel_hoehe1: drehung2 = drehung0 drehung0 = drehung1 drehung1 = drehung2 # Schauen ob der Förderer direkt am Kreisel verbunden ist am_kreisel, kreisel_verbunden = as_es_methoden.am_kreisel_direct_verbunden( ctx.x, ctx.y, upper_hoehe_vario, lower_hoehe_vario, x0_kreisel, y0_kreisel, richtung_rad0, abstand0, dx, dy, x1_kreisel, y1_kreisel, richtung_rad1, abstand1, ) # Falls der Förder mit beiden Kreisel verbunden ist if kreisel_verbunden == 2: # Erstellung der blockname für wenn die Motorstation rechts und links blockname = f"Vario_Foerderer_{winkel}_{foerder_richtung}_{laenge}_{hoehe_vario}_rechts_{kreisel_verbunden}_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}" block_name_links = f"Vario_Foerderer_{winkel}_{foerder_richtung}_{laenge}_{hoehe_vario}_links_{kreisel_verbunden}_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}" # Falls der Block bereits in dem ctx.doc ist platziere diesen einfach if blockname in ctx.doc.blocks: if ctx.merkmale.get("Motorseite") == "links": ctx.msp.add_blockref( block_name_links, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) return elif ctx.merkmale.get("Motorseite") == "rechts": ctx.msp.add_blockref( blockname, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) return # Erstellung des Blocks und diesen in die Modelspace tuen. Die Linke version wird bei der vario erstellung selber am ende gemacht block_vario = ctx.doc.blocks.new(blockname, base_point=(0, 0, 0)) dy_true = halbe_laenge * math.cos(0) start = (ctx.x, ctx.y + dy_true, upper_hoehe_vario) ende = (ctx.x, ctx.y - dy_true, lower_hoehe_vario) start, ende = VarioFoerderer.VarioFoerderer.vario_verbuden_am_kreisel( foerderer, block_vario, start, ende, None, kreisel_verbunden ) # Die Vario erstellung selber VarioFoerderer.VarioFoerderer.vario_erstellung( foerderer, ctx.doc, ctx.lib_doc, ctx.config, block_vario, block_name_links, start, ende, foerder_richtung, winkel_VP_offset_vorne, winkel_VP_offset_hinten, ) # reintuen des förderes in den Modelspace if ctx.merkmale.get("Motorseite") == "links": ctx.msp.add_blockref( block_name_links, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) return elif ctx.merkmale.get("Motorseite") == "rechts": ctx.msp.add_blockref( blockname, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) return # Falls der Förderer nur mit einem Kreisel direkt verbunden ist if am_kreisel != 0: # schauen ob der erste Kreisel höher ist if upper_hoehe_vario == kreisel_hoehe0: erster_kreisel_höher = True else: erster_kreisel_höher = False # Erstellung der blockname für wenn die Motorstation rechts und links blockname = f"Vario_Foerderer_{winkel}_{foerder_richtung}_{laenge}_{hoehe_vario}_rechts_{am_kreisel}_{erster_kreisel_höher}_{drehung0}_{drehung1}_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}" block_name_links = f"Vario_Foerderer_{winkel}_{foerder_richtung}_{laenge}_{hoehe_vario}_links_{am_kreisel}_{erster_kreisel_höher}_{drehung0}_{drehung1}_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}" # Falls der Block bereits in dem ctx.doc ist platziere diesen einfach if blockname in ctx.doc.blocks: if ctx.merkmale.get("Motorseite") == "links": ctx.msp.add_blockref( block_name_links, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) return elif ctx.merkmale.get("Motorseite") == "rechts": ctx.msp.add_blockref( blockname, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) return # Erstellung des Blocks und diesen in die Modelspace tuen. Die Linke version wird bei der vario erstellung selber am ende gemacht block_vario = ctx.doc.blocks.new(blockname, base_point=(0, 0, 0)) dy_true = halbe_laenge * math.cos(0) start = (ctx.x, ctx.y + dy_true, upper_hoehe_vario) ende = (ctx.x, ctx.y - dy_true, lower_hoehe_vario) # schauen ob der Förderer mit welchen Kreisel der Förderer verbunden ist, und dem entsprechend eine Gefällestrecke dort reintuern y1, z1 = VarioFoerderer.VarioFoerderer.vario_verbuden_am_kreisel( foerderer, block_vario, start, ende, None, kreisel_verbunden, am_kreisel, erster_kreisel_höher, ) # Schauen welche es oder as element man braucht man braucht und diese in den block einfügen # Entnehmen von start und end Werte für spätere vario erstellung start, ende = as_es_methoden.gefaellegerade_erstellung( foerderer, ctx.doc, ctx.lib_doc, richtung2, drehung0, drehung1, None, blockname, ctx.config, block_vario, am_kreisel, erster_kreisel_höher, y1, z1, ) # Erstellung der Vario gefälle selber VarioFoerderer.VarioFoerderer.vario_erstellung( foerderer, ctx.doc, ctx.lib_doc, ctx.config, block_vario, block_name_links, start, ende, foerder_richtung, winkel_VP_offset_vorne, winkel_VP_offset_hinten, ) # Reintuen des endblockes in den Modelspace if ctx.merkmale.get("Motorseite") == "links": ctx.msp.add_blockref( block_name_links, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) elif ctx.merkmale.get("Motorseite") == "rechts": ctx.msp.add_blockref( blockname, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) # Falls es nicht mit dem Kreisel direkt verbunden ist else: # Erstellung der blockname für wenn die Motorstation rechts und links blockname = f"Vario_Foerderer_{winkel}_{foerder_richtung}_{laenge}_{hoehe_vario}_rechts_{drehung0}_{drehung1}_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}" block_name_links = f"Vario_Foerderer_{winkel}_{foerder_richtung}_{laenge}_{hoehe_vario}_links_{drehung0}_{drehung1}_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}" # Falls der Block bereits in dem ctx.doc ist platziere diesen einfach if blockname in ctx.doc.blocks: if ctx.merkmale.get("Motorseite") == "links": ctx.msp.add_blockref( block_name_links, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) return elif ctx.merkmale.get("Motorseite") == "rechts": ctx.msp.add_blockref( blockname, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) return # Erstellung des Blocks und diesen in die Modelspace tuen. Die Linke version wird bei der vario erstellung selber am ende gemacht block_vario = ctx.doc.blocks.new(blockname, base_point=(0, 0, 0)) # Schauen welche es oder as element man braucht man braucht und diese in den block einfügen # Entnehmen von start und end Werte für spätere vario erstellung start, ende = as_es_methoden.gefaellegerade_erstellung( foerderer, ctx.doc, ctx.lib_doc, richtung2, drehung0, drehung1, None, blockname, ctx.config, block_vario, ) # Erstellung des Vario selber VarioFoerderer.VarioFoerderer.vario_erstellung( foerderer, ctx.doc, ctx.lib_doc, ctx.config, block_vario, block_name_links, start, ende, foerder_richtung, winkel_VP_offset_vorne, winkel_VP_offset_hinten, ) # Reintuen des endblockes in den Modelspace if ctx.merkmale.get("Motorseite") == "links": ctx.msp.add_blockref( block_name_links, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) elif ctx.merkmale.get("Motorseite") == "rechts": ctx.msp.add_blockref( blockname, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) # Erstellung des Varios falls es nicht mit einem Kreisel verbunden ist else: halbe_laenge = laenge / 2 dy = halbe_laenge * math.cos(0) # Erstellung der blockname für wenn die Motorstation rechts und links blockname = f"Vario_Foerderer_{winkel}_{foerder_richtung}_{laenge}_{hoehe_vario}_rechts_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}" block_name_links = f"Vario_Foerderer_{winkel}_{foerder_richtung}_{laenge}_{hoehe_vario}_links_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}" # Falls der Block bereits in dem ctx.doc ist platziere diesen einfach if blockname in ctx.doc.blocks: if ctx.merkmale.get("Motorseite") == "links": ctx.msp.add_blockref( block_name_links, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) return elif ctx.merkmale.get("Motorseite") == "rechts": ctx.msp.add_blockref( blockname, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) return # Erstellung des Blocks und diesen in die Modelspace tuen. Die Linke version wird bei der vario erstellung selber am ende gemacht block = ctx.doc.blocks.new(blockname, base_point=(0, 0, 0)) # Erstellung von start und ende start = (ctx.x, ctx.y + dy, upper_hoehe_vario) ende = (ctx.x, ctx.y - dy, lower_hoehe_vario) # Erstellung des Förderes selber VarioFoerderer.VarioFoerderer.vario_erstellung( foerderer, ctx.doc, ctx.lib_doc, ctx.config, block, block_name_links, start, ende, foerder_richtung, winkel_VP_offset_vorne, winkel_VP_offset_hinten, ) # Reintuen des endblockes in den Modelspace if ctx.merkmale.get("Motorseite") == "links": ctx.msp.add_blockref( block_name_links, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) if ctx.merkmale.get("Motorseite") == "rechts": ctx.msp.add_blockref( blockname, (ctx.x, ctx.y, hoehe_vario), dxfattribs={"rotation": rotation}, ) def handle_ils_2_0_kurve_angetrieben(ctx): """Erstellt eine Angetriebene Kurve (Förderer Kurve) in der neuen Dxf""" voerder_kurve = Angetriebene_Kurve.Angetriebene_Kurve.from_merkmale( ctx.teileid, ctx.x, ctx.y, ctx.merkmale ) kurvenwinkel = voerder_kurve.winkel h_zwischen = voerder_kurve.hight_zwischen antriebNebenStrecke = voerder_kurve.antrieb kurvenrichtung = voerder_kurve.kurvenrichtung rotation = voerder_kurve.drehung blockname = ( f"Vario_Kurve_{kurvenrichtung}_{kurvenwinkel}°_TEF_{antriebNebenStrecke}" ) block_methoden.import_block(blockname, ctx.lib_doc, ctx.doc) layer, color = block_methoden.get_insert_color_layer(ctx.lib_doc, blockname) ctx.msp.add_blockref( blockname, (ctx.x, ctx.y, h_zwischen), dxfattribs={"rotation": rotation, "layer": layer, "color": color}, ) def handle_ils_2_0_kurve(ctx): """Erstellt eine Kurve (Gefälle Kurve) in der neuen Dxf""" rotation = float(ctx.merkmale.get("Drehung")) h0 = float(ctx.merkmale.get("Höhe Anfang")) * 1000 h1 = float(ctx.merkmale.get("Höhe Ende")) * 1000 hz = (h0 + h1) / 2 kurvenrichtung = ctx.merkmale.get("Kurvenrichtung") kurvenwinkel = int(ctx.merkmale.get("Kurvenwinkel")) blockname = f"Kurve_{kurvenrichtung}_{kurvenwinkel}°_R500_Gefälle" block_methoden.import_block(blockname, ctx.lib_doc, ctx.doc) ctx.msp.add_blockref( blockname, (ctx.x, ctx.y, hz), dxfattribs={"rotation": rotation} ) def handle_bt___beladung(ctx): """Erstellt ein BT Element in der neuen Dxf""" bt_element = Bt_element.Bt_element.from_merkmale( ctx.teileid, ctx.x, ctx.y, ctx.merkmale ) rotation = bt_element.drehung hight = bt_element.hoehe blockname = "AN8" block_methoden.import_block(blockname, ctx.lib_doc, ctx.doc) ctx.msp.add_blockref( blockname, (ctx.x, ctx.y, hight), dxfattribs={"rotation": rotation} ) def handle_bt___entladung(ctx): """Erstellt ein BT Element in der neuen Dxf""" bt_element = Bt_element.Bt_element.from_merkmale( ctx.teileid, ctx.x, ctx.y, ctx.merkmale ) rotation = bt_element.drehung hight = bt_element.hoehe blockname = "AN8" block_methoden.import_block(blockname, ctx.lib_doc, ctx.doc) ctx.msp.add_blockref( blockname, (ctx.x, ctx.y, hight), dxfattribs={"rotation": rotation} ) def handle_omniflo(ctx): """ Für Omniflo Gerade: zeichnet eine Linie (Mitte = Koordinate, Länge und Winkel aus Merkmale). Für alle anderen Omniflo-Typen: Block mit SivasNummer an den Koordinaten. """ # Prüfen, ob es sich um eine Gerade handelt omnisivas = ctx.config.get("Omniflo", "OFgeradesivas") tefsivas = ctx.config.get("Omniflo", "Tefgeradesivas") foerderer = ctx.config.get("Omniflo", "OFfoerderer") omniflo_objekt = Omniflo.Omniflo.from_merkmale( ctx.teileid, ctx.x, ctx.y, ctx.merkmale ) rotation = omniflo_objekt.drehung if ( omniflo_objekt.sivasnummer == omnisivas or omniflo_objekt.sivasnummer == tefsivas ): Omniflo.Omniflo.Omniflo_geraden_erstellung( ctx.msp, ctx.doc, tefsivas, omniflo_objekt ) if omniflo_objekt.sivasnummer == omnisivas: anzahl_seperatoren_oder_scan( ctx.msp, ctx.doc, ctx.lib_doc, omniflo_objekt, ctx.config ) elif omniflo_objekt.sivasnummer == foerderer: Omniflo.Omniflo.omniflo_foerdererstellung( ctx.msp, ctx.doc, ctx.lib_doc, omniflo_objekt ) return # Sonst wie gehabt: Block mit SivasNummer else: if not ctx.lib_doc: print("[WARN] lib_doc nicht verfügbar, Block wird nicht eingefügt.") return blockname = ctx.merkmale.get("SivasNummer") if not blockname: print(f"[WARN] Keine SivasNummer für {ctx.teileid}, überspringe.") return if blockname not in ctx.lib_doc.blocks: print( f"[WARN] Omniflo-Block '{blockname}' nicht in Bibliothek {ctx.lib_doc.filename}. Überspringe {ctx.teileid}." ) return blockname = blockname block_methoden.import_block(blockname, ctx.lib_doc, ctx.doc) layer, color = block_methoden.get_insert_color_layer( ctx.lib_doc, omniflo_objekt.sivasnummer ) ctx.msp.add_blockref( blockname, (ctx.x, ctx.y, omniflo_objekt.hoehe), dxfattribs={"rotation": rotation, "layer": layer, "color": color}, ) def anzahl_seperatoren_oder_scan(msp, doc, lib_doc, klassen_objekt, config): """Importiert alle seperatoren und/oder scanner für das nötige objekt""" omniflo_scanner = config.get("Scanner_Stoper_namen", "Omniflo_scanner") ILS_scanner = config.get("Scanner_Stoper_namen", "Ils_scanner") omniflo_stopper = config.get("Scanner_Stoper_namen", "Omniflo_stopper") ILS_seperator = config.get("Scanner_Stoper_namen", "ILS_seperator") scanner = klassen_objekt.anzahl_scanner separatoren = None stopper = None x = klassen_objekt.x y = klassen_objekt.y hoehe = klassen_objekt.hight_zwischen rotation = klassen_objekt.drehung # Schauen welche Ausrichtung das Objekt hat, damit man die Separtoren unbd Scanner nicht in das Objekt tut if rotation == 0 or rotation == -180: ausrichtung = "V" else: ausrichtung = "H" if ausrichtung == "V": einsatz_fest = [x + 300, y, hoehe] modular = 2 else: einsatz_fest = [x, y - 150, hoehe] modular = 3 if omniflo_scanner not in lib_doc.blocks: block_methoden.import_block(ILS_scanner, lib_doc, doc) block_methoden.import_block(ILS_seperator, lib_doc, doc) scanner_name = ILS_scanner separator_name = ILS_seperator layer_scan, color_scan = block_methoden.get_insert_color_layer( lib_doc, ILS_scanner ) layer_separatioren, color_separatioren = block_methoden.get_insert_color_layer( lib_doc, ILS_seperator ) separatoren = klassen_objekt.anzahl_separatoren else: block_methoden.import_block(omniflo_scanner, lib_doc, doc) block_methoden.import_block(omniflo_stopper, lib_doc, doc) scanner_name = omniflo_scanner stopper_name = omniflo_stopper layer_scan, color_scan = block_methoden.get_insert_color_layer( lib_doc, omniflo_scanner ) layer_stopper, color_stopper = block_methoden.get_insert_color_layer( lib_doc, omniflo_stopper ) stopper = klassen_objekt.anzahl_stopper einsatz_zwischen = [einsatz_fest[0], einsatz_fest[1], einsatz_fest[2]] anzahl = 0 if separatoren != None: while anzahl < separatoren: anzahl = anzahl + 1 msp.add_blockref( separator_name, einsatz_zwischen, dxfattribs={"layer": layer_separatioren, "color": color_separatioren}, ) if anzahl % modular == 0: einsatz_fest[1] = einsatz_fest[1] - 150 einsatz_zwischen = einsatz_fest.copy() else: einsatz_zwischen[0] = einsatz_zwischen[0] + 300 if anzahl % modular != 0: einsatz_fest[1] = einsatz_fest[1] - 150 einsatz_zwischen = einsatz_fest.copy() anzahl = 0 else: while anzahl < stopper: anzahl = anzahl + 1 msp.add_blockref( stopper_name, einsatz_zwischen, dxfattribs={"layer": layer_stopper, "color": color_stopper}, ) if anzahl % modular == 0: einsatz_fest[1] = einsatz_fest[1] - 250 einsatz_zwischen = einsatz_fest.copy() else: einsatz_zwischen[0] = einsatz_zwischen[0] + 200 if anzahl % modular != 0: einsatz_fest[1] = einsatz_fest[1] - 250 einsatz_zwischen = einsatz_fest.copy() anzahl = 0 while anzahl < scanner: anzahl = anzahl + 1 msp.add_blockref( scanner_name, einsatz_zwischen, dxfattribs={"layer": layer_scan, "color": color_scan}, ) if anzahl % modular == 0: einsatz_fest[1] = einsatz_fest[1] - 150 einsatz_zwischen = einsatz_fest.copy() else: einsatz_zwischen[0] = einsatz_zwischen[0] + 300 def get_libfile_cfg(teileart, cfg_path): """Liest den Bibliotheksdateinamen für eine TeileArt aus der allgemein.cfg.""" parser = configparser.ConfigParser() with open(cfg_path, encoding="utf-8") as f: parser.read_file(f) # Teileart kann z.B. "ILS 2.0 Kreisel" sein, wir nehmen den ersten Teil vor erstem Leerzeichen oder Punkt # oder suchen iterativ nach Sektionen, die im Teileart-Namen vorkommen for section in parser.sections(): if section in teileart: return parser.get(section, "libfile", fallback=None) return None # --------------------------------------------------------- Hauptfunktion def main( csv_path: Path, lib_path: Path, cfg_path: Path, allgemein_cfg_path: Path, output_path: Path, output_path_json: Path, verbose=False, logger=None, ): data_dir = check_environment_var("PROJECT_DATA") # Bibliothek nur laden, wenn Datei existiert check_dxflibrary_path(lib_path, verbose, logger) parser_cfg_path = configparser.ConfigParser() try: with open(cfg_path, encoding="utf-8") as f: parser_cfg_path.read_file(f) except Exception as e: msg = f"Fehler beim Lesen der Config-Datei {cfg_path}: {e}" # Neue Ziel­zeichnung (DXF R2018) config = parser_cfg_path parser_allgemein_path = configparser.ConfigParser() try: with open(allgemein_cfg_path, encoding="utf-8") as f: parser_allgemein_path.read_file(f) except Exception as e: msg = f"Fehler beim Lesen der Config-Datei {cfg_path}: {e}" # Neue Ziel­zeichnung (DXF R2018) config_allgemein = parser_allgemein_path doc = ezdxf.new(dxfversion="R2018", setup=True) doc.units = units.M doc.header["$INSUNITS"] = 4 # Millimeter msp = doc.modelspace() blocklib_dir = data_dir / "block_libraries" lib_docs = dict() # gibt zu jeder ShapeId einer Gefällestrecke zurück, ob sich der jeweilige Kreisel im UZ oder GUZ dreht # rot_of_gf["shape_3ae53a7b-efb8-f66b-eadc-20b99f949ef1"] = ('UZ', 'GUZ') strecken_nachbarn = arbeiten_mit_csv.get_nachbar_information(csv_path) # Verarbeitung der Blöcke with csv_path.open(newline="", encoding="utf-8") as fh: reader = csv.DictReader(fh, delimiter=";") for row in reader: bezeichner = row["Bezeichnung"].strip() teileart = row["TeileArt"].strip() teileid = row["TeileId"].strip() planquadrat = row["Planquadrat"] merkmale = arbeiten_mit_csv.parse_merkmale(row.get("Merkmale", "")) merkmale["bezeichner"] = bezeichner try: x, y = arbeiten_mit_csv.extract_coords(planquadrat) except Exception as e: msg = f"[WARN] {teileid}: {e}" if logger: logger.warning(msg) else: print(msg) continue # Bibliotheksdatei bestimmen libfile = get_libfile_cfg(teileart, allgemein_cfg_path) if libfile: lib_path = blocklib_dir / libfile else: lib_path = default_lib_path # Bibliothek laden (mit Cache) lib_doc = None if lib_path in lib_docs: lib_doc = lib_docs[lib_path] elif lib_path.exists(): try: lib_doc = ezdxf.readfile(lib_path) lib_docs[lib_path] = lib_doc if verbose: print(f"[INFO] Bibliothek geladen: {lib_path}") except Exception as e: print(f"[WARN] Fehler beim Lesen der Bibliothek '{lib_path}': {e}") else: print( f"[INFO] Keine Bibliothek gefunden unter {lib_path}. Komplexe Formen werden übersprungen." ) # Funktions-Dispatch: handle_ (mit _ statt Leerzeichen und Punkten, alles klein) func_name = f"handle_{arbeiten_mit_csv.normalize_func_name(teileart)}" handler = globals().get(func_name) symbols = arbeiten_mit_csv.get_shape_cfg(teileart, cfg_path, logger=logger) # Mapping für Omniflo-Typen if func_name.startswith("handle_omniflo") or func_name.startswith( "handle_tef" ): handler = globals().get("handle_omniflo") if func_name.startswith("handle_ils_2_0_kreisel"): handler = globals().get("handle_ils_2_0_kreisel") if handler: # Erstelle HandlerContext-Objekt ctx = HandlerContext( msp=msp, teileid=teileid, merkmale=merkmale, x=x, y=y, doc=doc, lib_doc=lib_doc, verbose=verbose, symbols=symbols, strecken_nachbarn=strecken_nachbarn, config=config, config_allgemein=config_allgemein, ) handler(ctx) else: msg = f"[WARN] Keine Routine für TeileArt '{teileart}'. Überspringe '{teileid}'." if logger: logger.warning(msg) else: print(msg) doc.saveas(output_path) if logger: logger.info(f"[DONE] DXF gespeichert unter: {output_path}") else: print(f"[DONE] DXF gespeichert unter: {output_path}") def check_dxflibrary_path(lib_path, verbose, logger): lib_doc = None if lib_path.exists(): try: lib_doc = ezdxf.readfile(lib_path) if verbose: ( logger.info(f"[INFO] Bibliothek geladen: {lib_path}") if logger else print(f"[INFO] Bibliothek geladen: {lib_path}") ) except Exception as e: msg = f"Fehler beim Lesen der Bibliothek '{lib_path}': {e}" if logger: logger.error(msg) else: print(msg) sys.exit(1) else: msg = f"[INFO] Keine Bibliothek gefunden unter {lib_path}." if logger: logger.error(msg) else: print(msg) sys.exit(1) if __name__ == "__main__": parser = argparse.ArgumentParser( description="Plaziert Anlagenkomponenten aus RuleDesigner CSV." ) parser.add_argument( "-f", "--file", required=True, help="CSV-Datei (Name oder Pfad)", metavar="input.csv", ) parser.add_argument( "-c", "--config", help="CFG mit einfachen Formen", metavar="shapes.cfg" ) parser.add_argument( "-l", "--lib", help="DXF-Bibliothek mit Blöcken", metavar="bibliothek.dxf" ) parser.add_argument( "-o", "--output", help="Ziel-DXF (Standard: PROJECT_WORK/anlage.dxf)", metavar="anlage.dxf", ) parser.add_argument( "-v", "--verbose", action="store_true", help="mehr Ausgaben anzeigen" ) args = parser.parse_args() # Verzeichnisse aus Umgebungs­variablen log_dir = check_environment_var("PROJECT_LOG") data_dir = check_environment_var("PROJECT_DATA") work_dir = check_environment_var("PROJECT_WORK") config_dir = check_environment_var("PROJECT_CFG") logger = setup_logger(log_dir, name="plant2dxf") logger.info("=== plant2dxf Verarbeitung gestartet ===") # CSV‑Pfad: nur Dateiname → im WORK‑Ordner suchen if os.sep not in args.file and "/" not in args.file: csv_path = work_dir / args.file else: csv_path = Path(args.file) cfg_path = Path(args.config) if args.config else config_dir / "shapes.cfg" allgemein_cfg_path = config_dir / "allgemein.cfg" default_lib_path = Path(args.lib) if args.lib else data_dir / "blocks.dxf" output_path = ( Path(args.output) if args.output else (work_dir / f"{csv_path.stem}.dxf") ) output_path_json = ( Path(args.output) if args.output else (work_dir / f"{csv_path.stem}.json") ) main( csv_path, default_lib_path, cfg_path, allgemein_cfg_path, output_path, output_path_json, verbose=args.verbose, logger=logger, ) logger.info("=== plant2dxf Verarbeitung abgeschlossen ===")