Files
plant2dxf/lib/plant2dxf.py
T

1279 lines
70 KiB
Python
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
placeblocks.py
Erzeugt DXF-Elemente aus einer RuleDesigner-CSV.
"""
import os
import sys
import csv
import json
import re
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 Elemente import Kreisel, VarioFoerderer,Gefaehllestrecke,Angetriebene_Kurve,Bt_element,Omniflo, Eckrad
import as_es_methoden
import block_methoden
# --------------------------------------------------------- CFG-Leser für shapes.cfg
def get_shape_cfg(teileart, cfg_path, logger=None):
parser = configparser.ConfigParser()
try:
with open(cfg_path, encoding='utf-8') as f:
parser.read_file(f)
except Exception as e:
msg = f"Fehler beim Lesen der Config-Datei {cfg_path}: {e}"
if logger:
logger.error(msg)
else:
print(msg)
return []
section = teileart
if section not in parser:
return []
# Blöcke
items = parser.get(section, "items", fallback="").replace('"', '').split(",")
blocks = [item.strip() for item in items if item.strip()]
symbols = []
for i, name in enumerate(blocks):
# Offset
offset_key = f"offset_symb{i+1}"
offset_str = parser.get(section, offset_key, fallback="0,0")
try:
ox, oy = [float(x) for x in offset_str.split(",")]
except Exception:
ox, oy = 0.0, 0.0
# Rotation
rot_key = f"rot_symb{i+1}"
rot_str = parser.get(section, rot_key, fallback="0.0")
try:
rot = float(rot_str)
except Exception:
rot = 0.0
symbols.append({
"name": name,
"offset": (ox, oy),
"rotation": rot
})
return symbols
# --------------------------------------------------------- Konstante Parameter
ATTR_TAG = "TeileId" # Attributtag im Block
RADIUS = 400 # Radius der Kreiselkreise (mm)
# --------------------------------------------------------- Hilfsfunktionen
def extract_coords(planquadrat: str) -> tuple[float, float]:
"""Extrahiert X/Y Koordinaten aus PlanquadratString."""
m = re.search(r"X:(\d+[\.,]?\d*)\s+Y:(\d+[\.,]?\d*)", planquadrat)
if not m:
raise ValueError(f"Koordinaten nicht gefunden in: '{planquadrat}'")
x, y = m.groups()
return float(x.replace(",", ".")), float(y.replace(",", "."))
def parse_merkmale(merkmale_str: str) -> dict:
"""Parst Merkmale-JSON-String in dict; bei Fehler → leeres Dict."""
try:
return json.loads(merkmale_str)
except json.JSONDecodeError:
return {}
def handle_ils_2_0_kreisel(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols,strecken_nachbarn,config,config_allgemein):
"""Erstellt ein Kreisel in der neuen Dxf"""
kreisel = Kreisel.Kreisel.from_merkmale(teileid, x, y, 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,lib_doc,doc)
block_methoden.import_block(block_separatoren,lib_doc,doc)
i = 0
while i < kreisel.anzahl_scanner:
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:
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(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, lib_doc, doc)
blockref_layer, color = block_methoden.get_insert_color_layer(lib_doc, blockname)
bref = msp.add_blockref(blockname, pos, dxfattribs={"layer" : blockref_layer})
bref.add_auto_attribs({ATTR_TAG: teileid})
if verbose:
print(f"[INFO] Block '{blockname}' (Kreisel) → {teileid} "
f"({pos[0]:.1f}, {pos[1]:.1f}), rot={rotation}")
# Linien zeichnen
block_methoden.import_block("Pinbereich",lib_doc,doc)
Kreisel.Kreisel.draw_kreisel_lines(msp, pos1, pos2, kreisel)
Kreisel.Kreisel.draw_kreisel_drehrichtung_markierung(msp, pos1, pos2, kreisel, lib_doc, doc, verbose)
def handle_ils_2_0_eckrad(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols, strecken_nachbarn,config,config_allgemein):
"""Erstellt ein Eckrad in der neuen Dxf"""
block_methoden.import_block("AN8",lib_doc,doc)
block_methoden.import_block("Richtungspfeil",lib_doc,doc)
eckrad_rechts = "eckrad_UZS"
eckrad_links = "eckrad_GUZS"
hight = float(merkmale.get("Höhe in m")) * 1000
# Erstellung der Richtungung Blöcke der Eckrads
if eckrad_rechts not in doc.blocks:
block_rechts = doc.blocks.new(name= eckrad_rechts,base_point=(0,0,0))
block_links = doc.blocks.new(name= eckrad_links,base_point=(0,0,0))
block_rechts.add_blockref("AN8",(0,0,0))
block_links.add_blockref("AN8",(0,0,0))
block_rechts.add_blockref("Richtungspfeil",(0+200,0+ RADIUS,0))
block_rechts.add_blockref("Richtungspfeil",(0-200,0- RADIUS,0),dxfattribs={"rotation": 180})
block_links.add_blockref("Richtungspfeil",(0+200,0- RADIUS,0))
block_links.add_blockref("Richtungspfeil",(0-200,0+ RADIUS,0),dxfattribs={"rotation": 180})
if merkmale.get("Drehrichtung") == "UZS":
msp.add_blockref(eckrad_rechts,(x,y,hight))
elif merkmale.get("Drehrichtung") == "GUZS":
msp.add_blockref(eckrad_links,(x,y,hight))
else:
msp.add_blockref("AN8",(x,y,hight))
def handle_ils_2_0_gefaellestrecke(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols, strecken_nachbarn,config,config_allgemein):
"""Erstellt eine Gefällestrecke in der neuen Dxf"""
#Vorbereitung der attributen
gefaelle_objekt = Gefaehllestrecke.Gefaellestrecke.from_merkmale(teileid,x,y,merkmale)
asoffset = float(config.get("ILS 2.0 Gefällestrecke", "asoffset"))
esoffset = float(config.get("ILS 2.0 Gefällestrecke", "esoffset"))
upper_hoehe_gefaehlle= gefaelle_objekt.h1
lower_hoehe_gefaehlle = gefaelle_objekt.h0
hoehe_gefaehlle = 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 = x +dx, y + dy,upper_hoehe_gefaehlle
if "6-SP" not in doc.layers:
doc.layers.add(name="6-SP", color=7)
gefaelle_layer = "6-SP"
verbunden_am_einen = False
richtung2 ="DEFAULT"
unterschiedlich = False
anzahl_seperatoren_oder_scan(msp, x, y, doc, lib_doc, gefaelle_objekt, hoehe_gefaehlle, rotation)
for nachbarn in strecken_nachbarn:
if 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
if upper_hoehe_gefaehlle < lower_hoehe_gefaehlle:
hoehe2 = upper_hoehe_gefaehlle
upper_hoehe_gefaehlle = lower_hoehe_gefaehlle
gefaelle_objekt.h1 = upper_hoehe_gefaehlle
lower_hoehe_gefaehlle = hoehe2
gefaelle_objekt.h0 = lower_hoehe_gefaehlle
rotation = rotation -180
gefaelle_objekt.drehung = rotation
# Übrerprüfung ob die Gefällestrecke einen Motor oder Umlenkstation braucht, wenn es mit einer angetriebenen Kurve verbunden ist
block_Vario_Umlenkstation_500mm, block_Vario_Motorstation_500mm, blockname_motor_links, blockname_umlenk_links = block_methoden.rotatate_and_left_motor_umlenk(doc, lib_doc,config)
hat_zusatz = Gefaehllestrecke.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(x, y, upper_hoehe_gefaehlle, lower_hoehe_gefaehlle, 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:
dx = halbe_laenge *math.sin(winkel * -1)
dy = halbe_laenge * math.cos(winkel)
start = x +dx, y + dy,upper_hoehe_gefaehlle
ende = x -dx, y - dy,lower_hoehe_gefaehlle
line =msp.add_line(start,ende)
line.dxf.layer = "6-SP"
return
#Bearbeitung der Gefällestrecke die direkt am Kreisel hängt und eine Motor- Umlenkstation besitzt
else:
dy = halbe_laenge * math.cos(0)
start = [x , y + dy ,upper_hoehe_gefaehlle]
ende = [x , y - dy ,lower_hoehe_gefaehlle]
blockname = f"Ils_2.0_Gefaellestrecke_{laenge}_{hoehe_gefaehlle}_{hat_umlenk_0}_{hat_motor_0}_{tefkurve_0}_{umlenk_gerade}_{motor_gerade}"
if blockname not in doc.blocks:
block = doc.blocks.new(name=blockname,base_point= (0,0,0))
dy = halbe_laenge * math.cos(0)
start = [x , y + dy ,upper_hoehe_gefaehlle]
ende = [x , y - dy ,lower_hoehe_gefaehlle]
start, ende = Gefaehllestrecke.Gefaellestrecke.ein_motor_oder_eine_umlenk(x, y,start,ende, doc, lib_doc, hoehe_gefaehlle, 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(-x,-y,-hoehe_gefaehlle)
block.add_entity(line)
msp.add_blockref(blockname,(x,y,hoehe_gefaehlle),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_gefaehlle == 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_gefaehlle}_{verbunden_am_einen}_{hight}"
else:
blockname = f"Ils_2.0_Gefaellestrecke_{laenge}_{drehung0}_{hoehe_gefaehlle}_{verbunden_am_einen}_{hight}_{hat_umlenk_0}_{hat_motor_0}_{tefkurve_0}_{umlenk_gerade}_{motor_gerade}"
if blockname in doc.blocks:
bref =msp.add_blockref(blockname,(x,y,hoehe_gefaehlle),dxfattribs={"rotation": rotation,"layer": gefaelle_layer})
a =bref.add_attrib(
tag= "NAME",
text= merkmale.get("bezeichner"),
insert = (x,y)
)
a.is_invisible = True
return
if laenge > asoffset or laenge > esoffset:
block = doc.blocks.new(name=blockname,base_point= (0,0,0))
else:
block = None
dy = halbe_laenge * math.cos(0)
start = [x , y + dy ,upper_hoehe_gefaehlle]
ende = [x , y - dy ,lower_hoehe_gefaehlle]
start, ende = Gefaehllestrecke.Gefaellestrecke.ein_motor_oder_eine_umlenk(x, y, start,ende,doc, lib_doc, hoehe_gefaehlle, 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 x> x0_kreisel:
as_es_rotation= -90
else:
as_es_rotation= -270
else:
if y> y0_kreisel:
as_es_rotation= 0
else:
as_es_rotation= -180
only_es_or_as = as_es_methoden.erstellung_gefaelle_block_verbunenden_am_einen(msp,x, y, doc, lib_doc, upper_hoehe_gefaehlle, lower_hoehe_gefaehlle, hoehe_gefaehlle, drehung0, laenge, blockname,config,hight,None,None,None,block,start,ende,None,as_es_rotation)
if only_es_or_as == False:
bref =msp.add_blockref(blockname,(x,y,hoehe_gefaehlle),dxfattribs={"rotation": rotation,"layer": gefaelle_layer})
a =bref.add_attrib(
tag= "NAME",
text= merkmale.get("bezeichner"),
insert = (x,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(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(x, y, upper_hoehe_gefaehlle, lower_hoehe_gefaehlle, 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:
start = x +dx, y + dy,upper_hoehe_gefaehlle
ende = x -dx, y - dy,lower_hoehe_gefaehlle
line = msp.add_line(start,ende)
line.dxf.layer = "6-SP"
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(x, y, upper_hoehe_gefaehlle, lower_hoehe_gefaehlle, 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"
if richtung2 == "DEFAULT":
if richtung0 == "Vertikal":
if x0_kreisel < x1_kreisel:
position = hight_position + "_links"
else:
position = hight_position + "_rechts"
else:
if y0_kreisel > y1_kreisel:
position = hight_position + "_higher"
else:
position = hight_position + "_lower"
if richtung0 == "Vertikal":
if position == "lower_rechts" or position == "higher_links":
gefaelle = "links"
else:
gefaelle = "rechts"
elif richtung0 == "Horizontal":
if position == "lower_lower" or position == "higher_higher":
gefaelle = "oben"
else:
gefaelle = "unten"
# vertausch der drehung und der höhe für die namens gebung des blockes
if (position == "higher_rechts" or position == "lower_rechts" or position=="higher_lower" or position== "lower_lower") and drehung0 != drehung1 and am_kreisel == 0:
drehung_2 = drehung0
drehung0 = drehung1
drehung1= drehung_2
if hight_position == "higher":
hight_position = "lower"
else:
hight_position = "higher"
# austausch der werte damit immer davon ausgehen dass der 1 kreisel in unserer Liste am Kreisel verbuden ist
if kreisel_verbunden == 1 and am_kreisel ==2:
am_kreisel == 1
drehung_2 = drehung0
drehung0 = drehung1
drehung1= drehung_2
if hight_position == "higher":
hight_position = "lower"
else:
hight_position = "higher"
else:
if richtung2 == "Vertikal":
if x0_kreisel < x1_kreisel:
position = hight_position + "_links"
else:
position = hight_position + "_rechts"
else:
if y0_kreisel > y1_kreisel:
position = hight_position + "_higher"
else:
position = hight_position + "_lower"
if richtung2 == "Vertikal":
if position == "lower_rechts" or position == "higher_links":
gefaelle = "links"
else:
gefaelle = "rechts"
elif richtung2 == "Horizontal":
if position == "lower_lower" or position == "higher_higher":
gefaelle = "oben"
else:
gefaelle = "unten"
# austausch der werte damit immer davon ausgehen dass der 1 kreisel in unserer Liste am Kreisel verbuden ist
if am_kreisel == 2:
am_kreisel = 1
drehung_2 = drehung0
drehung0 = drehung1
drehung1= drehung_2
if hight_position == "higher":
hight_position = "lower"
else:
hight_position = "higher"
# Erstellung der Rotation
if gefaelle == "oben":
rotation = 0
elif gefaelle == "unten" :
rotation = 180
elif gefaelle == "links" :
rotation = 90
elif gefaelle == "rechts" :
rotation = 270
#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_gefaehlle}_{drehung0}_{drehung1}_{hight_position}_{verbunden_am_einen}"
else:
blockname = f"Ils_2.0_Gefaellestrecke_{laenge}_{hoehe_gefaehlle}_{drehung0}_{drehung1}_{hight_position}_{unterschiedlich}_{richtung2}_{verbunden_am_einen}"
as_es_methoden.gefaellegerade_erstellung(x, y, doc, lib_doc, upper_hoehe_gefaehlle, lower_hoehe_gefaehlle, hoehe_gefaehlle,richtung2,drehung0, drehung1, laenge, hight_position,blockname,config)
bref =msp.add_blockref(blockname,(x,y,hoehe_gefaehlle),dxfattribs={"rotation": rotation, "layer": gefaelle_layer})
a = bref.add_attrib(
tag= "NAME",
text= merkmale.get("bezeichner"),
insert = (x,y)
)
a.is_invisible = True
#falls eine gefällestrecke nicht mit einem kreisel verbunden ist
else:
rotation= float(merkmale.get("Drehung"))
if upper_hoehe_gefaehlle < lower_hoehe_gefaehlle:
hoehe2 = upper_hoehe_gefaehlle
upper_hoehe_gefaehlle = lower_hoehe_gefaehlle
gefaelle_objekt.h1 = upper_hoehe_gefaehlle
lower_hoehe_gefaehlle = hoehe2
gefaelle_objekt.h0 = lower_hoehe_gefaehlle
rotation = rotation -180
gefaelle_objekt.drehung = rotation
# 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(doc, lib_doc,config)
hat_zusatz = Gefaehllestrecke.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_gefaehlle}_{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 == False or hat_umlenk_0 == False or hat_motor_1 == False or hat_umlenk_1 == False:
dx = halbe_laenge *math.sin(winkel * -1)
dy = halbe_laenge * math.cos(winkel)
start = [x , y + dy ,upper_hoehe_gefaehlle]
ende = [x , y - dy ,lower_hoehe_gefaehlle]
a= msp.add_line(start,ende)
a.dxf.layer = "6-SP"
return
# Behandlung falls es mit einer odr zwei Vario kurve verbunden ist
if blockname not in doc.blocks:
block = doc.blocks.new(name=blockname,base_point = (0,0,0))
dy = halbe_laenge * math.cos(0)
start = [x , y + dy ,upper_hoehe_gefaehlle]
ende = [x , y - dy ,lower_hoehe_gefaehlle]
start, ende = Gefaehllestrecke.Gefaellestrecke.ein_motor_oder_eine_umlenk(x, y,start,ende, doc, lib_doc, hoehe_gefaehlle, 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 = Gefaehllestrecke.Gefaellestrecke.ein_motor_oder_eine_umlenk(x, y,start,ende, doc, lib_doc, hoehe_gefaehlle, 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(-x,-y,-hoehe_gefaehlle)
block.add_entity(line)
msp.add_blockref(blockname,(x,y,hoehe_gefaehlle),dxfattribs={"rotation": rotation,"layer": gefaelle_layer})
def anzahl_seperatoren_oder_scan(msp, x, y, doc, lib_doc, klassen_objekt, hoehe, rotation):
"""Importiert alle seperatoren und/oder scanner für das nötige objekt"""
separatoren = klassen_objekt.anzahl_separatoren
scanner = klassen_objekt.anzahl_scanner
# 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
block_scanner = "SCAN"
block_separatoren = "S-LP"
block_methoden.import_block(block_scanner,lib_doc,doc)
block_methoden.import_block(block_separatoren,lib_doc,doc)
layer_scan, color_scan = block_methoden.get_insert_color_layer(lib_doc, block_scanner)
layer_separatioren, color_separatioren = block_methoden.get_insert_color_layer(lib_doc, block_separatoren)
einsatz_zwischen =[ einsatz_fest[0],einsatz_fest[1],einsatz_fest[2]]
anzahl =0
while anzahl < separatoren:
anzahl = anzahl + 1
msp.add_blockref(block_separatoren,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
while anzahl < scanner:
anzahl = anzahl + 1
msp.add_blockref(block_scanner,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 handle_ils_2_0_variofoerderer(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols, strecken_nachbarn,config,config_allgemein):
"""Erstellt ein Vario Förderer in der neuen Dxf"""
foerderer = VarioFoerderer.VarioFoerderer.from_merkmale(teileid,x,y,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 doc.layers:
doc.layers.add(name="VARIO", color=3)
if "6-SP" not in doc.layers:
doc.layers.add(name="6-SP", color=7)
# Vorbereitung der Werte
voerder_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(msp, x, y, doc, lib_doc, foerderer, hoehe_vario, rotation)
# Umstellung der Höhen falls nötig für die Konsistenz der spätere Erstellung, ist nur notwendig für ab Vario Förderer
if upper_hoehe_vario< lower_hoehe_vario:
hight = upper_hoehe_vario
upper_hoehe_vario = lower_hoehe_vario
foerderer.h1 = upper_hoehe_vario
lower_hoehe_vario = hight
foerderer.h0 = lower_hoehe_vario
# Korrektur der rotation mit der Umstellung der Höhe
rotation = rotation -180
foerderer.drehung = rotation
# Hollen der Information der Nachbarn strukturen ob diese Kreisel sind
for nachbarn in strecken_nachbarn:
if 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(doc, 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
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(x, y, voerder_richtung, rotation, x0_eckrad, y0_eckrad)
blockname = (f"Vario_Foerderer_{winkel}_{voerder_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}_{voerder_richtung}_{laenge}_{hoehe_vario}_links_{ein_kreisel_höher}_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}_{mit_horizontal_verbunden}")
if blockname not in doc.blocks:
block_vario = doc.blocks.new(blockname, base_point=(0,0,0))
dy_true = halbe_laenge * math.cos (0)
start = (x, y + dy_true,upper_hoehe_vario)
ende = (x,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, doc, lib_doc, config, block_vario,block_name_links, start, ende,voerder_richtung ,winkel_VP_offset_vorne,winkel_VP_offset_hinten)
# reintuen des förderes in den Modelspace
if merkmale.get("Motorseite")== "links":
msp.add_blockref(block_name_links,(x,y,hoehe_vario),dxfattribs={"rotation": rotation})
return
elif merkmale.get("Motorseite")== "rechts":
msp.add_blockref(blockname,(x,y,hoehe_vario),dxfattribs={"rotation": rotation})
return
if "Eckrad_x" in gefaellestrecke_vario and "Eckrad_x_1" in gefaellestrecke_vario:
blockname = (f"Vario_Foerderer_{winkel}_{voerder_richtung}_{laenge}_{hoehe_vario}_rechts_2_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}")
block_name_links = (f"Vario_Foerderer_{winkel}_{voerder_richtung}_{laenge}_{hoehe_vario}_links_2_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}")
if blockname not in doc.blocks:
block_vario = doc.blocks.new(blockname, base_point=(0,0,0))
dy_true = halbe_laenge * math.cos (0)
start = (x, y + dy_true,upper_hoehe_vario)
ende = (x,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, doc, lib_doc, config, block_vario,block_name_links, start, ende,voerder_richtung ,winkel_VP_offset_vorne,winkel_VP_offset_hinten)
# reintuen des förderes in den Modelspace
if merkmale.get("Motorseite")== "links":
msp.add_blockref(block_name_links,(x,y,hoehe_vario),dxfattribs={"rotation": rotation})
return
elif merkmale.get("Motorseite")== "rechts":
msp.add_blockref(blockname,(x,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(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)
# Herausfinden ob der Förderere direkt mit dem Kreisel verbunden ist, die Werte für den Zweiten Kreisel wird auf None gesetzt weil diese nicht existieren
# None als string für späteren vergleich
mit_horizontal_verbunden = VarioFoerderer.VarioFoerderer.horizontale_ausrichtung(x, y, voerder_richtung, rotation, x0_kreisel, y0_kreisel)
am_kreisel,kreseil_verbunden =as_es_methoden.am_kreisel_direct_verbunden(x, 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}_{voerder_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}_{voerder_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 doc ist platziere diesen einfach
if blockname in doc.blocks:
if merkmale.get("Motorseite")== "links":
msp.add_blockref(block_name_links,(x,y,hoehe_vario),dxfattribs={"rotation": rotation})
return
elif merkmale.get("Motorseite")== "rechts":
msp.add_blockref(blockname,(x,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 = doc.blocks.new(blockname, base_point=(0,0,0))
dy_true = halbe_laenge * math.cos (0)
start = (x, y + dy_true,upper_hoehe_vario)
ende = (x,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, doc, lib_doc, config, block_vario,block_name_links, start, ende,voerder_richtung ,winkel_VP_offset_vorne,winkel_VP_offset_hinten)
# reintuen des förderes in den Modelspace
if merkmale.get("Motorseite")== "links":
msp.add_blockref(block_name_links,(x,y,hoehe_vario),dxfattribs={"rotation": rotation})
return
elif merkmale.get("Motorseite")== "rechts":
msp.add_blockref(blockname,(x,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}_{voerder_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}_{voerder_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 doc ist platziere diesen einfach
if blockname in doc.blocks:
if merkmale.get("Motorseite")== "links":
msp.add_blockref(block_name_links,(x,y,hoehe_vario),dxfattribs={"rotation": rotation})
return
elif merkmale.get("Motorseite")== "rechts":
msp.add_blockref(blockname,(x,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 = 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_verbunenden_am_einen(msp,x, y, doc, lib_doc, upper_hoehe_vario, lower_hoehe_vario, hoehe_vario, drehung0, laenge, blockname,config,None ,block_vario, voerder_richtung, ein_kreisel_höher,None,None,None,mit_horizontal_verbunden)
# Erstellung des Varios selber
VarioFoerderer.VarioFoerderer.vario_erstellung(foerderer, doc, lib_doc, config, block_vario,block_name_links, start, ende,voerder_richtung ,winkel_VP_offset_vorne,winkel_VP_offset_hinten)
# reintuen des förderes in den Modelspace
if merkmale.get("Motorseite")== "links":
msp.add_blockref(block_name_links,(x,y,hoehe_vario),dxfattribs={"rotation": rotation})
if merkmale.get("Motorseite")== "rechts":
msp.add_blockref(blockname,(x,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(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(x, 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}_{voerder_richtung}_{laenge}_{hoehe_vario}_rechts_{kreisel_verbunden}_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}")
block_name_links = (f"Vario_Foerderer_{winkel}_{voerder_richtung}_{laenge}_{hoehe_vario}_links_{kreisel_verbunden}_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}")
# Falls der Block bereits in dem doc ist platziere diesen einfach
if blockname in doc.blocks:
if merkmale.get("Motorseite")== "links":
msp.add_blockref(block_name_links,(x,y,hoehe_vario),dxfattribs={"rotation": rotation})
return
elif merkmale.get("Motorseite")== "rechts":
msp.add_blockref(blockname,(x,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 = doc.blocks.new(blockname, base_point=(0,0,0))
dy_true = halbe_laenge * math.cos (0)
start = (x, y + dy_true,upper_hoehe_vario)
ende = (x,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,doc, lib_doc, config, block_vario,block_name_links, start, ende,voerder_richtung ,winkel_VP_offset_vorne,winkel_VP_offset_hinten)
# reintuen des förderes in den Modelspace
if merkmale.get("Motorseite")== "links":
msp.add_blockref(block_name_links,(x,y,hoehe_vario),dxfattribs={"rotation": rotation})
return
elif merkmale.get("Motorseite")== "rechts":
msp.add_blockref(blockname,(x,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}_{voerder_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}_{voerder_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 doc ist platziere diesen einfach
if blockname in doc.blocks:
if merkmale.get("Motorseite")== "links":
msp.add_blockref(block_name_links,(x,y,hoehe_vario),dxfattribs={"rotation": rotation})
return
elif merkmale.get("Motorseite")== "rechts":
msp.add_blockref(blockname,(x,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 = doc.blocks.new(blockname, base_point=(0,0,0))
dy_true = halbe_laenge * math.cos(0)
start = (x, y + dy_true,upper_hoehe_vario)
ende = (x,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(x, y, doc, lib_doc, upper_hoehe_vario, lower_hoehe_vario, hoehe_vario,richtung2, drehung0, drehung1, laenge, None, blockname,config,block_vario,voerder_richtung, am_kreisel,erster_kreisel_höher,y1,z1)
# Erstellung der Vario gefälle selber
VarioFoerderer.VarioFoerderer.vario_erstellung(foerderer, doc, lib_doc, config, block_vario,block_name_links, start, ende,voerder_richtung ,winkel_VP_offset_vorne,winkel_VP_offset_hinten)
# Reintuen des endblockes in den Modelspace
if merkmale.get("Motorseite")== "links":
msp.add_blockref(block_name_links,(x,y,hoehe_vario),dxfattribs={"rotation": rotation})
elif merkmale.get("Motorseite")== "rechts":
msp.add_blockref(blockname,(x,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}_{voerder_richtung}_{laenge}_{hoehe_vario}_rechts_{drehung0}_{drehung1}_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}")
block_name_links = (f"Vario_Foerderer_{winkel}_{voerder_richtung}_{laenge}_{hoehe_vario}_links_{drehung0}_{drehung1}_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}")
# Falls der Block bereits in dem doc ist platziere diesen einfach
if blockname in doc.blocks:
if merkmale.get("Motorseite")== "links":
msp.add_blockref(block_name_links,(x,y,hoehe_vario),dxfattribs={"rotation": rotation})
return
elif merkmale.get("Motorseite")== "rechts":
msp.add_blockref(blockname,(x,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 = 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(x, y, doc, lib_doc, upper_hoehe_vario, lower_hoehe_vario, hoehe_vario,richtung2, drehung0, drehung1, laenge, None, blockname,config,block_vario,voerder_richtung)
# Erstellung des Vario selber
VarioFoerderer.VarioFoerderer.vario_erstellung(foerderer, doc, lib_doc, config, block_vario,block_name_links, start, ende,voerder_richtung,winkel_VP_offset_vorne,winkel_VP_offset_hinten )
# Reintuen des endblockes in den Modelspace
if merkmale.get("Motorseite")== "links":
msp.add_blockref(block_name_links,(x,y,hoehe_vario),dxfattribs={"rotation": rotation})
elif merkmale.get("Motorseite")== "rechts":
msp.add_blockref(blockname,(x,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}_{voerder_richtung}_{laenge}_{hoehe_vario}_rechts_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}")
block_name_links =(f"Vario_Foerderer_{winkel}_{voerder_richtung}_{laenge}_{hoehe_vario}_links_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}")
# Falls der Block bereits in dem doc ist platziere diesen einfach
if blockname in doc.blocks:
if merkmale.get("Motorseite")== "links":
msp.add_blockref(block_name_links,(x,y,hoehe_vario),dxfattribs={"rotation": rotation})
return
elif merkmale.get("Motorseite")== "rechts":
msp.add_blockref(blockname,(x,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 = doc.blocks.new(blockname, base_point=(0,0,0))
# Erstellung von start und ende
start = (x,y +dy, upper_hoehe_vario)
ende = (x ,y -dy, lower_hoehe_vario)
# Erstellung des Förderes selber
VarioFoerderer.VarioFoerderer.vario_erstellung(foerderer, doc, lib_doc, config, block,block_name_links, start, ende,voerder_richtung ,winkel_VP_offset_vorne,winkel_VP_offset_hinten)
# Reintuen des endblockes in den Modelspace
if merkmale.get("Motorseite")== "links":
msp.add_blockref(block_name_links,(x,y,hoehe_vario),dxfattribs={"rotation": rotation})
if merkmale.get("Motorseite")== "rechts":
msp.add_blockref(blockname,(x,y,hoehe_vario),dxfattribs={"rotation": rotation})
def handle_ils_2_0_kurve_angetrieben(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols, strecken_nachbarn,config,config_allgemein):
"""Erstellt eine Angetriebene Kurve (Förderer Kurve) in der neuen Dxf"""
voerder_kurve = Angetriebene_Kurve.Angetriebene_Kurve.from_merkmale(teileid,x,y,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,lib_doc,doc)
layer, color = block_methoden.get_insert_color_layer(lib_doc, blockname)
msp.add_blockref(blockname,(x,y,h_zwischen),dxfattribs={"rotation": rotation,"layer": layer, "color":color})
def handle_ils_2_0_kurve(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols, strecken_nachbarn,config,config_allgemein):
"""Erstellt eine Kurve (Gefälle Kurve) in der neuen Dxf"""
rotation= float(merkmale.get("Drehung"))
h0 = float(merkmale.get("Höhe Anfang")) * 1000
h1 = float(merkmale.get("Höhe Ende")) * 1000
hz = (h0 + h1)/2
kurvenrichtung = merkmale.get("Kurvenrichtung")
kurvenwinkel =int(merkmale.get("Kurvenwinkel"))
blockname = (f"Kurve_{kurvenrichtung}_{kurvenwinkel}°_R500_Gefälle")
block_methoden.import_block(blockname,lib_doc,doc)
msp.add_blockref(blockname,(x,y,hz),dxfattribs={"rotation": rotation})
def handle_bt___beladung(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols, strecken_nachbarn,config,config_allgemein):
"""Erstellt ein BT Element in der neuen Dxf"""
bt_element = Bt_element.Bt_element.from_merkmale(teileid,x,y,merkmale)
rotation = bt_element.drehung
hight = bt_element.hoehe
blockname = "AN8"
block_methoden.import_block(blockname,lib_doc,doc)
msp.add_blockref(blockname,(x,y,hight),dxfattribs={"rotation": rotation})
def handle_bt___entladung(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols, strecken_nachbarn,config,config_allgemein):
"""Erstellt ein BT Element in der neuen Dxf"""
bt_element = Bt_element.Bt_element.from_merkmale(teileid,x,y,merkmale)
rotation = bt_element.drehung
hight = bt_element.hoehe
blockname = "AN8"
block_methoden.import_block(blockname,lib_doc,doc)
msp.add_blockref(blockname,(x,y,hight),dxfattribs={"rotation": rotation})
def handle_omniflo(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols, strecken_nachbarn,config,config_allgemein):
"""
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 = config.get("Omniflo","OFgeradesivas")
tefsivas = config.get("Omniflo","Tefgeradesivas")
foerderer = config.get("Omniflo","OFfoerderer")
omniflo_objekt = Omniflo.Omniflo.from_merkmale(teileid,x,y,merkmale)
rotation = omniflo_objekt.drehung
if omniflo_objekt.sivasnummer == omnisivas or omniflo_objekt.sivasnummer == tefsivas:
Omniflo.Omniflo.Omniflo_geraden_erstellung(msp, x, y, doc, tefsivas, omniflo_objekt)
elif omniflo_objekt.sivasnummer == foerderer:
Omniflo.Omniflo.omniflo_foerdererstellung(msp, x, y, doc, lib_doc, omniflo_objekt, rotation)
# Sonst wie gehabt: Block mit SivasNummer
else:
if not lib_doc:
print("[WARN] lib_doc nicht verfügbar, Block wird nicht eingefügt.")
return
blockname = merkmale.get("SivasNummer")
if not blockname:
print(f"[WARN] Keine SivasNummer für {teileid}, überspringe.")
return
if blockname not in lib_doc.blocks:
print(f"[WARN] Omniflo-Block '{blockname}' nicht in Bibliothek {lib_doc.filename}. Überspringe {teileid}.")
return
blockname = blockname
block_methoden.import_block(blockname, lib_doc, doc)
layer, color = block_methoden.get_insert_color_layer(lib_doc, omniflo_objekt.sivasnummer)
msp.add_blockref(blockname, (x, y,omniflo_objekt.hoehe), dxfattribs={"rotation": rotation,"layer": layer, "color": color})
def normalize_func_name(name):
return (
name.replace('ä', 'ae')
.replace('ö', 'oe')
.replace('ü', 'ue')
.replace('ß', 'ss')
.replace(' ', '_')
.replace('.', '_')
.replace('-', '_')
.lower()
)
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
def get_nachbar_information(csv_path:Path) -> dict:
"""Gibt die Art und nötige Elemente den Nachbardateien zurück"""
geraden = []
kreisel =[]
strecken_nachbarn = []
angetriebene_kurve= []
eckrad_dic= []
"""Gib für jede gefällestrecke zurück welche Drehrichtung die benachbarten Kreisel haben """
with csv_path.open(newline="", encoding="utf-8") as fh:
reader = csv.DictReader(fh, delimiter=';')
for row in reader:
bezeichner = row["TeileArt"].strip()
if bezeichner == "ILS 2.0 Gefällestrecke":
Id = row["TeileId"].strip()
NachbarIds = row["NachbarIds"].strip()
geraden.append({"Id": Id, "NachbarIds": NachbarIds})
if bezeichner == "ILS 2.0 Kreisel" or bezeichner == "ILS 2.0 Kreisel mit Pin":
Id = row["TeileId"].strip()
planquadrat = row["Planquadrat"]
x, y = extract_coords(planquadrat)
merkmale = parse_merkmale(row.get("Merkmale", ""))
# Erstelle Kreisel-Objekt
kreisel_obj = Kreisel.Kreisel.from_merkmale(Id, x, y, merkmale)
# Für Kompatibilität auch als Dict speichern (für bestehende Code-Stellen)
kreisel.append({
"Id": Id,
"drehung": kreisel_obj.drehrichtung,
"höhe": kreisel_obj.hoehe,
"x": kreisel_obj.x,
"y": kreisel_obj.y,
"rotation": kreisel_obj.drehung,
"abstand": str(kreisel_obj.abstand / 1000) # Zurück in Meter als String
})
if bezeichner =="ILS 2.0 VarioFoerderer":
Id = row["TeileId"].strip()
NachbarIds = row["NachbarIds"].strip()
merkmale = parse_merkmale(row.get("Merkmale", ""))
planquadrat = row["Planquadrat"]
x, y = extract_coords(planquadrat)
foerderer_objekt = VarioFoerderer.VarioFoerderer.from_merkmale(Id, x,y,merkmale)
winkel = foerderer_objekt.winkel
h0 = foerderer_objekt.h0
h1 = foerderer_objekt.h1
foerderrichtung = foerderer_objekt.foerderer_richtung
geraden.append({"Id": Id,"NachbarIds":NachbarIds, "Winkel":winkel, "h0": h0,"h1": h1,"Foerderrichtung":foerderrichtung,"X_foerderer": x,"Y_foerderer": y
})
if bezeichner =="ILS 2.0 Kurve angetrieben":
Id = row["TeileId"].strip()
planquadrat = row["Planquadrat"]
x, y = extract_coords(planquadrat)
merkmale = parse_merkmale(row.get("Merkmale", ""))
kurve_angetrieben = Angetriebene_Kurve.Angetriebene_Kurve.from_merkmale(Id,x,y,merkmale)
h0 = kurve_angetrieben.hoehe0
h1 = kurve_angetrieben.hoehe1
kurvenrichtung = kurve_angetrieben.kurvenrichtung
tefkurve = kurve_angetrieben.antrieb
kurve_winkel = kurve_angetrieben.winkel
angetriebene_kurve.append({"Id": Id,"H0": h0,"H1":h1,"kurvenrichtung":kurvenrichtung,"Tefkurve": tefkurve,"Kurvenwinkel": kurve_winkel,"X_angetrieben":x,"Y_angetrieben":y})
if bezeichner =="ILS 2.0 Eckrad":
Id = row["TeileId"].strip()
planquadrat = row["Planquadrat"]
x, y = extract_coords(planquadrat)
merkmale = parse_merkmale(row.get("Merkmale", ""))
eckrad_att = Eckrad.Eckrad.from_merkmale(Id,x,y,merkmale)
eckrad_dic.append({"Id": Id,"H0": eckrad_att.hoehe,"Eckrad_x": x,"Eckrad_y": y})
for gerade in geraden:
anweisungen = 0
voerder_anweisung = 0
geraden_anweisung = 0
eckrad_anweisung = 0
eintrag = {"Id": gerade["Id"]}
for foerderer in angetriebene_kurve:
if foerderer["Id"] in gerade["NachbarIds"]:
if voerder_anweisung == 0:
eintrag["X_angetrieben"] = foerderer.get("X_angetrieben")
eintrag["Y_angetrieben"] = foerderer.get("Y_angetrieben")
eintrag["vario_hoehe_0"] = foerderer.get("H0")
eintrag["vario_hoehe_1"] = foerderer.get("H1")
eintrag["Kurvenrichtung"] = foerderer.get("kurvenrichtung")
eintrag["Tefkurve"] = foerderer.get("Tefkurve")
eintrag["Kurvenwinkel"] = foerderer.get("Kurvenwinkel")
voerder_anweisung = 1
elif voerder_anweisung ==1:
eintrag["X_angetrieben_1"] = foerderer.get("X_angetrieben")
eintrag["Y_angetrieben_1"] = foerderer.get("Y_angetrieben")
eintrag["vario_hoehe_0_1"] = foerderer.get("H0")
eintrag["vario_hoehe_1_1"] = foerderer.get("H1")
eintrag["Kurvenrichtung_1"] = foerderer.get("kurvenrichtung")
eintrag["Tefkurve_1"] = foerderer.get("Tefkurve")
eintrag["Kurvenwinkel_1"] = foerderer.get("Kurvenwinkel")
for eckrad in eckrad_dic:
if eckrad["Id"] in gerade["NachbarIds"]:
if eckrad_anweisung == 0:
eintrag["Eckrad_x"] = eckrad.get("Eckrad_x")
eintrag["Eckrad_y"] = eckrad.get("Eckrad_y")
eintrag["Eckrad_höhe"] = eckrad.get("H0")
eckrad_anweisung = 1
elif eckrad_anweisung == 1:
eintrag["Eckrad_x_1"] = eckrad.get("Eckrad_x")
eintrag["Eckrad_y_1"] = eckrad.get("Eckrad_y")
eintrag["Eckrad_höhe_1"] = eckrad.get("H0")
for kreis in kreisel:
if kreis["Id"] in gerade["NachbarIds"]:
if anweisungen == 0:
eintrag["Drehung0"] = kreis.get("drehung")
eintrag["Hoehe0"] = kreis.get("höhe")
eintrag["x0"] = kreis.get("x")
eintrag["y0"] = kreis.get("y")
eintrag["rotation0"] = kreis.get("rotation")
eintrag["abstand0"] = kreis.get("abstand")
anweisungen = 1
elif anweisungen == 1:
eintrag["Drehung1"] = kreis.get("drehung")
eintrag["Hoehe1"] = kreis.get("höhe")
eintrag["x1"] = kreis.get("x")
eintrag["y1"] = kreis.get("y")
eintrag["rotation1"] = kreis.get("rotation")
eintrag["abstand1"] = kreis.get("abstand")
break
if(gerade.get("Winkel") != None ):
for vario_gerade in geraden:
if vario_gerade["Id"] in gerade["NachbarIds"] and vario_gerade.get("Winkel") != None:
if geraden_anweisung == 0:
eintrag["X_foerderer"] = vario_gerade.get("X_foerderer")
eintrag["Y_foerderer"] = vario_gerade.get("Y_foerderer")
eintrag["Winkel"] = vario_gerade.get("Winkel")
eintrag["h0"] = vario_gerade.get("h0")
eintrag["h1"] = vario_gerade.get("h1")
eintrag["Foerderrichtung"] = vario_gerade.get("Foerderrichtung")
geraden_anweisung =1
elif geraden_anweisung == 1:
eintrag["X_foerderer_2"] = vario_gerade.get("X_foerderer")
eintrag["Y_foerderer_2"] = vario_gerade.get("Y_foerderer")
eintrag["Winkel_2"] = vario_gerade.get("Winkel")
eintrag["h0_2"] = vario_gerade.get("h0")
eintrag["h1_2"] = vario_gerade.get("h1")
eintrag["Foerderrichtung_2"] = vario_gerade.get("Foerderrichtung")
break
strecken_nachbarn.append(eintrag)
return strecken_nachbarn
# --------------------------------------------------------- Hauptfunktion
def main(csv_path: Path, lib_path: Path, cfg_path: Path, allgemein_cfg_path: Path,
output_path: Path, output_path_jason: 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 = 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 = parse_merkmale(row.get("Merkmale", ""))
merkmale["bezeichner"] = bezeichner
try:
x, y = 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_<teileart> (mit _ statt Leerzeichen und Punkten, alles klein)
func_name = f'handle_{normalize_func_name(teileart)}'
handler = globals().get(func_name)
symbols = 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:
handler(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols, strecken_nachbarn, config,config_allgemein)
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 ===")
# CSVPfad: nur Dateiname → im WORKOrdner 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_jason = Path(args.output) if args.output else (work_dir / f"{csv_path.stem}.jason")
main(csv_path, default_lib_path, cfg_path,allgemein_cfg_path, output_path,output_path_jason, verbose=args.verbose, logger=logger)
logger.info("=== plant2dxf Verarbeitung abgeschlossen ===")