alles neu mit black formatiert. handler_context.py impl. um weniger Übergabeparameter zu haben
This commit is contained in:
@@ -1,15 +1,17 @@
|
||||
|
||||
from pydantic import BaseModel, Field, field_validator
|
||||
|
||||
|
||||
class Angetriebene_Kurve(BaseModel):
|
||||
teileid: str
|
||||
x: float
|
||||
y:float
|
||||
drehung: float = Field(default=0.0,description="Rotation der Kurve")
|
||||
hoehe0: float = Field(default=0.0,description="Hoehe Anfang der Kurve")
|
||||
hoehe1: float = Field(default=0.0,description="Hoehe Ende der Kurve")
|
||||
y: float
|
||||
drehung: float = Field(default=0.0, description="Rotation der Kurve")
|
||||
hoehe0: float = Field(default=0.0, description="Hoehe Anfang der Kurve")
|
||||
hoehe1: float = Field(default=0.0, description="Hoehe Ende der Kurve")
|
||||
kurvenrichtung: str = Field(description="Kurvenrichtung der Kurve")
|
||||
antriebNebenStrecke: str =Field(description="wo die Angetriebene Strecke ist abhängig von der kurvenrichtung")
|
||||
antriebNebenStrecke: str = Field(
|
||||
description="wo die Angetriebene Strecke ist abhängig von der kurvenrichtung"
|
||||
)
|
||||
winkel: int = Field(description="Der Winkel der Kurve")
|
||||
|
||||
@property
|
||||
@@ -19,11 +21,15 @@ class Angetriebene_Kurve(BaseModel):
|
||||
elif self.antriebNebenStrecke == "Innen":
|
||||
self.antriebNebenStrecke = "innen"
|
||||
return self.antriebNebenStrecke
|
||||
|
||||
@property
|
||||
def hight_zwischen(self):
|
||||
return ((self.hoehe0 + self.hoehe1) /2)
|
||||
return (self.hoehe0 + self.hoehe1) / 2
|
||||
|
||||
@classmethod
|
||||
def from_merkmale(cls, teileid: str, x: float, y: float, merkmale: dict) -> 'Angetriebene_Kurve':
|
||||
def from_merkmale(
|
||||
cls, teileid: str, x: float, y: float, merkmale: dict
|
||||
) -> "Angetriebene_Kurve":
|
||||
hoehe0 = float(merkmale.get("Höhe Anfang")) * 1000
|
||||
hoehe1 = float(merkmale.get("Höhe Ende")) * 1000
|
||||
winkel = int(merkmale.get("Kurvenwinkel"))
|
||||
@@ -35,14 +41,13 @@ class Angetriebene_Kurve(BaseModel):
|
||||
drehung = 0.0
|
||||
|
||||
return cls(
|
||||
teileid = teileid,
|
||||
x = x,
|
||||
y = y,
|
||||
drehung = drehung,
|
||||
hoehe0 = hoehe0,
|
||||
hoehe1 = hoehe1,
|
||||
kurvenrichtung = kurvenrichtung,
|
||||
antriebNebenStrecke = antriebNebenstrecke,
|
||||
winkel = winkel
|
||||
|
||||
teileid=teileid,
|
||||
x=x,
|
||||
y=y,
|
||||
drehung=drehung,
|
||||
hoehe0=hoehe0,
|
||||
hoehe1=hoehe1,
|
||||
kurvenrichtung=kurvenrichtung,
|
||||
antriebNebenStrecke=antriebNebenstrecke,
|
||||
winkel=winkel,
|
||||
)
|
||||
@@ -1,14 +1,18 @@
|
||||
from pydantic import BaseModel, Field, field_validator
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class Bt_element(BaseModel):
|
||||
"""Das sind beide BTMT Elemente"""
|
||||
|
||||
teileid: str
|
||||
drehung: Optional [float] = Field(default=0.0,description="Rotation des Elements")
|
||||
hoehe: Optional [float] = Field(default=0.0,description="Hoehe des Elements")
|
||||
drehung: Optional[float] = Field(default=0.0, description="Rotation des Elements")
|
||||
hoehe: Optional[float] = Field(default=0.0, description="Hoehe des Elements")
|
||||
|
||||
@classmethod
|
||||
def from_merkmale(cls, teileid: str, x: float, y: float, merkmale: dict) -> 'Bt_element':
|
||||
def from_merkmale(
|
||||
cls, teileid: str, x: float, y: float, merkmale: dict
|
||||
) -> "Bt_element":
|
||||
try:
|
||||
hoehe = float(merkmale.get("Höhe in Meter"))
|
||||
except Exception as e:
|
||||
@@ -18,10 +22,4 @@ class Bt_element(BaseModel):
|
||||
except Exception as e:
|
||||
drehung = 0.0
|
||||
|
||||
return cls(
|
||||
teileid = teileid,
|
||||
x = x,
|
||||
y = y,
|
||||
hoehe = hoehe,
|
||||
drehung = drehung
|
||||
)
|
||||
return cls(teileid=teileid, x=x, y=y, hoehe=hoehe, drehung=drehung)
|
||||
|
||||
+28
-22
@@ -1,15 +1,22 @@
|
||||
from pydantic import BaseModel, Field, field_validator
|
||||
from typing import Optional
|
||||
import block_methoden
|
||||
|
||||
RADIUS = 400
|
||||
|
||||
|
||||
class Eckrad(BaseModel):
|
||||
teileid: str
|
||||
drehung: Optional [float] = Field(default=0.0,description="Rotation des Elements")
|
||||
hoehe: Optional [float] = Field(default=0.0,description="Hoehe des Elements")
|
||||
drehrichtung: Optional [str] =Field(default=None,description="Richtung des Eckrads")
|
||||
drehung: Optional[float] = Field(default=0.0, description="Rotation des Elements")
|
||||
hoehe: Optional[float] = Field(default=0.0, description="Hoehe des Elements")
|
||||
drehrichtung: Optional[str] = Field(
|
||||
default=None, description="Richtung des Eckrads"
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_merkmale(cls, teileid: str, x: float, y: float, merkmale: dict) -> 'Eckrad':
|
||||
def from_merkmale(
|
||||
cls, teileid: str, x: float, y: float, merkmale: dict
|
||||
) -> "Eckrad":
|
||||
try:
|
||||
hoehe = float(merkmale.get("Höhe in Meter")) * 1000
|
||||
except Exception as e:
|
||||
@@ -22,27 +29,26 @@ class Eckrad(BaseModel):
|
||||
drehrichtung = merkmale.get("Drehrichtung")
|
||||
except Exception as e:
|
||||
drehrichtung = None
|
||||
return cls(
|
||||
teileid = teileid,
|
||||
x = x,
|
||||
y = y,
|
||||
hoehe = hoehe,
|
||||
drehrichtung = drehrichtung
|
||||
)
|
||||
return cls(teileid=teileid, x=x, y=y, hoehe=hoehe, drehrichtung=drehrichtung)
|
||||
|
||||
def erstellung_eckrad_richtung(merkmale, doc, lib_doc):
|
||||
block_methoden.import_block("AN8",lib_doc,doc)
|
||||
block_methoden.import_block("Richtungspfeil",lib_doc,doc)
|
||||
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})
|
||||
return eckrad_rechts,eckrad_links,hight
|
||||
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}
|
||||
)
|
||||
return eckrad_rechts, eckrad_links, hight
|
||||
|
||||
@@ -38,11 +38,11 @@ class Gefaellestrecke(BaseModel):
|
||||
anzahl_scanner = int(merkmale.get("Anzahl der Scanner")),
|
||||
anzahl_separatoren = int(merkmale.get("Anzahl der Separatoren"))
|
||||
)
|
||||
def erstehlung_von_gefalle_ohne_aussnahmen(msp, x, y, upper_hoehe_gefaehlle, lower_hoehe_gefaehlle, halbe_laenge, winkel):
|
||||
def erstehlung_von_gefalle_ohne_aussnahmen(msp, x, y, upper_hoehe_gefaelle, lower_hoehe_gefaelle, halbe_laenge, winkel):
|
||||
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
|
||||
start = x +dx, y + dy,upper_hoehe_gefaelle
|
||||
ende = x -dx, y - dy,lower_hoehe_gefaelle
|
||||
line =msp.add_line(start,ende)
|
||||
line.dxf.layer = "6-SP"
|
||||
def rotation_mit_zwei_verbunden(gefaellestrecke_nachbarn,richtung2, richtung0, am_kreisel, kreisel_verbunden, hight_position):
|
||||
@@ -137,7 +137,7 @@ class Gefaellestrecke(BaseModel):
|
||||
elif gefaelle == "rechts" :
|
||||
rotation = 270
|
||||
return rotation,drehung0,drehung1,hight_position
|
||||
def 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):
|
||||
def ein_motor_oder_eine_umlenk(x, y,start,ende, doc, 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):
|
||||
|
||||
block_Vario_Bogen_auf = (f"Vario_Bogen_auf_3°")
|
||||
block_Vario_Bogen_ab = (f"Vario_Bogen_ab_3°")
|
||||
@@ -165,48 +165,48 @@ class Gefaellestrecke(BaseModel):
|
||||
if hat_motor_0 == True:
|
||||
if tefkurve_0 == "links":
|
||||
if motor_gerade == False:
|
||||
block.add_blockref(block_Vario_Bogen_ab_links,(start[0]-x,start[1]-Vario_Bogen_ab_Delta_SP_0[0]-y,start[2]- Vario_Bogen_ab_Delta_SP_0[2]-hoehe_gefaehlle),dxfattribs={"rotation": 270})
|
||||
block.add_blockref(block_Vario_Bogen_ab_links,(start[0]-x,start[1]-Vario_Bogen_ab_Delta_SP_0[0]-y,start[2]- Vario_Bogen_ab_Delta_SP_0[2]-hoehe_gefaelle),dxfattribs={"rotation": 270})
|
||||
start = [start[0],start[1]-Vario_Bogen_ab_Delta_SP_0[0]- Vario_Bogen_ab_Delta_SP_1[0],start[2]-Vario_Bogen_ab_Delta_SP_0[2]- Vario_Bogen_ab_Delta_SP_1[2]]
|
||||
block.add_blockref(blockname_motor_links, (start[0]-x,start[1] - 250* math.cos(math.radians(3))-y,start[2] - 250* math.sin(math.radians(3))-hoehe_gefaehlle),dxfattribs={"rotation": 270})
|
||||
block.add_blockref(blockname_motor_links, (start[0]-x,start[1] - 250* math.cos(math.radians(3))-y,start[2] - 250* math.sin(math.radians(3))-hoehe_gefaelle),dxfattribs={"rotation": 270})
|
||||
start[1]= start[1] - 500* math.cos(math.radians(3))
|
||||
start[2] = start[2] - 500* math.sin(math.radians(3))
|
||||
else:
|
||||
block.add_blockref("Vario_Motorstation_500mm_links", (start[0]-x,start[1] -250 -y,start[2] -hoehe_gefaehlle),dxfattribs={"rotation": 270})
|
||||
block.add_blockref("Vario_Motorstation_500mm_links", (start[0]-x,start[1] -250 -y,start[2] -hoehe_gefaelle),dxfattribs={"rotation": 270})
|
||||
start[1]= start[1] - 500
|
||||
|
||||
else:
|
||||
if motor_gerade == False:
|
||||
block.add_blockref(block_Vario_Bogen_ab,(start[0]-x,start[1]-Vario_Bogen_ab_Delta_SP_0[0]-y,start[2]- Vario_Bogen_ab_Delta_SP_0[2]-hoehe_gefaehlle),dxfattribs={"rotation": 270})
|
||||
block.add_blockref(block_Vario_Bogen_ab,(start[0]-x,start[1]-Vario_Bogen_ab_Delta_SP_0[0]-y,start[2]- Vario_Bogen_ab_Delta_SP_0[2]-hoehe_gefaelle),dxfattribs={"rotation": 270})
|
||||
start = [start[0],start[1]-Vario_Bogen_ab_Delta_SP_0[0]- Vario_Bogen_ab_Delta_SP_1[0],start[2]-Vario_Bogen_ab_Delta_SP_0[2]- Vario_Bogen_ab_Delta_SP_1[2]]
|
||||
block.add_blockref(block_Vario_Motorstation_500mm, (start[0]-x,start[1] - 250* math.cos(math.radians(3))-y,start[2] - 250* math.sin(math.radians(3))-hoehe_gefaehlle),dxfattribs={"rotation": 270})
|
||||
block.add_blockref(block_Vario_Motorstation_500mm, (start[0]-x,start[1] - 250* math.cos(math.radians(3))-y,start[2] - 250* math.sin(math.radians(3))-hoehe_gefaelle),dxfattribs={"rotation": 270})
|
||||
start[1]= start[1] - 500* math.cos(math.radians(3))
|
||||
start[2] = start[2] - 500* math.sin(math.radians(3))
|
||||
else:
|
||||
block.add_blockref("Vario_Motorstation_500mm", (start[0]-x,start[1]- 250 -y,start[2] -hoehe_gefaehlle),dxfattribs={"rotation": 270})
|
||||
block.add_blockref("Vario_Motorstation_500mm", (start[0]-x,start[1]- 250 -y,start[2] -hoehe_gefaelle),dxfattribs={"rotation": 270})
|
||||
start[1]= start[1] - 500
|
||||
|
||||
if hat_umlenk_0 == True:
|
||||
if tefkurve_0 == "links":
|
||||
if umlenk_gerade == False:
|
||||
block.add_blockref(block_Vario_Bogen_auf,(ende[0]-x,ende[1]+Vario_Bogen_auf_Delta_SP_0[0]-y,ende[2] + Vario_Bogen_auf_Delta_SP_0[2]-hoehe_gefaehlle),dxfattribs={"rotation": 90})
|
||||
block.add_blockref(block_Vario_Bogen_auf,(ende[0]-x,ende[1]+Vario_Bogen_auf_Delta_SP_0[0]-y,ende[2] + Vario_Bogen_auf_Delta_SP_0[2]-hoehe_gefaelle),dxfattribs={"rotation": 90})
|
||||
ende = [ende[0],ende[1]+ Vario_Bogen_auf_Delta_SP_0[0]+ Vario_Bogen_auf_Delta_SP_1[0],ende[2]+Vario_Bogen_auf_Delta_SP_0[2]+ Vario_Bogen_auf_Delta_SP_1[2]]
|
||||
block.add_blockref(blockname_umlenk_links, (ende[0]-x,ende[1] + 250* math.cos(math.radians(3))-y,ende[2] + 250* math.sin(math.radians(3))-hoehe_gefaehlle),dxfattribs={"rotation": 270})
|
||||
block.add_blockref(blockname_umlenk_links, (ende[0]-x,ende[1] + 250* math.cos(math.radians(3))-y,ende[2] + 250* math.sin(math.radians(3))-hoehe_gefaelle),dxfattribs={"rotation": 270})
|
||||
|
||||
ende [1]= ende[1] + 500* math.cos(math.radians(3))
|
||||
ende[2] = ende[2] + 500* math.sin(math.radians(3))
|
||||
else:
|
||||
block.add_blockref("Vario_Umlenkstation_500mm_links", (ende[0]-x,ende[1] + 250-y,ende[2] -hoehe_gefaehlle),dxfattribs={"rotation": 270})
|
||||
block.add_blockref("Vario_Umlenkstation_500mm_links", (ende[0]-x,ende[1] + 250-y,ende[2] -hoehe_gefaelle),dxfattribs={"rotation": 270})
|
||||
ende [1]= ende[1] + 500
|
||||
|
||||
else:
|
||||
if umlenk_gerade == False:
|
||||
block.add_blockref(block_Vario_Bogen_auf_links,(ende[0]-x,ende[1]+Vario_Bogen_auf_Delta_SP_0[0]-y,ende[2] + Vario_Bogen_auf_Delta_SP_0[2]-hoehe_gefaehlle),dxfattribs={"rotation": 90})
|
||||
block.add_blockref(block_Vario_Bogen_auf_links,(ende[0]-x,ende[1]+Vario_Bogen_auf_Delta_SP_0[0]-y,ende[2] + Vario_Bogen_auf_Delta_SP_0[2]-hoehe_gefaelle),dxfattribs={"rotation": 90})
|
||||
ende = [ende[0],ende[1]+ Vario_Bogen_auf_Delta_SP_0[0]+ Vario_Bogen_auf_Delta_SP_1[0],ende[2]+Vario_Bogen_auf_Delta_SP_0[2]+ Vario_Bogen_auf_Delta_SP_1[2]]
|
||||
block.add_blockref(block_Vario_Umlenkstation_500mm, (ende[0]-x,ende[1] + 250* math.cos(math.radians(3))-y,ende[2] + 250* math.sin(math.radians(3))-hoehe_gefaehlle),dxfattribs={"rotation": 270})
|
||||
block.add_blockref(block_Vario_Umlenkstation_500mm, (ende[0]-x,ende[1] + 250* math.cos(math.radians(3))-y,ende[2] + 250* math.sin(math.radians(3))-hoehe_gefaelle),dxfattribs={"rotation": 270})
|
||||
ende [1]= ende[1] + 500* math.cos(math.radians(3))
|
||||
ende[2] = ende[2] + 500* math.sin(math.radians(3))
|
||||
else:
|
||||
block.add_blockref("Vario_Umlenkstation_500mm", (ende[0]-x,ende[1] + 250-y,ende[2] -hoehe_gefaehlle),dxfattribs={"rotation": 270})
|
||||
block.add_blockref("Vario_Umlenkstation_500mm", (ende[0]-x,ende[1] + 250-y,ende[2] -hoehe_gefaelle),dxfattribs={"rotation": 270})
|
||||
ende [1]= ende[1] + 500
|
||||
return start,ende
|
||||
def hat_motor_umlenk_station (gefaelle_objekt, gefaellestrecke_nachbarn):
|
||||
@@ -218,8 +218,8 @@ class Gefaellestrecke(BaseModel):
|
||||
tefkurve_1 = None
|
||||
umlenk_gerade = False
|
||||
motor_gerade = False
|
||||
upper_hoehe_gefaehlle = gefaelle_objekt.h1
|
||||
lower_hoehe_gefaehlle = gefaelle_objekt.h0
|
||||
upper_hoehe_gefaelle = gefaelle_objekt.h1
|
||||
lower_hoehe_gefaelle = gefaelle_objekt.h0
|
||||
rotation = gefaelle_objekt.drehung
|
||||
x = gefaelle_objekt.x
|
||||
y = gefaelle_objekt.y
|
||||
@@ -238,13 +238,13 @@ class Gefaellestrecke(BaseModel):
|
||||
else:
|
||||
tefkurve_0 = "links"
|
||||
|
||||
if upper_hoehe_gefaehlle > lower_hoehe_gefaehlle:
|
||||
if vario_hoehe_0 == upper_hoehe_gefaehlle or vario_hoehe_1 == upper_hoehe_gefaehlle:
|
||||
if upper_hoehe_gefaelle > lower_hoehe_gefaelle:
|
||||
if vario_hoehe_0 == upper_hoehe_gefaelle or vario_hoehe_1 == upper_hoehe_gefaelle:
|
||||
hat_motor_0 = True
|
||||
else:
|
||||
hat_umlenk_0 = True
|
||||
elif upper_hoehe_gefaehlle < lower_hoehe_gefaehlle:
|
||||
if vario_hoehe_0 == lower_hoehe_gefaehlle or vario_hoehe_1 == lower_hoehe_gefaehlle:
|
||||
elif upper_hoehe_gefaelle < lower_hoehe_gefaelle:
|
||||
if vario_hoehe_0 == lower_hoehe_gefaelle or vario_hoehe_1 == lower_hoehe_gefaelle:
|
||||
hat_motor_0 = True
|
||||
else:
|
||||
hat_umlenk_0 = True
|
||||
@@ -270,13 +270,13 @@ class Gefaellestrecke(BaseModel):
|
||||
tefkurve_1 = "rechts"
|
||||
else:
|
||||
tefkurve_1 = "links"
|
||||
if upper_hoehe_gefaehlle > lower_hoehe_gefaehlle:
|
||||
if vario_hoehe_0_1 == upper_hoehe_gefaehlle or vario_hoehe_1_1 == upper_hoehe_gefaehlle:
|
||||
if upper_hoehe_gefaelle > lower_hoehe_gefaelle:
|
||||
if vario_hoehe_0_1 == upper_hoehe_gefaelle or vario_hoehe_1_1 == upper_hoehe_gefaelle:
|
||||
hat_motor_1 = True
|
||||
else:
|
||||
hat_umlenk_1 = True
|
||||
elif upper_hoehe_gefaehlle < lower_hoehe_gefaehlle:
|
||||
if vario_hoehe_0_1 == lower_hoehe_gefaehlle or vario_hoehe_1_1 == lower_hoehe_gefaehlle:
|
||||
elif upper_hoehe_gefaelle < lower_hoehe_gefaelle:
|
||||
if vario_hoehe_0_1 == lower_hoehe_gefaelle or vario_hoehe_1_1 == lower_hoehe_gefaelle:
|
||||
hat_motor_1 = True
|
||||
else:
|
||||
hat_umlenk_1 = True
|
||||
|
||||
+83
-34
@@ -1,4 +1,3 @@
|
||||
|
||||
from ezdxf.entities import Line
|
||||
import math
|
||||
from pydantic import BaseModel, Field, field_validator
|
||||
@@ -10,20 +9,28 @@ import block_methoden
|
||||
ATTR_TAG = "TeileId" # Attributtag im Block
|
||||
RADIUS = 400 # Radius der Kreiselkreise (mm)
|
||||
|
||||
|
||||
class Kreisel(BaseModel):
|
||||
"""Pydantic-Modell für Kreisel-Komponenten."""
|
||||
|
||||
teileid: str
|
||||
x: float = Field(description="X-Koordinate des Kreisel-Zentrums")
|
||||
y: float = Field(description="Y-Koordinate des Kreisel-Zentrums")
|
||||
hoehe: float = Field(description="Höhe in mm")
|
||||
drehung: float = Field(default=0.0, description="Drehung/Winkel in Grad")
|
||||
drehrichtung: Optional[str] = Field(default=None, description="Drehrichtung: UZS oder GUZS")
|
||||
abstand: float = Field(default=20000.0, description="Abstand zwischen Kreiselachsen in mm")
|
||||
kreiselart: Optional[str] = Field(default=None, description="Kreiselart, z.B. 'Pin'")
|
||||
drehrichtung: Optional[str] = Field(
|
||||
default=None, description="Drehrichtung: UZS oder GUZS"
|
||||
)
|
||||
abstand: float = Field(
|
||||
default=20000.0, description="Abstand zwischen Kreiselachsen in mm"
|
||||
)
|
||||
kreiselart: Optional[str] = Field(
|
||||
default=None, description="Kreiselart, z.B. 'Pin'"
|
||||
)
|
||||
anzahl_scanner: float = Field(default=0.0, description="Anzahl der Scanner")
|
||||
anzahl_separatoren: float = Field(default=0.0, description="Anzahl der Separatoren")
|
||||
|
||||
@field_validator('abstand')
|
||||
@field_validator("abstand")
|
||||
@classmethod
|
||||
def validate_abstand(cls, v):
|
||||
"""Konvertiert Abstand von Meter zu mm, falls nötig."""
|
||||
@@ -35,7 +42,7 @@ class Kreisel(BaseModel):
|
||||
v = 10000.0 # Fallback 10 m
|
||||
return v
|
||||
|
||||
@field_validator('hoehe')
|
||||
@field_validator("hoehe")
|
||||
@classmethod
|
||||
def validate_hoehe(cls, v):
|
||||
"""Konvertiert Höhe von Meter zu mm, falls nötig."""
|
||||
@@ -86,7 +93,9 @@ class Kreisel(BaseModel):
|
||||
return self.hoehe
|
||||
|
||||
@classmethod
|
||||
def from_merkmale(cls, teileid: str, x: float, y: float, merkmale: dict) -> 'Kreisel':
|
||||
def from_merkmale(
|
||||
cls, teileid: str, x: float, y: float, merkmale: dict
|
||||
) -> "Kreisel":
|
||||
"""Erstellt ein Kreisel-Objekt aus einem merkmale-Dictionary."""
|
||||
hoehe_m = merkmale.get("Höhe in m", "0").replace(",", ".")
|
||||
try:
|
||||
@@ -94,7 +103,9 @@ class Kreisel(BaseModel):
|
||||
except (ValueError, TypeError):
|
||||
hoehe = 0.0
|
||||
|
||||
abstand_m = merkmale.get("Abstand (Kreiselachse A - Kreiselachse) in Meter", "20").replace(",", ".")
|
||||
abstand_m = merkmale.get(
|
||||
"Abstand (Kreiselachse A - Kreiselachse) in Meter", "20"
|
||||
).replace(",", ".")
|
||||
try:
|
||||
abstand = float(abstand_m) * 1000
|
||||
except (ValueError, TypeError):
|
||||
@@ -125,7 +136,7 @@ class Kreisel(BaseModel):
|
||||
abstand=abstand,
|
||||
kreiselart=merkmale.get("Kreiselart"),
|
||||
anzahl_scanner=anzahl_scanner,
|
||||
anzahl_separatoren=anzahl_separatoren
|
||||
anzahl_separatoren=anzahl_separatoren,
|
||||
)
|
||||
|
||||
def draw_kreisel_lines(msp, pos1, pos2, kreisel):
|
||||
@@ -145,18 +156,22 @@ class Kreisel(BaseModel):
|
||||
nx = -dy / length * RADIUS
|
||||
ny = dx / length * RADIUS
|
||||
# Tangentialpunkte
|
||||
p1a = (x1 + nx, y1 + ny,z1)
|
||||
p1b = (x1 - nx, y1 - ny,z1)
|
||||
p2a = (x2 + nx, y2 + ny,z1)
|
||||
p2b = (x2 - nx, y2 - ny,z1)
|
||||
p1a = (x1 + nx, y1 + ny, z1)
|
||||
p1b = (x1 - nx, y1 - ny, z1)
|
||||
p2a = (x2 + nx, y2 + ny, z1)
|
||||
p2b = (x2 - nx, y2 - ny, z1)
|
||||
if kreisel.kreiselart == "Pin":
|
||||
if rotation == 0.0:
|
||||
p1a2 = p1a[0] - RADIUS - 50, p1a[1] + 50, z1
|
||||
p1b2 = p1b[0] - RADIUS - 50, p1b[1] - 50, z1
|
||||
p2a2 = p2a[0] + RADIUS + 50, p2a[1] + 50, z1
|
||||
p2b2 = p2b[0] + RADIUS + 50, p2b[1] - 50, z1
|
||||
Line1 = Line.new(dxfattribs={"start": p1a2,"end": p2a2,"layer": "Pinbereich"})
|
||||
Line2 = Line.new(dxfattribs={"start": p1b2,"end": p2b2,"layer": "Pinbereich"})
|
||||
Line1 = Line.new(
|
||||
dxfattribs={"start": p1a2, "end": p2a2, "layer": "Pinbereich"}
|
||||
)
|
||||
Line2 = Line.new(
|
||||
dxfattribs={"start": p1b2, "end": p2b2, "layer": "Pinbereich"}
|
||||
)
|
||||
msp.add_entity(Line1)
|
||||
msp.add_entity(Line2)
|
||||
elif rotation == 180.0:
|
||||
@@ -164,26 +179,38 @@ class Kreisel(BaseModel):
|
||||
p1b2 = p1b[0] + RADIUS + 50, p1b[1] + 50, z1
|
||||
p2a2 = p2a[0] - RADIUS - 50, p2a[1] - 50, z1
|
||||
p2b2 = p2b[0] - RADIUS - 50, p2b[1] + 50, z1
|
||||
Line1 = Line.new(dxfattribs={"start": p1a2,"end": p2a2,"layer": "Pinbereich"})
|
||||
Line2 = Line.new(dxfattribs={"start": p1b2,"end": p2b2,"layer": "Pinbereich"})
|
||||
Line1 = Line.new(
|
||||
dxfattribs={"start": p1a2, "end": p2a2, "layer": "Pinbereich"}
|
||||
)
|
||||
Line2 = Line.new(
|
||||
dxfattribs={"start": p1b2, "end": p2b2, "layer": "Pinbereich"}
|
||||
)
|
||||
msp.add_entity(Line1)
|
||||
msp.add_entity(Line2)
|
||||
elif rotation == 90.0:
|
||||
p1a2 = p1a[0] + 50, p1a[1] - 50 + RADIUS , z1
|
||||
p1a2 = p1a[0] + 50, p1a[1] - 50 + RADIUS, z1
|
||||
p1b2 = p1b[0] - 50, p1b[1] - 50 + RADIUS, z1
|
||||
p2a2 = p2a[0] + 50, p2a[1] + 50 - RADIUS, z1
|
||||
p2b2 = p2b[0] - 50, p2b[1] + 50 - RADIUS, z1
|
||||
Line1 = Line.new(dxfattribs={"start": p1a2,"end": p2a2,"layer": "Pinbereich"})
|
||||
Line2 = Line.new(dxfattribs={"start": p1b2,"end": p2b2,"layer": "Pinbereich"})
|
||||
Line1 = Line.new(
|
||||
dxfattribs={"start": p1a2, "end": p2a2, "layer": "Pinbereich"}
|
||||
)
|
||||
Line2 = Line.new(
|
||||
dxfattribs={"start": p1b2, "end": p2b2, "layer": "Pinbereich"}
|
||||
)
|
||||
msp.add_entity(Line1)
|
||||
msp.add_entity(Line2)
|
||||
elif rotation == 270.0:
|
||||
p1a2 = p1a[0] - 50, p1a[1] + 50 - RADIUS , z1
|
||||
p1a2 = p1a[0] - 50, p1a[1] + 50 - RADIUS, z1
|
||||
p1b2 = p1b[0] + 50, p1b[1] + 50 - RADIUS, z1
|
||||
p2a2 = p2a[0] - 50, p2a[1] - 50 + RADIUS, z1
|
||||
p2b2 = p2b[0] + 50, p2b[1] - 50 + RADIUS, z1
|
||||
Line1 = Line.new(dxfattribs={"start": p1a2,"end": p2a2,"layer": "Pinbereich"})
|
||||
Line2 = Line.new(dxfattribs={"start": p1b2,"end": p2b2,"layer": "Pinbereich"})
|
||||
Line1 = Line.new(
|
||||
dxfattribs={"start": p1a2, "end": p2a2, "layer": "Pinbereich"}
|
||||
)
|
||||
Line2 = Line.new(
|
||||
dxfattribs={"start": p1b2, "end": p2b2, "layer": "Pinbereich"}
|
||||
)
|
||||
msp.add_entity(Line1)
|
||||
msp.add_entity(Line2)
|
||||
|
||||
@@ -191,12 +218,14 @@ class Kreisel(BaseModel):
|
||||
msp.add_line(p1a, p2a)
|
||||
msp.add_line(p1b, p2b)
|
||||
|
||||
def draw_kreisel_drehrichtung_markierung(msp, pos1, pos2, kreisel, lib_doc, doc, verbose):
|
||||
def draw_kreisel_drehrichtung_markierung(
|
||||
msp, pos1, pos2, kreisel, lib_doc, doc, verbose
|
||||
):
|
||||
drehrichtung = (kreisel.drehrichtung or "").upper()
|
||||
if drehrichtung not in ("UZS", "GUZS"):
|
||||
return
|
||||
x1, y1,z1= pos1
|
||||
x2, y2,z2 = pos2
|
||||
x1, y1, z1 = pos1
|
||||
x2, y2, z2 = pos2
|
||||
dx = x2 - x1
|
||||
dy = y2 - y1
|
||||
length = math.hypot(dx, dy)
|
||||
@@ -216,24 +245,44 @@ class Kreisel(BaseModel):
|
||||
t = i / 4 # 1/4, 2/4, 3/4
|
||||
px = p1_oben[0] + t * (p2_oben[0] - p1_oben[0])
|
||||
py = p1_oben[1] + t * (p2_oben[1] - p1_oben[1])
|
||||
rotation = math.degrees(math.atan2(p2_oben[1] - p1_oben[1], p2_oben[0] - p1_oben[0]))
|
||||
rotation = math.degrees(
|
||||
math.atan2(p2_oben[1] - p1_oben[1], p2_oben[0] - p1_oben[0])
|
||||
)
|
||||
if drehrichtung == "GUZS":
|
||||
rotation += 180
|
||||
block_methoden.import_block("Richtungspfeil", lib_doc, doc)
|
||||
blockref_layer, color = block_methoden.get_insert_color_layer(lib_doc, "Richtungspfeil")
|
||||
bref = msp.add_blockref("Richtungspfeil", (px, py,z1), dxfattribs={"rotation": rotation,"layer": blockref_layer})
|
||||
blockref_layer, color = block_methoden.get_insert_color_layer(
|
||||
lib_doc, "Richtungspfeil"
|
||||
)
|
||||
bref = msp.add_blockref(
|
||||
"Richtungspfeil",
|
||||
(px, py, z1),
|
||||
dxfattribs={"rotation": rotation, "layer": blockref_layer},
|
||||
)
|
||||
if verbose:
|
||||
print(f"[INFO] Drehrichtung '{drehrichtung}': Richtungspfeil oben bei ({px:.1f}, {py:.1f}), rot={rotation:.1f}")
|
||||
print(
|
||||
f"[INFO] Drehrichtung '{drehrichtung}': Richtungspfeil oben bei ({px:.1f}, {py:.1f}), rot={rotation:.1f}"
|
||||
)
|
||||
# S-LP auf unterer Linie (Drehrichtung invertiert)
|
||||
for i in range(1, 4):
|
||||
t = i / 4
|
||||
px = p1_unten[0] + t * (p2_unten[0] - p1_unten[0])
|
||||
py = p1_unten[1] + t * (p2_unten[1] - p1_unten[1])
|
||||
rotation = math.degrees(math.atan2(p2_unten[1] - p1_unten[1], p2_unten[0] - p1_unten[0]))
|
||||
rotation = math.degrees(
|
||||
math.atan2(p2_unten[1] - p1_unten[1], p2_unten[0] - p1_unten[0])
|
||||
)
|
||||
if drehrichtung == "UZS":
|
||||
rotation += 180
|
||||
block_methoden.import_block("Richtungspfeil", lib_doc, doc)
|
||||
blockref_layer, color = block_methoden.get_insert_color_layer( lib_doc, "Richtungspfeil")
|
||||
bref = msp.add_blockref("Richtungspfeil", (px, py, z1), dxfattribs={"rotation": rotation , "layer": blockref_layer})
|
||||
blockref_layer, color = block_methoden.get_insert_color_layer(
|
||||
lib_doc, "Richtungspfeil"
|
||||
)
|
||||
bref = msp.add_blockref(
|
||||
"Richtungspfeil",
|
||||
(px, py, z1),
|
||||
dxfattribs={"rotation": rotation, "layer": blockref_layer},
|
||||
)
|
||||
if verbose:
|
||||
print(f"[INFO] Drehrichtung '{drehrichtung}':Richtungspfeil unten bei ({px:.1f}, {py:.1f}), rot={rotation:.1f}")
|
||||
print(
|
||||
f"[INFO] Drehrichtung '{drehrichtung}':Richtungspfeil unten bei ({px:.1f}, {py:.1f}), rot={rotation:.1f}"
|
||||
)
|
||||
|
||||
+47
-38
@@ -1,31 +1,37 @@
|
||||
|
||||
from ezdxf.entities import Line
|
||||
import math
|
||||
from pydantic import BaseModel, Field, field_validator
|
||||
from typing import Optional
|
||||
import plant2dxf
|
||||
import block_methoden
|
||||
|
||||
|
||||
class Omniflo(BaseModel):
|
||||
teileid:str
|
||||
x:float
|
||||
y:float
|
||||
sivasnummer:str
|
||||
laenge: Optional [float]
|
||||
teileid: str
|
||||
x: float
|
||||
y: float
|
||||
sivasnummer: str
|
||||
laenge: Optional[float]
|
||||
drehung: float
|
||||
hoehe : Optional[float]
|
||||
h0: Optional[float] = Field(default = 0.0,description="Höhe unten im CSV")
|
||||
h1: Optional[float] = Field(default = 0.0, description="Höhe Oben im CSV")
|
||||
anzahl_scanner: Optional [int] = Field(default=0, description="Anzahl der Scanner")
|
||||
anzahl_stopper: Optional [int] = Field(default=0, description="Anzahl der Separatoren")
|
||||
hoehe: Optional[float]
|
||||
h0: Optional[float] = Field(default=0.0, description="Höhe unten im CSV")
|
||||
h1: Optional[float] = Field(default=0.0, description="Höhe Oben im CSV")
|
||||
anzahl_scanner: Optional[int] = Field(default=0, description="Anzahl der Scanner")
|
||||
anzahl_stopper: Optional[int] = Field(
|
||||
default=0, description="Anzahl der Separatoren"
|
||||
)
|
||||
|
||||
@property
|
||||
def hight_zwischen(self):
|
||||
return ((self.h0 + self.h1) /2)
|
||||
return (self.h0 + self.h1) / 2
|
||||
|
||||
@classmethod
|
||||
def from_merkmale(cls, teileid,x,y, merkmale):
|
||||
def from_merkmale(cls, teileid, x, y, merkmale):
|
||||
sivasnummer = merkmale.get("SivasNummer")
|
||||
try:
|
||||
laenge = float(merkmale.get("Länge in Meter", "0").replace(",", ".")) * 1000 # Meter → mm
|
||||
laenge = (
|
||||
float(merkmale.get("Länge in Meter", "0").replace(",", ".")) * 1000
|
||||
) # Meter → mm
|
||||
except Exception:
|
||||
laenge = 0
|
||||
try:
|
||||
@@ -53,18 +59,19 @@ class Omniflo(BaseModel):
|
||||
except Exception:
|
||||
anzahl_separatoren = 0
|
||||
return cls(
|
||||
teileid= teileid,
|
||||
teileid=teileid,
|
||||
x=x,
|
||||
y=y,
|
||||
sivasnummer = sivasnummer,
|
||||
laenge = laenge,
|
||||
drehung = winkel,
|
||||
hoehe = hoehe,
|
||||
h0 = h0,
|
||||
h1 = h1,
|
||||
anzahl_scanner = anzahl_scanner,
|
||||
anzahl_stopper = anzahl_separatoren
|
||||
sivasnummer=sivasnummer,
|
||||
laenge=laenge,
|
||||
drehung=winkel,
|
||||
hoehe=hoehe,
|
||||
h0=h0,
|
||||
h1=h1,
|
||||
anzahl_scanner=anzahl_scanner,
|
||||
anzahl_stopper=anzahl_separatoren,
|
||||
)
|
||||
|
||||
def Omniflo_geraden_erstellung(msp, doc, tefsivas, omniflo_objekt):
|
||||
"""Erstellung der Tef gerade und Omniflo gerade"""
|
||||
winkel_rad = math.radians(omniflo_objekt.drehung)
|
||||
@@ -74,21 +81,22 @@ class Omniflo(BaseModel):
|
||||
# Man muss bei sin -1 machen wegen des links koordinaten system
|
||||
dx = halbe_laenge * math.sin(winkel_rad * -1)
|
||||
dy = halbe_laenge * math.cos(winkel_rad)
|
||||
start = (x + dx, y + dy, omniflo_objekt.h1 )
|
||||
start = (x + dx, y + dy, omniflo_objekt.h1)
|
||||
ende = (x - dx, y - dy, omniflo_objekt.h0)
|
||||
if "A-2" not in doc.layers:
|
||||
doc.layers.add(name="A-2", color=2)
|
||||
if "F-1" not in doc.layers:
|
||||
doc.layers.add(name="F-1", color =1)
|
||||
linie=msp.add_line(start, ende)
|
||||
doc.layers.add(name="F-1", color=1)
|
||||
linie = msp.add_line(start, ende)
|
||||
if omniflo_objekt.sivasnummer == tefsivas:
|
||||
linie.dxf.layer = "F-1"
|
||||
else:
|
||||
linie.dxf.layer = "A-2"
|
||||
|
||||
def omniflo_foerdererstellung(msp, doc, lib_doc, omniflo_objekt):
|
||||
""""Erstellung des Kettenförderers aktuell nur grundriss"""
|
||||
block_methoden.import_block("bogen1",lib_doc,doc)
|
||||
block_methoden.import_block("bogen2",lib_doc,doc)
|
||||
""" "Erstellung des Kettenförderers aktuell nur grundriss"""
|
||||
block_methoden.import_block("bogen1", lib_doc, doc)
|
||||
block_methoden.import_block("bogen2", lib_doc, doc)
|
||||
x = omniflo_objekt.x
|
||||
y = omniflo_objekt.y
|
||||
rotation = omniflo_objekt.drehung
|
||||
@@ -96,21 +104,22 @@ class Omniflo(BaseModel):
|
||||
h0 = omniflo_objekt.h0
|
||||
h1 = omniflo_objekt.h1
|
||||
h_zwischen = omniflo_objekt.hight_zwischen
|
||||
blockname = (f"OF_Förderer_{laenge}_{h_zwischen}")
|
||||
blockname = f"OF_Förderer_{laenge}_{h_zwischen}"
|
||||
winkel_rad = math.radians(rotation)
|
||||
halbe_laenge = laenge / 2
|
||||
# Man muss bei sin -1 machen wegen des links koordinaten system
|
||||
dx = halbe_laenge * math.sin(rotation * -1)
|
||||
dy = halbe_laenge * math.cos(rotation)
|
||||
start = (x + dx, y + dy, h1 )
|
||||
start = (x + dx, y + dy, h1)
|
||||
ende = (x - dx, y - dy, h0)
|
||||
if blockname not in doc.blocks:
|
||||
block = doc.blocks.new(blockname, base_point=(0,0,0))
|
||||
block.add_blockref("bogen1",start)
|
||||
block.add_blockref("bogen2",ende)
|
||||
line = Line.new(dxfattribs={"start": start,"end":ende})
|
||||
block = doc.blocks.new(blockname, base_point=(0, 0, 0))
|
||||
block.add_blockref("bogen1", start)
|
||||
block.add_blockref("bogen2", ende)
|
||||
line = Line.new(dxfattribs={"start": start, "end": ende})
|
||||
copy = line.copy()
|
||||
copy.translate(-x,-y,-h_zwischen)
|
||||
copy.translate(-x, -y, -h_zwischen)
|
||||
block.add_entity(copy)
|
||||
msp.add_blockref(blockname,(x,y,h_zwischen),dxfattribs={"rotation": rotation})
|
||||
|
||||
msp.add_blockref(
|
||||
blockname, (x, y, h_zwischen), dxfattribs={"rotation": rotation}
|
||||
)
|
||||
|
||||
+1245
-384
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@ import re
|
||||
import configparser
|
||||
from pathlib import Path
|
||||
from utils import check_environment_var, setup_logger
|
||||
from Elemente import Kreisel, VarioFoerderer,Gefaehllestrecke,Angetriebene_Kurve,Bt_element,Omniflo, Eckrad
|
||||
from Elemente import Kreisel, VarioFoerderer,Gefaellestrecke,Angetriebene_Kurve,Bt_element,Omniflo, Eckrad
|
||||
# --------------------------------------------------------- CFG-Leser für shapes.cfg
|
||||
def get_shape_cfg(teileart, cfg_path, logger=None):
|
||||
parser = configparser.ConfigParser()
|
||||
|
||||
+701
-293
File diff suppressed because it is too large
Load Diff
+82
-40
@@ -3,22 +3,32 @@ import plant2dxf
|
||||
from ezdxf import units
|
||||
from ezdxf.entities import Line
|
||||
from ezdxf.addons import importer
|
||||
from ezdxf.math import Matrix44, X_AXIS,Y_AXIS,Z_AXIS
|
||||
def dreh_block(block_name: str, to_doc,lib_doc, winkel) :
|
||||
"""Nimmt ein schon importierten Block und erstellt einen neuen der an der y_axis oder x_axis gedreht wird
|
||||
"""
|
||||
dreh_block_name = block_name +f"_{math.degrees(winkel)}"
|
||||
layer, color = get_insert_color_layer(lib_doc,block_name)
|
||||
if (dreh_block_name in to_doc.blocks):
|
||||
from ezdxf.math import Matrix44, X_AXIS, Y_AXIS, Z_AXIS
|
||||
|
||||
|
||||
def dreh_block(block_name: str, to_doc, lib_doc, winkel):
|
||||
"""Nimmt ein schon importierten Block und erstellt einen neuen der an der y_axis oder x_axis gedreht wird"""
|
||||
dreh_block_name = block_name + f"_{math.degrees(winkel)}"
|
||||
layer, color = get_insert_color_layer(lib_doc, block_name)
|
||||
if dreh_block_name in to_doc.blocks:
|
||||
return dreh_block_name
|
||||
block_zwischen = to_doc.blocks.new(name=block_name + f"zwischenschrit_{winkel}", base_point=(0,0,0))
|
||||
block = to_doc.blocks.new(name=dreh_block_name, base_point=(0,0,0))
|
||||
if block_name == "200000146_ES-Element_90_rechts" or block_name =="400102632_ES-Element_90_links" or block_name =="200000241_AS-Element_90_rechts" or block_name =="200000217_AS-Element_90_links":
|
||||
block_zwischen = to_doc.blocks.new(
|
||||
name=block_name + f"zwischenschrit_{winkel}", base_point=(0, 0, 0)
|
||||
)
|
||||
block = to_doc.blocks.new(name=dreh_block_name, base_point=(0, 0, 0))
|
||||
if (
|
||||
block_name == "200000146_ES-Element_90_rechts"
|
||||
or block_name == "400102632_ES-Element_90_links"
|
||||
or block_name == "200000241_AS-Element_90_rechts"
|
||||
or block_name == "200000217_AS-Element_90_links"
|
||||
):
|
||||
rotation_matrix = Matrix44.axis_rotate(X_AXIS, winkel)
|
||||
else:
|
||||
rotation_matrix = Matrix44.axis_rotate(Y_AXIS, winkel)
|
||||
|
||||
block_zwischen.add_blockref(block_name,(0,0,0),dxfattribs={"layer":layer,"color": color})
|
||||
block_zwischen.add_blockref(
|
||||
block_name, (0, 0, 0), dxfattribs={"layer": layer, "color": color}
|
||||
)
|
||||
for e in block_zwischen:
|
||||
copy = e.copy()
|
||||
copy.transform(rotation_matrix)
|
||||
@@ -26,7 +36,7 @@ def dreh_block(block_name: str, to_doc,lib_doc, winkel) :
|
||||
return dreh_block_name
|
||||
|
||||
|
||||
def import_block(block_name: str, from_doc, to_doc, winkel = None) -> None:
|
||||
def import_block(block_name: str, from_doc, to_doc, winkel=None) -> None:
|
||||
"""Importiert Blockdefinition block_name von from_doc nach to_doc.
|
||||
|
||||
- Kopiert alle Entities des Blocks
|
||||
@@ -41,16 +51,16 @@ def import_block(block_name: str, from_doc, to_doc, winkel = None) -> None:
|
||||
|
||||
# Alle Linientypen importieren
|
||||
imp.import_table("linetypes")
|
||||
if ((block_name in to_doc.blocks)):
|
||||
if block_name in to_doc.blocks:
|
||||
# speichern der attdef elemente in eine Liste falks diese verhanden sind und gibt diese zurück
|
||||
for ent in src:
|
||||
copy = ent.copy()
|
||||
|
||||
if ent.dxftype() == "ATTDEF":
|
||||
att_def[ent.dxf.tag] =ent.dxf.text
|
||||
att_def[ent.dxf.tag] = ent.dxf.text
|
||||
if ent.dxftype() == "INSERT":
|
||||
|
||||
import_block(ent.dxf.name,from_doc, to_doc,None)
|
||||
import_block(ent.dxf.name, from_doc, to_doc, None)
|
||||
|
||||
if att_def != {}:
|
||||
return att_def
|
||||
@@ -92,14 +102,15 @@ def import_block(block_name: str, from_doc, to_doc, winkel = None) -> None:
|
||||
copy = ent.copy()
|
||||
|
||||
if ent.dxftype() == "ATTDEF":
|
||||
att_def[ent.dxf.tag] =ent.dxf.text
|
||||
att_def[ent.dxf.tag] = ent.dxf.text
|
||||
if ent.dxftype() == "INSERT":
|
||||
import_block(ent.dxf.name,from_doc, to_doc,None)
|
||||
import_block(ent.dxf.name, from_doc, to_doc, None)
|
||||
tgt.add_entity(copy)
|
||||
|
||||
if att_def != {}:
|
||||
return att_def
|
||||
|
||||
|
||||
def get_insert_color_layer(lib_doc, blockname):
|
||||
"""Gibt den Layer und die Color für den Jeweiligen block in der Libary datei zurück"""
|
||||
msp_lib = lib_doc.modelspace()
|
||||
@@ -111,34 +122,65 @@ def get_insert_color_layer(lib_doc, blockname):
|
||||
layer = insert.dxf.layer
|
||||
return layer, color
|
||||
|
||||
def rotatate_and_left_motor_umlenk(doc, lib_doc,config):
|
||||
motor_rotation = float(config.get("Ils 2.0 core winkel","winkel_motor"))
|
||||
umlenk_rotation = float(config.get("Ils 2.0 core winkel","winkel_umlenk"))
|
||||
block_Vario_Umlenkstation_500mm ="Vario_Umlenkstation_500mm"
|
||||
|
||||
def rotatate_and_left_motor_umlenk(doc, lib_doc, config):
|
||||
motor_rotation = float(config.get("Ils 2.0 core winkel", "winkel_motor"))
|
||||
umlenk_rotation = float(config.get("Ils 2.0 core winkel", "winkel_umlenk"))
|
||||
block_Vario_Umlenkstation_500mm = "Vario_Umlenkstation_500mm"
|
||||
block_Vario_Motorstation_500mm = "Vario_Motorstation_500mm"
|
||||
blockname_motor_links = block_Vario_Motorstation_500mm +"_links"
|
||||
blockname_motor_links = block_Vario_Motorstation_500mm + "_links"
|
||||
blockname_umlenk_links = block_Vario_Umlenkstation_500mm + "_links"
|
||||
import_block(block_Vario_Umlenkstation_500mm,lib_doc,doc)
|
||||
import_block(block_Vario_Motorstation_500mm,lib_doc,doc)
|
||||
turn_two_blocks_left(doc, block_Vario_Umlenkstation_500mm, block_Vario_Motorstation_500mm, blockname_motor_links, blockname_umlenk_links)
|
||||
import_block(block_Vario_Umlenkstation_500mm, lib_doc, doc)
|
||||
import_block(block_Vario_Motorstation_500mm, lib_doc, doc)
|
||||
turn_two_blocks_left(
|
||||
doc,
|
||||
block_Vario_Umlenkstation_500mm,
|
||||
block_Vario_Motorstation_500mm,
|
||||
blockname_motor_links,
|
||||
blockname_umlenk_links,
|
||||
)
|
||||
|
||||
block_Vario_Umlenkstation_500mm =dreh_block(block_Vario_Umlenkstation_500mm,doc,lib_doc,math.radians(umlenk_rotation))
|
||||
block_Vario_Motorstation_500mm =dreh_block(block_Vario_Motorstation_500mm,doc,lib_doc,math.radians(motor_rotation))
|
||||
blockname_motor_links =dreh_block(blockname_motor_links,doc,lib_doc,math.radians(umlenk_rotation))
|
||||
blockname_umlenk_links =dreh_block(blockname_umlenk_links,doc,lib_doc,math.radians(motor_rotation))
|
||||
return block_Vario_Umlenkstation_500mm,block_Vario_Motorstation_500mm,blockname_motor_links,blockname_umlenk_links
|
||||
block_Vario_Umlenkstation_500mm = dreh_block(
|
||||
block_Vario_Umlenkstation_500mm, doc, lib_doc, math.radians(umlenk_rotation)
|
||||
)
|
||||
block_Vario_Motorstation_500mm = dreh_block(
|
||||
block_Vario_Motorstation_500mm, doc, lib_doc, math.radians(motor_rotation)
|
||||
)
|
||||
blockname_motor_links = dreh_block(
|
||||
blockname_motor_links, doc, lib_doc, math.radians(umlenk_rotation)
|
||||
)
|
||||
blockname_umlenk_links = dreh_block(
|
||||
blockname_umlenk_links, doc, lib_doc, math.radians(motor_rotation)
|
||||
)
|
||||
return (
|
||||
block_Vario_Umlenkstation_500mm,
|
||||
block_Vario_Motorstation_500mm,
|
||||
blockname_motor_links,
|
||||
blockname_umlenk_links,
|
||||
)
|
||||
|
||||
def turn_two_blocks_left(doc, block_1_name_zwischen, block_2_name_zwischen, block_2_left_name, block_1_left_name):
|
||||
|
||||
def turn_two_blocks_left(
|
||||
doc,
|
||||
block_1_name_zwischen,
|
||||
block_2_name_zwischen,
|
||||
block_2_left_name,
|
||||
block_1_left_name,
|
||||
):
|
||||
blockname1 = block_1_name_zwischen
|
||||
blockname2 = block_2_name_zwischen
|
||||
if block_2_left_name not in doc.blocks:
|
||||
matrix = Matrix44.scale(1,-1,1)
|
||||
block1_zwischen = doc.blocks.new(name=block_1_name_zwischen + "zwischenschrit", base_point=(0,0,0))
|
||||
block2_zwischen = doc.blocks.new(name=block_2_name_zwischen + "zwischenschrit", base_point=(0,0,0))
|
||||
block_2 = doc.blocks.new(name=block_2_left_name,base_point=(0,0,0))
|
||||
block_1_left_name = doc.blocks.new(name=block_1_left_name,base_point=(0,0,0))
|
||||
block1_zwischen.add_blockref(blockname1,(0,0,0))
|
||||
block2_zwischen.add_blockref(blockname2,(0,0,0))
|
||||
matrix = Matrix44.scale(1, -1, 1)
|
||||
block1_zwischen = doc.blocks.new(
|
||||
name=block_1_name_zwischen + "zwischenschrit", base_point=(0, 0, 0)
|
||||
)
|
||||
block2_zwischen = doc.blocks.new(
|
||||
name=block_2_name_zwischen + "zwischenschrit", base_point=(0, 0, 0)
|
||||
)
|
||||
block_2 = doc.blocks.new(name=block_2_left_name, base_point=(0, 0, 0))
|
||||
block_1_left_name = doc.blocks.new(name=block_1_left_name, base_point=(0, 0, 0))
|
||||
block1_zwischen.add_blockref(blockname1, (0, 0, 0))
|
||||
block2_zwischen.add_blockref(blockname2, (0, 0, 0))
|
||||
for e in block2_zwischen:
|
||||
copy = e.copy()
|
||||
copy.transform(matrix)
|
||||
@@ -149,8 +191,8 @@ def turn_two_blocks_left(doc, block_1_name_zwischen, block_2_name_zwischen, bloc
|
||||
copy.transform(matrix)
|
||||
block_1_left_name.add_entity(copy)
|
||||
|
||||
def add_attributes_to_block(block, attributes):
|
||||
|
||||
def add_attributes_to_block(block, attributes):
|
||||
"""
|
||||
Fügt einem bestehenden ezdxf-Block Attribut-Definitionen hinzu.
|
||||
|
||||
@@ -161,7 +203,7 @@ def add_attributes_to_block(block, attributes):
|
||||
for tag, value in attributes.items():
|
||||
tag = tag
|
||||
value = value
|
||||
a =block.add_attrib(
|
||||
a = block.add_attrib(
|
||||
tag=tag,
|
||||
text=value,
|
||||
)
|
||||
|
||||
+164
-90
@@ -4,12 +4,12 @@ from ezdxf.math import Matrix44, Vec3, BoundingBox, Vec2
|
||||
import math
|
||||
import argparse
|
||||
import sys
|
||||
import shutil
|
||||
import configparser
|
||||
from utils import check_environment_var, setup_logger
|
||||
from pathlib import Path
|
||||
import logging
|
||||
|
||||
|
||||
def create_block_library(input_dir, output_file, config, logger=None):
|
||||
"""
|
||||
Erstellt eine DXF-Block-Bibliothek aus einzelnen DXF-Dateien.
|
||||
@@ -79,22 +79,21 @@ def create_block_library(input_dir, output_file, config, logger=None):
|
||||
"REGION",
|
||||
}
|
||||
filtered_entities = []
|
||||
att_def= {}
|
||||
att_def = {}
|
||||
for insert in src_msp.query("INSERT"):
|
||||
for attrib in insert.attribs:
|
||||
att_def[attrib.dxf.tag] = attrib.dxf.text
|
||||
|
||||
|
||||
for e in entities:
|
||||
if e.dxftype() in allowed_types:
|
||||
filtered_entities.append(e)
|
||||
else:
|
||||
logger.info(f"{e.dxftype()} is nicht in der erlaubten Liste. Diese befindet sich in {filename}")
|
||||
|
||||
logger.info(
|
||||
f"{e.dxftype()} is nicht in der erlaubten Liste. Diese befindet sich in {filename}"
|
||||
)
|
||||
|
||||
entities = filtered_entities
|
||||
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Fehler beim Lesen von {filename}: {e}"
|
||||
if logger:
|
||||
@@ -106,7 +105,9 @@ def create_block_library(input_dir, output_file, config, logger=None):
|
||||
|
||||
# Sicherstellen, dass die im Quell-DXF verwendeten Layer im Zieldokument existieren
|
||||
try:
|
||||
used_layer_names = {e.dxf.layer for e in entities if hasattr(e.dxf, "layer")}
|
||||
used_layer_names = {
|
||||
e.dxf.layer for e in entities if hasattr(e.dxf, "layer")
|
||||
}
|
||||
for layer_name in used_layer_names:
|
||||
if layer_name and layer_name not in doc.layers:
|
||||
try:
|
||||
@@ -123,7 +124,9 @@ def create_block_library(input_dir, output_file, config, logger=None):
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
boundingbox, ausdehnung, center = calculate_block_bounding_box(filtered_entities, doc,src_doc, filename,config)
|
||||
boundingbox, ausdehnung, center = calculate_block_bounding_box(
|
||||
filtered_entities, doc, src_doc, filename, config
|
||||
)
|
||||
if center is None:
|
||||
error_msg = f"Keine gültige Geometrie in {filename}"
|
||||
if logger:
|
||||
@@ -136,7 +139,7 @@ def create_block_library(input_dir, output_file, config, logger=None):
|
||||
if name in doc.blocks:
|
||||
doc.blocks.delete_block(name)
|
||||
|
||||
blk = doc.blocks.new(name=name, base_point=(0,0))
|
||||
blk = doc.blocks.new(name=name, base_point=(0, 0))
|
||||
|
||||
for e in entities:
|
||||
cp = copy_entity(logger, error_files, filename, e, center)
|
||||
@@ -146,11 +149,10 @@ def create_block_library(input_dir, output_file, config, logger=None):
|
||||
# Platzierung in Reihen und Spalten
|
||||
# Attribut-Definition (ATTDEF) hinzufügen
|
||||
|
||||
|
||||
# Blockreferenz-Layer bestimmen
|
||||
blockref_layer = None
|
||||
try:
|
||||
#Konfiguration erlaubt expliziten Layernamen
|
||||
# Konfiguration erlaubt expliziten Layernamen
|
||||
cfg_layer = None
|
||||
try:
|
||||
cfg_layer = config.get("dxf2lib", "blockref_layer")
|
||||
@@ -186,9 +188,15 @@ def create_block_library(input_dir, output_file, config, logger=None):
|
||||
blockref_layer = None
|
||||
section = "dxf2lib"
|
||||
text_height = get_cfg_value(section, "text_height", DEFAULTS["text_height"])
|
||||
extra_block_space_x = get_cfg_value(section, "extra_block_space_x", DEFAULTS["extra_block_space_x"])
|
||||
blocks_per_row = get_cfg_value(section, "blocks_per_row", DEFAULTS["blocks_per_row"])
|
||||
extra_text_space_y = get_cfg_value(section, "extra_text_space_y", DEFAULTS["extra_text_space_y"])
|
||||
extra_block_space_x = get_cfg_value(
|
||||
section, "extra_block_space_x", DEFAULTS["extra_block_space_x"]
|
||||
)
|
||||
blocks_per_row = get_cfg_value(
|
||||
section, "blocks_per_row", DEFAULTS["blocks_per_row"]
|
||||
)
|
||||
extra_text_space_y = get_cfg_value(
|
||||
section, "extra_text_space_y", DEFAULTS["extra_text_space_y"]
|
||||
)
|
||||
|
||||
ausdehnung_x, ausdehung_y = ausdehnung[0], ausdehnung[1]
|
||||
|
||||
@@ -199,23 +207,34 @@ def create_block_library(input_dir, output_file, config, logger=None):
|
||||
x_offset += max_blockspacing_x
|
||||
# Blockreferenz mit optionalem Layer einfügen (Entity-Layer bleiben erhalten)
|
||||
if blockref_layer:
|
||||
test =msp.add_blockref(name, insert=(x_offset, y_offset), dxfattribs={"layer": blockref_layer})
|
||||
test = msp.add_blockref(
|
||||
name, insert=(x_offset, y_offset), dxfattribs={"layer": blockref_layer}
|
||||
)
|
||||
else:
|
||||
test =msp.add_blockref(name, insert=(x_offset, y_offset))
|
||||
test = msp.add_blockref(name, insert=(x_offset, y_offset))
|
||||
# Text mit Blocknamen über dem Block
|
||||
if name == "a" or name == "b":
|
||||
for tag, value in att_def.items():
|
||||
|
||||
tag = tag
|
||||
value = value
|
||||
a =test.add_attrib(
|
||||
a = test.add_attrib(
|
||||
tag=tag,
|
||||
text=value,
|
||||
)
|
||||
a.is_invisible = True
|
||||
# Werte aus Config holen (Block: [dxf2lib])
|
||||
|
||||
msp.add_text(name, dxfattribs={'height': text_height, 'insert': (x_offset -ausdehnung_x/2 , y_offset + ausdehung_y/2 + extra_text_space_y)})
|
||||
msp.add_text(
|
||||
name,
|
||||
dxfattribs={
|
||||
"height": text_height,
|
||||
"insert": (
|
||||
x_offset - ausdehnung_x / 2,
|
||||
y_offset + ausdehung_y / 2 + extra_text_space_y,
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
processed_files.append(filename)
|
||||
blocks_in_row += 1
|
||||
@@ -234,7 +253,9 @@ def create_block_library(input_dir, output_file, config, logger=None):
|
||||
logger.info(f"Fehlerhafte Dateien: {len(error_files)}")
|
||||
|
||||
if error_files:
|
||||
logger.warning(f"{len(error_files)} Dateien konnten nicht verarbeitet werden:")
|
||||
logger.warning(
|
||||
f"{len(error_files)} Dateien konnten nicht verarbeitet werden:"
|
||||
)
|
||||
for filename, error_msg in error_files:
|
||||
logger.error(f"{filename}: {error_msg}")
|
||||
else:
|
||||
@@ -245,7 +266,9 @@ def create_block_library(input_dir, output_file, config, logger=None):
|
||||
print(f"Fehlerhafte Dateien: {len(error_files)}")
|
||||
|
||||
if error_files:
|
||||
print(f"Warnung: {len(error_files)} Dateien konnten nicht verarbeitet werden.")
|
||||
print(
|
||||
f"Warnung: {len(error_files)} Dateien konnten nicht verarbeitet werden."
|
||||
)
|
||||
|
||||
output_dir = output_file.parent
|
||||
if not output_dir.exists():
|
||||
@@ -267,7 +290,9 @@ def copy_entity(logger, error_files, filename, e, center):
|
||||
return cp
|
||||
|
||||
except Exception as err:
|
||||
error_msg = f"Fehler beim Verarbeiten von Entity {e.dxftype()} in {filename}: {err}"
|
||||
error_msg = (
|
||||
f"Fehler beim Verarbeiten von Entity {e.dxftype()} in {filename}: {err}"
|
||||
)
|
||||
if logger:
|
||||
logger.error(error_msg)
|
||||
else:
|
||||
@@ -276,15 +301,15 @@ def copy_entity(logger, error_files, filename, e, center):
|
||||
return None
|
||||
|
||||
|
||||
|
||||
# Standardwerte (falls nicht in der Config)
|
||||
DEFAULTS = {
|
||||
"text_height": 20, # Schriftgröße des Texts (in DXF-Einheiten)
|
||||
"blocks_per_row": 20, # Anzahl Blöcke pro Zeile im Raster
|
||||
"extra_block_space_x" : 50, # Extra Platz damit sich Blöcke nicht überlappen
|
||||
"extra_text_space_y" : 50 # Abstand der Überschrift über dem Symbol
|
||||
|
||||
"extra_block_space_x": 50, # Extra Platz damit sich Blöcke nicht überlappen
|
||||
"extra_text_space_y": 50, # Abstand der Überschrift über dem Symbol
|
||||
}
|
||||
|
||||
|
||||
def get_cfg_value(section, key, fallback):
|
||||
try:
|
||||
return int(config.get(section, key))
|
||||
@@ -292,9 +317,9 @@ def get_cfg_value(section, key, fallback):
|
||||
return fallback
|
||||
|
||||
|
||||
|
||||
|
||||
def convert_dxf_to_block_with_inserts(input_filename, output_filename, block_name="CONVERTED_BLOCK"):
|
||||
def convert_dxf_to_block_with_inserts(
|
||||
input_filename, output_filename, block_name="CONVERTED_BLOCK"
|
||||
):
|
||||
"""
|
||||
Konvertiert alle Entities einer DXF-Datei in einen neuen Block
|
||||
INSERTs werden als Referenzen beibehalten (nicht explodiert)
|
||||
@@ -305,8 +330,8 @@ def convert_dxf_to_block_with_inserts(input_filename, output_filename, block_nam
|
||||
print(f"Lade DXF-Datei: {input_filename}")
|
||||
|
||||
# Neue Ausgabe-DXF erstellen
|
||||
output_doc = ezdxf.new('R2010')
|
||||
output_doc.header['$INSUNITS'] = 4 # Millimeter
|
||||
output_doc = ezdxf.new("R2010")
|
||||
output_doc.header["$INSUNITS"] = 4 # Millimeter
|
||||
|
||||
# Zuerst alle Block-Definitionen kopieren
|
||||
copied_blocks = copy_block_definitions(input_doc, output_doc)
|
||||
@@ -322,7 +347,7 @@ def convert_dxf_to_block_with_inserts(input_filename, output_filename, block_nam
|
||||
insert_count = 0
|
||||
|
||||
for entity in msp:
|
||||
if entity.dxftype() == 'INSERT':
|
||||
if entity.dxftype() == "INSERT":
|
||||
# INSERT direkt kopieren (nicht explodieren)
|
||||
copy_entity_to_block(entity, new_block)
|
||||
insert_count += 1
|
||||
@@ -373,7 +398,7 @@ def copy_block_definitions(source_doc, target_doc):
|
||||
|
||||
for block_name in source_doc.blocks:
|
||||
# Standard-Blöcke (MODEL_SPACE, PAPER_SPACE) überspringen
|
||||
if block_name.startswith('*'):
|
||||
if block_name.startswith("*"):
|
||||
continue
|
||||
|
||||
source_block = source_doc.blocks[block_name]
|
||||
@@ -395,7 +420,7 @@ def copy_block_definitions(source_doc, target_doc):
|
||||
return copied_blocks
|
||||
|
||||
|
||||
def calculate_block_bounding_box(block, doc, src_doc, filename,config):
|
||||
def calculate_block_bounding_box(block, doc, src_doc, filename, config):
|
||||
"""
|
||||
Berechnet die Bounding Box eines Blocks inklusive aller INSERTs
|
||||
"""
|
||||
@@ -403,15 +428,20 @@ def calculate_block_bounding_box(block, doc, src_doc, filename,config):
|
||||
bbox = BoundingBox()
|
||||
|
||||
for entity in block:
|
||||
entity_bbox = get_entity_bounding_box(entity, doc,src_doc,filename,config)
|
||||
entity_bbox = get_entity_bounding_box(entity, doc, src_doc, filename, config)
|
||||
if entity_bbox and entity_bbox.has_data:
|
||||
bbox.extend(entity_bbox)
|
||||
|
||||
|
||||
return bbox, (bbox.extmax.x - bbox.extmin.x, bbox.extmax.y - bbox.extmin.y), bbox.center
|
||||
return (
|
||||
bbox,
|
||||
(bbox.extmax.x - bbox.extmin.x, bbox.extmax.y - bbox.extmin.y),
|
||||
bbox.center,
|
||||
)
|
||||
|
||||
|
||||
def _bbox_from_virtual_entities(entity, doc, src_doc, filename, config, transform_matrix=None):
|
||||
def _bbox_from_virtual_entities(
|
||||
entity, doc, src_doc, filename, config, transform_matrix=None
|
||||
):
|
||||
"""
|
||||
Nutzt virtual_entities(), um komplexe Objekte (z.B. SURFACE) in
|
||||
auswertbare Geometrie zu zerlegen und darauf eine Bounding Box zu
|
||||
@@ -432,7 +462,7 @@ def _bbox_from_virtual_entities(entity, doc, src_doc, filename, config, transfor
|
||||
return v_bbox
|
||||
|
||||
|
||||
def get_entity_bounding_box(e, doc,src_doc,filename,config, transform_matrix=None):
|
||||
def get_entity_bounding_box(e, doc, src_doc, filename, config, transform_matrix=None):
|
||||
"""
|
||||
Berechnet die Bounding Box einer einzelnen Entity
|
||||
Berücksichtigt INSERTs mit ihren Block-Inhalten
|
||||
@@ -440,7 +470,7 @@ def get_entity_bounding_box(e, doc,src_doc,filename,config, transform_matrix=Non
|
||||
|
||||
bbox = BoundingBox()
|
||||
try:
|
||||
if e.dxftype() == 'LINE':
|
||||
if e.dxftype() == "LINE":
|
||||
start = Vec3(e.dxf.start)
|
||||
end = Vec3(e.dxf.end)
|
||||
if transform_matrix:
|
||||
@@ -449,7 +479,7 @@ def get_entity_bounding_box(e, doc,src_doc,filename,config, transform_matrix=Non
|
||||
bbox.extend([start])
|
||||
bbox.extend([end])
|
||||
|
||||
elif e.dxftype() == 'CIRCLE':
|
||||
elif e.dxftype() == "CIRCLE":
|
||||
# Kreis durch Punktabtastung (robust bei Transformationen)
|
||||
center = Vec3(e.dxf.center)
|
||||
radius = float(e.dxf.radius)
|
||||
@@ -465,7 +495,7 @@ def get_entity_bounding_box(e, doc,src_doc,filename,config, transform_matrix=Non
|
||||
if points:
|
||||
bbox.extend(points)
|
||||
|
||||
elif e.dxftype() == 'ARC':
|
||||
elif e.dxftype() == "ARC":
|
||||
# Bogen durch Punktabtastung zwischen Start- und Endwinkel
|
||||
center = Vec3(e.dxf.center)
|
||||
radius = float(e.dxf.radius)
|
||||
@@ -496,7 +526,7 @@ def get_entity_bounding_box(e, doc,src_doc,filename,config, transform_matrix=Non
|
||||
if points:
|
||||
bbox.extend(points)
|
||||
|
||||
elif e.dxftype() == 'LWPOLYLINE':
|
||||
elif e.dxftype() == "LWPOLYLINE":
|
||||
# Nutze virtuelle Entities (Linien/Bögen), inkl. Bulge-Unterstützung
|
||||
ve_bbox = _bbox_from_virtual_entities(
|
||||
e, doc, src_doc, filename, config, transform_matrix
|
||||
@@ -504,7 +534,7 @@ def get_entity_bounding_box(e, doc,src_doc,filename,config, transform_matrix=Non
|
||||
if ve_bbox.has_data:
|
||||
bbox.extend(ve_bbox)
|
||||
|
||||
elif e.dxftype() == 'POLYLINE':
|
||||
elif e.dxftype() == "POLYLINE":
|
||||
# 2D/3D Polylines ebenfalls über virtuelle Entities
|
||||
ve_bbox = _bbox_from_virtual_entities(
|
||||
e, doc, src_doc, filename, config, transform_matrix
|
||||
@@ -512,7 +542,7 @@ def get_entity_bounding_box(e, doc,src_doc,filename,config, transform_matrix=Non
|
||||
if ve_bbox.has_data:
|
||||
bbox.extend(ve_bbox)
|
||||
|
||||
elif e.dxftype() == '3DFACE':
|
||||
elif e.dxftype() == "3DFACE":
|
||||
# 3DFace: direkte Eckpunkte verwenden
|
||||
pts = []
|
||||
try:
|
||||
@@ -527,7 +557,7 @@ def get_entity_bounding_box(e, doc,src_doc,filename,config, transform_matrix=Non
|
||||
if pts:
|
||||
bbox.extend(pts)
|
||||
|
||||
elif e.dxftype() in {'MESH', 'POLYFACE', 'POLYFACEMESH'}:
|
||||
elif e.dxftype() in {"MESH", "POLYFACE", "POLYFACEMESH"}:
|
||||
# Mesh/Polyface über virtuelle Geometrie auswerten
|
||||
ve_bbox = _bbox_from_virtual_entities(
|
||||
e, doc, src_doc, filename, config, transform_matrix
|
||||
@@ -535,7 +565,7 @@ def get_entity_bounding_box(e, doc,src_doc,filename,config, transform_matrix=Non
|
||||
if ve_bbox.has_data:
|
||||
bbox.extend(ve_bbox)
|
||||
|
||||
elif e.dxftype() == 'SPLINE':
|
||||
elif e.dxftype() == "SPLINE":
|
||||
# Approximation der Spline-Kurve
|
||||
try:
|
||||
pts = list(e.approximate(60))
|
||||
@@ -557,18 +587,20 @@ def get_entity_bounding_box(e, doc,src_doc,filename,config, transform_matrix=Non
|
||||
if sampled:
|
||||
bbox.extend(sampled)
|
||||
|
||||
elif e.dxftype() == 'ATTDEF':
|
||||
elif e.dxftype() == "ATTDEF":
|
||||
|
||||
insert_point = Vec3(e.dxf.insert)
|
||||
if transform_matrix:
|
||||
insert_point = transform_matrix.transform(insert_point)
|
||||
elif e.dxftype() == 'TEXT':
|
||||
elif e.dxftype() == "TEXT":
|
||||
insert_point = Vec3(e.dxf.insert)
|
||||
height = float(getattr(e.dxf, "height", 1.0))
|
||||
width_factor = float(getattr(e.dxf, "width", 1.0))
|
||||
rotation = math.radians(getattr(e.dxf, "rotation", 0.0))
|
||||
text_content = getattr(e.dxf, "text", "") or ""
|
||||
est_width = max(len(text_content) * height * 0.6 * width_factor, height * 0.5)
|
||||
est_width = max(
|
||||
len(text_content) * height * 0.6 * width_factor, height * 0.5
|
||||
)
|
||||
corners = [
|
||||
insert_point,
|
||||
insert_point + Vec3(est_width, 0, 0),
|
||||
@@ -590,7 +622,7 @@ def get_entity_bounding_box(e, doc,src_doc,filename,config, transform_matrix=Non
|
||||
pt = transform_matrix.transform(pt)
|
||||
bbox.extend([pt])
|
||||
|
||||
elif e.dxftype() == 'MTEXT':
|
||||
elif e.dxftype() == "MTEXT":
|
||||
insert_point = Vec3(e.dxf.insert)
|
||||
char_height = float(getattr(e.dxf, "char_height", 1.0))
|
||||
width = float(getattr(e.dxf, "width", 0.0))
|
||||
@@ -610,7 +642,7 @@ def get_entity_bounding_box(e, doc,src_doc,filename,config, transform_matrix=Non
|
||||
pt = transform_matrix.transform(pt)
|
||||
bbox.extend([pt])
|
||||
|
||||
elif e.dxftype() == 'REGION':
|
||||
elif e.dxftype() == "REGION":
|
||||
# Region: Begrenzungsgeometrie über virtual_entities()
|
||||
ve_bbox = _bbox_from_virtual_entities(
|
||||
e, doc, src_doc, filename, config, transform_matrix
|
||||
@@ -618,7 +650,7 @@ def get_entity_bounding_box(e, doc,src_doc,filename,config, transform_matrix=Non
|
||||
if ve_bbox.has_data:
|
||||
bbox.extend(ve_bbox)
|
||||
|
||||
elif e.dxftype().endswith('SURFACE'):
|
||||
elif e.dxftype().endswith("SURFACE"):
|
||||
# Viele Surface-Typen liefern ihre Proxy-Geometrie über virtual_entities()
|
||||
ve_bbox = _bbox_from_virtual_entities(
|
||||
e, doc, src_doc, filename, config, transform_matrix
|
||||
@@ -626,24 +658,36 @@ def get_entity_bounding_box(e, doc,src_doc,filename,config, transform_matrix=Non
|
||||
if ve_bbox.has_data:
|
||||
bbox.extend(ve_bbox)
|
||||
|
||||
elif e.dxftype() == 'INSERT':
|
||||
elif e.dxftype() == "INSERT":
|
||||
# INSERT: Block-Inhalt mit Transformation berücksichtigen
|
||||
insert_bbox = calculate_insert_bounding_box(e, doc,src_doc,filename,config, transform_matrix)
|
||||
if insert_bbox and insert_bbox.has_data and e.dxf.layer not in config.get("dxf2lib","automation_layer"):
|
||||
insert_bbox = calculate_insert_bounding_box(
|
||||
e, doc, src_doc, filename, config, transform_matrix
|
||||
)
|
||||
if (
|
||||
insert_bbox
|
||||
and insert_bbox.has_data
|
||||
and e.dxf.layer not in config.get("dxf2lib", "automation_layer")
|
||||
):
|
||||
bbox.extend(insert_bbox)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Fehler bei Bounding Box Berechnung für {e.dxftype()}: {e}")
|
||||
|
||||
|
||||
return bbox
|
||||
|
||||
def extract_scaling(matrix):
|
||||
sx = math.sqrt(matrix[0, 0]**2 + matrix[0, 1]**2 + matrix[0, 2]**2)
|
||||
sy = math.sqrt(matrix[1, 0]**2 + matrix[1, 1]**2 + matrix[1, 2]**2)
|
||||
return sx, sy,
|
||||
|
||||
def calculate_insert_bounding_box(insert_entity, doc,src_doc,filename,config,parent_transform=None):
|
||||
def extract_scaling(matrix):
|
||||
sx = math.sqrt(matrix[0, 0] ** 2 + matrix[0, 1] ** 2 + matrix[0, 2] ** 2)
|
||||
sy = math.sqrt(matrix[1, 0] ** 2 + matrix[1, 1] ** 2 + matrix[1, 2] ** 2)
|
||||
return (
|
||||
sx,
|
||||
sy,
|
||||
)
|
||||
|
||||
|
||||
def calculate_insert_bounding_box(
|
||||
insert_entity, doc, src_doc, filename, config, parent_transform=None
|
||||
):
|
||||
"""
|
||||
Berechnet die Bounding Box eines INSERTs inklusive Block-Inhalt
|
||||
"""
|
||||
@@ -667,7 +711,6 @@ def calculate_insert_bounding_box(insert_entity, doc,src_doc,filename,config,par
|
||||
|
||||
block_def = src_blk
|
||||
|
||||
|
||||
# Transformation der INSERT-Entity berechnen
|
||||
insert_transform = get_insert_transform_matrix(insert_entity)
|
||||
|
||||
@@ -682,7 +725,9 @@ def calculate_insert_bounding_box(insert_entity, doc,src_doc,filename,config,par
|
||||
|
||||
for block_entity in block_def:
|
||||
|
||||
entity_bbox= get_entity_bounding_box(block_entity, doc,src_doc,filename, config,combined_transform)
|
||||
entity_bbox = get_entity_bounding_box(
|
||||
block_entity, doc, src_doc, filename, config, combined_transform
|
||||
)
|
||||
if entity_bbox and entity_bbox.has_data:
|
||||
if new_insert:
|
||||
dst_blk.add_entity(block_entity.copy())
|
||||
@@ -703,18 +748,18 @@ def get_insert_transform_matrix(insert_entity):
|
||||
insert_point = Vec3(insert_entity.dxf.insert)
|
||||
|
||||
# Skalierung
|
||||
xscale = getattr(insert_entity.dxf, 'xscale', 1.0)
|
||||
yscale = getattr(insert_entity.dxf, 'yscale', 1.0)
|
||||
zscale = getattr(insert_entity.dxf, 'zscale', 1.0)
|
||||
xscale = getattr(insert_entity.dxf, "xscale", 1.0)
|
||||
yscale = getattr(insert_entity.dxf, "yscale", 1.0)
|
||||
zscale = getattr(insert_entity.dxf, "zscale", 1.0)
|
||||
|
||||
# Rotation (in Radiant umwandeln)
|
||||
rotation = math.radians(getattr(insert_entity.dxf, 'rotation', 0.0))
|
||||
rotation = math.radians(getattr(insert_entity.dxf, "rotation", 0.0))
|
||||
|
||||
# Transformationsmatrix erstellen
|
||||
matrix = Matrix44.chain(
|
||||
Matrix44.scale(xscale, yscale, zscale),
|
||||
Matrix44.z_rotate(rotation),
|
||||
Matrix44.translate(insert_point.x, insert_point.y, insert_point.z)
|
||||
Matrix44.translate(insert_point.x, insert_point.y, insert_point.z),
|
||||
)
|
||||
|
||||
return matrix
|
||||
@@ -759,11 +804,14 @@ def add_bounding_box_to_modelspace(msp, bbox, centered=False):
|
||||
(right, bottom),
|
||||
(right, top),
|
||||
(left, top),
|
||||
(left, bottom)
|
||||
(left, bottom),
|
||||
]
|
||||
# Roter Punkt in der Mitte
|
||||
msp.add_circle(center=(0.0, 0.0), radius=max(0.5, min(width, height) * 0.01),
|
||||
dxfattribs={"layer": "BOUNDING_BOX", "color": 1})
|
||||
msp.add_circle(
|
||||
center=(0.0, 0.0),
|
||||
radius=max(0.5, min(width, height) * 0.01),
|
||||
dxfattribs={"layer": "BOUNDING_BOX", "color": 1},
|
||||
)
|
||||
else:
|
||||
# Ursprüngliche, nicht-zentrierte Bounding Box
|
||||
bbox_points = [
|
||||
@@ -771,7 +819,7 @@ def add_bounding_box_to_modelspace(msp, bbox, centered=False):
|
||||
(max_pt.x, min_pt.y),
|
||||
(max_pt.x, max_pt.y),
|
||||
(min_pt.x, max_pt.y),
|
||||
(min_pt.x, min_pt.y)
|
||||
(min_pt.x, min_pt.y),
|
||||
]
|
||||
|
||||
bbox_poly = msp.add_lwpolyline(bbox_points)
|
||||
@@ -779,13 +827,23 @@ def add_bounding_box_to_modelspace(msp, bbox, centered=False):
|
||||
bbox_poly.dxf.color = 1 # Rot
|
||||
|
||||
# Text mit Abmessungen
|
||||
text_pos = Vec3(bbox_points[0][0], (bbox_points[2][1] if centered else max_pt.y) + 5, 0)
|
||||
msp.add_text(f"Breite: {width:.2f} mm", height=3,
|
||||
dxfattribs={'insert': text_pos, 'layer': "BOUNDING_BOX", 'color': 1})
|
||||
text_pos = Vec3(
|
||||
bbox_points[0][0], (bbox_points[2][1] if centered else max_pt.y) + 5, 0
|
||||
)
|
||||
msp.add_text(
|
||||
f"Breite: {width:.2f} mm",
|
||||
height=3,
|
||||
dxfattribs={"insert": text_pos, "layer": "BOUNDING_BOX", "color": 1},
|
||||
)
|
||||
|
||||
text_pos2 = Vec3(bbox_points[0][0], (bbox_points[2][1] if centered else max_pt.y) + 10, 0)
|
||||
msp.add_text(f"Höhe: {height:.2f} mm", height=3,
|
||||
dxfattribs={'insert': text_pos2, 'layer': "BOUNDING_BOX", 'color': 1})
|
||||
text_pos2 = Vec3(
|
||||
bbox_points[0][0], (bbox_points[2][1] if centered else max_pt.y) + 10, 0
|
||||
)
|
||||
msp.add_text(
|
||||
f"Höhe: {height:.2f} mm",
|
||||
height=3,
|
||||
dxfattribs={"insert": text_pos2, "layer": "BOUNDING_BOX", "color": 1},
|
||||
)
|
||||
|
||||
|
||||
def format_bounding_box(bbox):
|
||||
@@ -801,9 +859,11 @@ def format_bounding_box(bbox):
|
||||
height = max_pt.y - min_pt.y
|
||||
depth = max_pt.z - min_pt.z
|
||||
|
||||
return (f"Min: ({min_pt.x:.2f}, {min_pt.y:.2f}, {min_pt.z:.2f}) "
|
||||
return (
|
||||
f"Min: ({min_pt.x:.2f}, {min_pt.y:.2f}, {min_pt.z:.2f}) "
|
||||
f"Max: ({max_pt.x:.2f}, {max_pt.y:.2f}, {max_pt.z:.2f}) "
|
||||
f"Größe: {width:.2f} × {height:.2f} × {depth:.2f} mm")
|
||||
f"Größe: {width:.2f} × {height:.2f} × {depth:.2f} mm"
|
||||
)
|
||||
|
||||
|
||||
def analyze_source_dxf_with_blocks(filename):
|
||||
@@ -824,16 +884,16 @@ def analyze_source_dxf_with_blocks(filename):
|
||||
entity_type = entity.dxftype()
|
||||
entity_types[entity_type] = entity_types.get(entity_type, 0) + 1
|
||||
|
||||
layer = getattr(entity.dxf, 'layer', '0')
|
||||
layer = getattr(entity.dxf, "layer", "0")
|
||||
layer_count[layer] = layer_count.get(layer, 0) + 1
|
||||
|
||||
if entity_type == 'INSERT':
|
||||
if entity_type == "INSERT":
|
||||
block_name = entity.dxf.name
|
||||
insert_blocks[block_name] = insert_blocks.get(block_name, 0) + 1
|
||||
|
||||
# Block-Definitionen analysieren
|
||||
for block_name in doc.blocks:
|
||||
if not block_name.startswith('*'): # Keine Standard-Blöcke
|
||||
if not block_name.startswith("*"): # Keine Standard-Blöcke
|
||||
block_def = doc.blocks[block_name]
|
||||
entity_count = len(list(block_def))
|
||||
block_definitions[block_name] = entity_count
|
||||
@@ -864,11 +924,21 @@ def analyze_source_dxf_with_blocks(filename):
|
||||
print(f"Fehler bei der Analyse: {e}")
|
||||
return {}, {}, {}, {}
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Argumentparser für Kommandozeilenoptionen
|
||||
parser = argparse.ArgumentParser(description="SVG/XML zu DXF Konverter")
|
||||
parser.add_argument('-i', '--input', type=str, help='Input-Verzeichnis mit SVG/XML-Dateien')
|
||||
parser.add_argument('-n', '--name', required=False, type=str, help='Name der zu erzeugenden Bibliothek (optional, wird sonst abgefragt)', default="test")
|
||||
parser.add_argument(
|
||||
"-i", "--input", type=str, help="Input-Verzeichnis mit SVG/XML-Dateien"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-n",
|
||||
"--name",
|
||||
required=False,
|
||||
type=str,
|
||||
help="Name der zu erzeugenden Bibliothek (optional, wird sonst abgefragt)",
|
||||
default="test",
|
||||
)
|
||||
|
||||
if len(sys.argv) == 2 and sys.argv[1] in ("-h", "--help"):
|
||||
parser.print_help()
|
||||
@@ -877,7 +947,9 @@ if __name__ == "__main__":
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.name:
|
||||
args.name = input("Bitte Namen der zu erzeugenden Bibliothek eingeben: ").strip()
|
||||
args.name = input(
|
||||
"Bitte Namen der zu erzeugenden Bibliothek eingeben: "
|
||||
).strip()
|
||||
if not args.name:
|
||||
print("Fehler: Kein Name angegeben. Beende.")
|
||||
sys.exit(1)
|
||||
@@ -890,7 +962,9 @@ if __name__ == "__main__":
|
||||
INPUT_DIR = check_environment_var("PROJECT_DATA") / "omniflo"
|
||||
print(f"Kein Input-Verzeichnis angegeben, verwende Standard: {INPUT_DIR} \n")
|
||||
|
||||
OUTPUT_FILE = check_environment_var("PROJECT_DATA") / "block_libraries" / f"{args.name}.dxf"
|
||||
OUTPUT_FILE = (
|
||||
check_environment_var("PROJECT_DATA") / "block_libraries" / f"{args.name}.dxf"
|
||||
)
|
||||
|
||||
# Prüfe und erstelle log-Verzeichnis falls nötig
|
||||
log_dir = check_environment_var("PROJECT_LOG")
|
||||
@@ -899,9 +973,9 @@ if __name__ == "__main__":
|
||||
print(f"Log-Verzeichnis erstellt: {log_dir}")
|
||||
|
||||
# Logger Setup
|
||||
log_file = Path(os.environ['PROJECT_LOG']) / 'dxf2lib.log'
|
||||
file_handler = logging.FileHandler(str(log_file), 'a', 'utf-8')
|
||||
logger = setup_logger(log_dir, name='dxf2lib')
|
||||
log_file = Path(os.environ["PROJECT_LOG"]) / "dxf2lib.log"
|
||||
file_handler = logging.FileHandler(str(log_file), "a", "utf-8")
|
||||
logger = setup_logger(log_dir, name="dxf2lib")
|
||||
logger.info("=== DXF2LIB Verarbeitung gestartet ===")
|
||||
logger.info(f"Input-Verzeichnis: {INPUT_DIR}")
|
||||
logger.info(f"Output-Datei: {OUTPUT_FILE}")
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
"""
|
||||
Handler Context für DXF-Elementgenerierung.
|
||||
Vereinfacht die Aufrufe der handle-Funktionen und bietet Debug-Unterstützung.
|
||||
"""
|
||||
|
||||
|
||||
class HandlerContext:
|
||||
"""
|
||||
Kontextobjekt für Handler-Funktionsaufrufe.
|
||||
|
||||
Speichert alle Parameter für handle-Funktionen und bietet:
|
||||
- Vereinfachte Aufrufe
|
||||
- Schöne String-Repräsentation für Debugging
|
||||
- Einfachen Zugriff auf alle Parameter
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
msp,
|
||||
teileid,
|
||||
merkmale,
|
||||
x,
|
||||
y,
|
||||
doc,
|
||||
lib_doc,
|
||||
verbose=False,
|
||||
symbols=None,
|
||||
strecken_nachbarn=None,
|
||||
config=None,
|
||||
config_allgemein=None,
|
||||
):
|
||||
self.msp = msp
|
||||
self.teileid = teileid
|
||||
self.merkmale = merkmale if merkmale is not None else {}
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.doc = doc
|
||||
self.lib_doc = lib_doc
|
||||
self.verbose = verbose
|
||||
self.symbols = symbols if symbols is not None else []
|
||||
self.strecken_nachbarn = (
|
||||
strecken_nachbarn if strecken_nachbarn is not None else []
|
||||
)
|
||||
self.config = config
|
||||
self.config_allgemein = config_allgemein
|
||||
|
||||
def call(self, handler_func):
|
||||
"""
|
||||
Ruft eine Handler-Funktion mit allen gespeicherten Parametern auf.
|
||||
|
||||
Args:
|
||||
handler_func: Die Handler-Funktion (z.B. handle_ils_2_0_kreisel)
|
||||
|
||||
Returns:
|
||||
Rückgabewert der Handler-Funktion
|
||||
"""
|
||||
return handler_func(
|
||||
self.msp,
|
||||
self.teileid,
|
||||
self.merkmale,
|
||||
self.x,
|
||||
self.y,
|
||||
self.doc,
|
||||
self.lib_doc,
|
||||
self.verbose,
|
||||
self.symbols,
|
||||
self.strecken_nachbarn,
|
||||
self.config,
|
||||
self.config_allgemein,
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
"""String-Repräsentation für Debugging."""
|
||||
lines = [
|
||||
"=" * 80,
|
||||
"HandlerContext:",
|
||||
"=" * 80,
|
||||
f"TeileId: {self.teileid}",
|
||||
f"Position: x={self.x:.2f}, y={self.y:.2f}",
|
||||
f"Verbose: {self.verbose}",
|
||||
"-" * 80,
|
||||
"Merkmale:",
|
||||
]
|
||||
|
||||
if self.merkmale:
|
||||
for key, value in self.merkmale.items():
|
||||
lines.append(f" {key:20s}: {value}")
|
||||
else:
|
||||
lines.append(" (keine)")
|
||||
|
||||
lines.append("-" * 80)
|
||||
lines.append(f"Symbols: {len(self.symbols)} Einträge")
|
||||
if self.symbols:
|
||||
for i, sym in enumerate(self.symbols, 1):
|
||||
lines.append(f" [{i}] {sym}")
|
||||
|
||||
lines.append("-" * 80)
|
||||
lines.append(f"Nachbarn: {len(self.strecken_nachbarn)} Einträge")
|
||||
|
||||
lines.append("-" * 80)
|
||||
lines.append(f"doc: {type(self.doc).__name__}")
|
||||
lines.append(
|
||||
f"lib_doc: {type(self.lib_doc).__name__ if self.lib_doc else 'None'}"
|
||||
)
|
||||
lines.append(f"msp: {type(self.msp).__name__}")
|
||||
lines.append(f"config: {'vorhanden' if self.config else 'None'}")
|
||||
lines.append(f"config_allg: {'vorhanden' if self.config_allgemein else 'None'}")
|
||||
lines.append("=" * 80)
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
def __repr__(self):
|
||||
"""Kurze Repräsentation."""
|
||||
return (
|
||||
f"HandlerContext(teileid={self.teileid!r}, "
|
||||
f"x={self.x:.2f}, y={self.y:.2f}, "
|
||||
f"merkmale={len(self.merkmale)} items)"
|
||||
)
|
||||
|
||||
def to_dict(self):
|
||||
"""
|
||||
Gibt alle Parameter als Dictionary zurück (ohne Objekt-Referenzen).
|
||||
Nützlich für Logging oder Serialisierung.
|
||||
"""
|
||||
return {
|
||||
"teileid": self.teileid,
|
||||
"x": self.x,
|
||||
"y": self.y,
|
||||
"verbose": self.verbose,
|
||||
"merkmale": self.merkmale.copy(),
|
||||
"symbols_count": len(self.symbols),
|
||||
"symbols": self.symbols,
|
||||
"nachbarn_count": len(self.strecken_nachbarn),
|
||||
"has_config": self.config is not None,
|
||||
"has_config_allgemein": self.config_allgemein is not None,
|
||||
"has_lib_doc": self.lib_doc is not None,
|
||||
}
|
||||
|
||||
@property
|
||||
def position(self):
|
||||
"""Gibt Position als Tuple zurück."""
|
||||
return (self.x, self.y)
|
||||
|
||||
@property
|
||||
def has_library(self):
|
||||
"""Prüft, ob eine Bibliothek verfügbar ist."""
|
||||
return self.lib_doc is not None
|
||||
|
||||
def get_merkmal(self, key, default=None):
|
||||
"""
|
||||
Holt ein Merkmal mit Fallback-Wert.
|
||||
|
||||
Args:
|
||||
key: Merkmal-Schlüssel
|
||||
default: Standardwert, falls Merkmal nicht existiert
|
||||
|
||||
Returns:
|
||||
Merkmalwert oder default
|
||||
"""
|
||||
return self.merkmale.get(key, default)
|
||||
|
||||
|
||||
def create_context_from_row(
|
||||
row,
|
||||
msp,
|
||||
doc,
|
||||
lib_doc,
|
||||
strecken_nachbarn,
|
||||
config,
|
||||
config_allgemein,
|
||||
symbols=None,
|
||||
verbose=False,
|
||||
):
|
||||
"""
|
||||
Factory-Funktion: Erstellt HandlerContext aus einer CSV-Zeile.
|
||||
|
||||
Args:
|
||||
row: Dictionary mit CSV-Daten
|
||||
msp: Modelspace
|
||||
doc: DXF-Dokument
|
||||
lib_doc: Bibliotheks-Dokument
|
||||
strecken_nachbarn: Liste der Nachbarn
|
||||
config: Config-Parser
|
||||
config_allgemein: Allgemeine Config
|
||||
symbols: Symbol-Liste (optional)
|
||||
verbose: Debug-Modus (optional)
|
||||
|
||||
Returns:
|
||||
HandlerContext-Instanz
|
||||
"""
|
||||
from arbeiten_mit_csv import parse_merkmale, extract_coords
|
||||
|
||||
bezeichner = row["Bezeichnung"].strip()
|
||||
teileid = row["TeileId"].strip()
|
||||
planquadrat = row["Planquadrat"]
|
||||
merkmale = parse_merkmale(row.get("Merkmale", ""))
|
||||
merkmale["bezeichner"] = bezeichner
|
||||
|
||||
x, y = extract_coords(planquadrat)
|
||||
|
||||
return HandlerContext(
|
||||
msp=msp,
|
||||
teileid=teileid,
|
||||
merkmale=merkmale,
|
||||
x=x,
|
||||
y=y,
|
||||
doc=doc,
|
||||
lib_doc=lib_doc,
|
||||
verbose=verbose,
|
||||
symbols=symbols if symbols is not None else [],
|
||||
strecken_nachbarn=strecken_nachbarn,
|
||||
config=config,
|
||||
config_allgemein=config_allgemein,
|
||||
)
|
||||
@@ -7,7 +7,7 @@ def inspect_blocks(dxf_path):
|
||||
print(f"Datei: {dxf_path}")
|
||||
print("Gefundene Blöcke und Attribute:\n")
|
||||
for block in doc.blocks:
|
||||
if block.name.startswith('*'): # Überspringe anonyme/Standardblöcke
|
||||
if block.name.startswith("*"): # Überspringe anonyme/Standardblöcke
|
||||
continue
|
||||
print(f"Block: {block.name}")
|
||||
attribs = [e for e in block if e.dxftype() == "ATTDEF"]
|
||||
|
||||
+1124
-390
File diff suppressed because it is too large
Load Diff
+204
-59
@@ -4,6 +4,7 @@ import difflib
|
||||
from utils import check_environment_var, setup_logger
|
||||
import plant2dxf
|
||||
|
||||
|
||||
class TestDXFGeometry(unittest.TestCase):
|
||||
testordner_path = Path(check_environment_var("PROJECT_TEST"))
|
||||
lib_path = Path(check_environment_var("PROJECT_DATA"))
|
||||
@@ -13,7 +14,25 @@ class TestDXFGeometry(unittest.TestCase):
|
||||
cfg_path = config_dir / "shapes.cfg"
|
||||
allgemein_cfg_path = config_dir / "allgemein.cfg"
|
||||
|
||||
GEOM_CODES = {"0", "8", "10", "20", "30", "11", "21", "31", "41", "42", "43", "70", "71", "72", "73", "74", "75"}
|
||||
GEOM_CODES = {
|
||||
"0",
|
||||
"8",
|
||||
"10",
|
||||
"20",
|
||||
"30",
|
||||
"11",
|
||||
"21",
|
||||
"31",
|
||||
"41",
|
||||
"42",
|
||||
"43",
|
||||
"70",
|
||||
"71",
|
||||
"72",
|
||||
"73",
|
||||
"74",
|
||||
"75",
|
||||
}
|
||||
|
||||
def extract_geometry_lines(self, file_path):
|
||||
"""
|
||||
@@ -39,125 +58,251 @@ class TestDXFGeometry(unittest.TestCase):
|
||||
geom1 = self.extract_geometry_lines(file1)
|
||||
geom2 = self.extract_geometry_lines(file2)
|
||||
if geom1 != geom2:
|
||||
diff = "".join(difflib.unified_diff(geom1, geom2, fromfile=str(file1), tofile=str(file2)))
|
||||
diff = "".join(
|
||||
difflib.unified_diff(
|
||||
geom1, geom2, fromfile=str(file1), tofile=str(file2)
|
||||
)
|
||||
)
|
||||
raise AssertionError(f"Geometrische Daten unterscheiden sich:\n{diff}")
|
||||
|
||||
def test_omniflobogen_dxf_file(self):
|
||||
omniflo_bogen = "omniflo_bogen"
|
||||
omniflo_bogen_csv = self.testordner_path / f"{omniflo_bogen}.csv"
|
||||
omniflo_bogen_dxf = f"{omniflo_bogen}.dxf"
|
||||
omniflo_bogen_jason = self.work_dir / f"{omniflo_bogen}.jason"
|
||||
omniflo_bogen_json = self.work_dir / f"{omniflo_bogen}.json"
|
||||
omniflo_bogen_output = self.work_dir / omniflo_bogen_dxf
|
||||
omniflo_bogen_reference = self.testordner_path / omniflo_bogen_dxf
|
||||
plant2dxf.main(omniflo_bogen_csv , self.default_lib_path, self.cfg_path, self.allgemein_cfg_path, omniflo_bogen_output,omniflo_bogen_jason)
|
||||
plant2dxf.main(
|
||||
omniflo_bogen_csv,
|
||||
self.default_lib_path,
|
||||
self.cfg_path,
|
||||
self.allgemein_cfg_path,
|
||||
omniflo_bogen_output,
|
||||
omniflo_bogen_json,
|
||||
)
|
||||
self.assert_dxf_geometry_equal(omniflo_bogen_output, omniflo_bogen_reference)
|
||||
|
||||
def test_weiche_90_dxf_file(self):
|
||||
weiche_90= "weiche_90"
|
||||
weiche_90 = "weiche_90"
|
||||
weiche_90_csv = self.testordner_path / f"{weiche_90}.csv"
|
||||
weiche_90_dxf = f"{weiche_90}.dxf"
|
||||
weiche_90_jason = self.work_dir /f"{weiche_90}.jason"
|
||||
weiche_90_json = self.work_dir / f"{weiche_90}.json"
|
||||
weiche_90_output = self.work_dir / weiche_90_dxf
|
||||
weiche_90_reference = self.testordner_path / weiche_90_dxf
|
||||
plant2dxf.main(weiche_90_csv , self.default_lib_path, self.cfg_path, self.allgemein_cfg_path, weiche_90_output,weiche_90_jason)
|
||||
plant2dxf.main(
|
||||
weiche_90_csv,
|
||||
self.default_lib_path,
|
||||
self.cfg_path,
|
||||
self.allgemein_cfg_path,
|
||||
weiche_90_output,
|
||||
weiche_90_json,
|
||||
)
|
||||
self.assert_dxf_geometry_equal(weiche_90_output, weiche_90_reference)
|
||||
|
||||
def test_weiche_45_simple_dxf_file(self):
|
||||
weiche_45_simple= "weiche_45_simple"
|
||||
weiche_45_simple = "weiche_45_simple"
|
||||
weiche_45_simple_csv = self.testordner_path / f"{weiche_45_simple}.csv"
|
||||
weiche_45_simple_dxf = f"{weiche_45_simple}.dxf"
|
||||
weiche_45_simple_jason = self.work_dir/ f"{weiche_45_simple}.jason"
|
||||
weiche_45_simple_json = self.work_dir / f"{weiche_45_simple}.json"
|
||||
weiche_45_simple_output = self.work_dir / weiche_45_simple_dxf
|
||||
weiche_45_simple_reference = self.testordner_path / weiche_45_simple_dxf
|
||||
plant2dxf.main(weiche_45_simple_csv , self.default_lib_path, self.cfg_path, self.allgemein_cfg_path, weiche_45_simple_output,weiche_45_simple_jason)
|
||||
self.assert_dxf_geometry_equal(weiche_45_simple_output, weiche_45_simple_reference)
|
||||
plant2dxf.main(
|
||||
weiche_45_simple_csv,
|
||||
self.default_lib_path,
|
||||
self.cfg_path,
|
||||
self.allgemein_cfg_path,
|
||||
weiche_45_simple_output,
|
||||
weiche_45_simple_json,
|
||||
)
|
||||
self.assert_dxf_geometry_equal(
|
||||
weiche_45_simple_output, weiche_45_simple_reference
|
||||
)
|
||||
|
||||
def test_weiche_45_doppel_dxf_file(self):
|
||||
weiche_45_doppel= "weiche_45_doppel"
|
||||
weiche_45_doppel = "weiche_45_doppel"
|
||||
weiche_45_doppel_csv = self.testordner_path / f"{weiche_45_doppel}.csv"
|
||||
weiche_45_doppel_dxf = f"{weiche_45_doppel}.dxf"
|
||||
weiche_45_doppel_jason = self.work_dir /f"{weiche_45_doppel}.jason"
|
||||
weiche_45_doppel_json = self.work_dir / f"{weiche_45_doppel}.json"
|
||||
weiche_45_doppel_output = self.work_dir / weiche_45_doppel_dxf
|
||||
weiche_45_doppel_reference = self.testordner_path / weiche_45_doppel_dxf
|
||||
plant2dxf.main(weiche_45_doppel_csv , self.default_lib_path, self.cfg_path, self.allgemein_cfg_path, weiche_45_doppel_output,weiche_45_doppel_jason)
|
||||
self.assert_dxf_geometry_equal(weiche_45_doppel_output, weiche_45_doppel_reference)
|
||||
plant2dxf.main(
|
||||
weiche_45_doppel_csv,
|
||||
self.default_lib_path,
|
||||
self.cfg_path,
|
||||
self.allgemein_cfg_path,
|
||||
weiche_45_doppel_output,
|
||||
weiche_45_doppel_json,
|
||||
)
|
||||
self.assert_dxf_geometry_equal(
|
||||
weiche_45_doppel_output, weiche_45_doppel_reference
|
||||
)
|
||||
|
||||
def test_weiche_45_dreiwege_dxf_file(self):
|
||||
weiche_45_dreiwege= "weiche_45_dreiwege"
|
||||
weiche_45_dreiwege = "weiche_45_dreiwege"
|
||||
weiche_45_dreiwege_csv = self.testordner_path / f"{weiche_45_dreiwege}.csv"
|
||||
weiche_45_dreiwege_dxf = f"{weiche_45_dreiwege}.dxf"
|
||||
weiche_45_dreiwege_jason = self.work_dir /f"{weiche_45_dreiwege}.jason"
|
||||
weiche_45_dreiwege_json = self.work_dir / f"{weiche_45_dreiwege}.json"
|
||||
weiche_45_dreiwege_output = self.work_dir / weiche_45_dreiwege_dxf
|
||||
weiche_45_dreiwege_reference = self.testordner_path / weiche_45_dreiwege_dxf
|
||||
plant2dxf.main(weiche_45_dreiwege_csv , self.default_lib_path, self.cfg_path, self.allgemein_cfg_path, weiche_45_dreiwege_output,weiche_45_dreiwege_jason)
|
||||
self.assert_dxf_geometry_equal(weiche_45_dreiwege_output, weiche_45_dreiwege_reference)
|
||||
plant2dxf.main(
|
||||
weiche_45_dreiwege_csv,
|
||||
self.default_lib_path,
|
||||
self.cfg_path,
|
||||
self.allgemein_cfg_path,
|
||||
weiche_45_dreiwege_output,
|
||||
weiche_45_dreiwege_json,
|
||||
)
|
||||
self.assert_dxf_geometry_equal(
|
||||
weiche_45_dreiwege_output, weiche_45_dreiwege_reference
|
||||
)
|
||||
|
||||
def test_weichenkoerper_dxf_file(self):
|
||||
weichenkoerper= "weichenkoerper"
|
||||
weichenkoerper = "weichenkoerper"
|
||||
weichenkoerper_csv = self.testordner_path / f"{weichenkoerper}.csv"
|
||||
weichenkoerper_dxf = f"{weichenkoerper}.dxf"
|
||||
weichenkoerper_jason = self.work_dir /f"{weichenkoerper}.jason"
|
||||
weichenkoerper_json = self.work_dir / f"{weichenkoerper}.json"
|
||||
weichenkoerper_output = self.work_dir / weichenkoerper_dxf
|
||||
weichenkoerper_reference = self.testordner_path / weichenkoerper_dxf
|
||||
plant2dxf.main(weichenkoerper_csv , self.default_lib_path, self.cfg_path, self.allgemein_cfg_path, weichenkoerper_output,weichenkoerper_jason)
|
||||
plant2dxf.main(
|
||||
weichenkoerper_csv,
|
||||
self.default_lib_path,
|
||||
self.cfg_path,
|
||||
self.allgemein_cfg_path,
|
||||
weichenkoerper_output,
|
||||
weichenkoerper_json,
|
||||
)
|
||||
self.assert_dxf_geometry_equal(weichenkoerper_output, weichenkoerper_reference)
|
||||
|
||||
def test_weichenkombination_dxf_file(self):
|
||||
weichenkombination= "weichenkombination"
|
||||
weichenkombination = "weichenkombination"
|
||||
weichenkombination_csv = self.testordner_path / f"{weichenkombination}.csv"
|
||||
weichenkombination_dxf = f"{weichenkombination}.dxf"
|
||||
weichenkombination_jason = self.work_dir /f"{weichenkombination}.jason"
|
||||
weichenkombination_json = self.work_dir / f"{weichenkombination}.json"
|
||||
weichenkombination_output = self.work_dir / weichenkombination_dxf
|
||||
weichenkombination_reference = self.testordner_path / weichenkombination_dxf
|
||||
plant2dxf.main(weichenkombination_csv , self.default_lib_path, self.cfg_path, self.allgemein_cfg_path, weichenkombination_output,weichenkombination_jason)
|
||||
self.assert_dxf_geometry_equal(weichenkombination_output, weichenkombination_reference)
|
||||
plant2dxf.main(
|
||||
weichenkombination_csv,
|
||||
self.default_lib_path,
|
||||
self.cfg_path,
|
||||
self.allgemein_cfg_path,
|
||||
weichenkombination_output,
|
||||
weichenkombination_json,
|
||||
)
|
||||
self.assert_dxf_geometry_equal(
|
||||
weichenkombination_output, weichenkombination_reference
|
||||
)
|
||||
|
||||
def test_gefaelle_dxf_file(self):
|
||||
gefaelle= "gefaelle"
|
||||
gefaelle = "gefaelle"
|
||||
gefaelle_csv = self.testordner_path / f"{gefaelle}.csv"
|
||||
gefaelle_dxf = f"{gefaelle}.dxf"
|
||||
gefaelle_jason = self.work_dir /f"{gefaelle}.jason"
|
||||
gefaelle_json = self.work_dir / f"{gefaelle}.json"
|
||||
weichenkombination_output = self.work_dir / gefaelle_dxf
|
||||
weichenkombination_reference = self.testordner_path / gefaelle_dxf
|
||||
plant2dxf.main(gefaelle_csv , self.default_lib_path, self.cfg_path, self.allgemein_cfg_path, weichenkombination_output,gefaelle_jason)
|
||||
self.assert_dxf_geometry_equal(weichenkombination_output, weichenkombination_reference)
|
||||
plant2dxf.main(
|
||||
gefaelle_csv,
|
||||
self.default_lib_path,
|
||||
self.cfg_path,
|
||||
self.allgemein_cfg_path,
|
||||
weichenkombination_output,
|
||||
gefaelle_json,
|
||||
)
|
||||
self.assert_dxf_geometry_equal(
|
||||
weichenkombination_output, weichenkombination_reference
|
||||
)
|
||||
|
||||
def test_gefaelle_ausnahme_gleiche_orientierung_dxf_file(self):
|
||||
gefaelle_ausnahme_gleiche_orientierung= "gefaelle_ausnahme_gleiche_orientierung"
|
||||
gefaelle_ausnahme_gleiche_orientierung_csv = self.testordner_path / f"{gefaelle_ausnahme_gleiche_orientierung}.csv"
|
||||
gefaelle_ausnahme_gleiche_orientierung_dxf = f"{gefaelle_ausnahme_gleiche_orientierung}.dxf"
|
||||
gefaelle_ausnahme_gleiche_orientierung_jason = self.work_dir /f"{gefaelle_ausnahme_gleiche_orientierung}.jason"
|
||||
gefaelle_ausnahme_gleiche_orientierung_output = self.work_dir / gefaelle_ausnahme_gleiche_orientierung_dxf
|
||||
gefaelle_ausnahme_gleiche_orientierung_reference = self.testordner_path / gefaelle_ausnahme_gleiche_orientierung_dxf
|
||||
plant2dxf.main(gefaelle_ausnahme_gleiche_orientierung_csv , self.default_lib_path, self.cfg_path, self.allgemein_cfg_path, gefaelle_ausnahme_gleiche_orientierung_output,gefaelle_ausnahme_gleiche_orientierung_jason)
|
||||
self.assert_dxf_geometry_equal(gefaelle_ausnahme_gleiche_orientierung_output, gefaelle_ausnahme_gleiche_orientierung_reference)
|
||||
gefaelle_ausnahme_gleiche_orientierung = (
|
||||
"gefaelle_ausnahme_gleiche_orientierung"
|
||||
)
|
||||
gefaelle_ausnahme_gleiche_orientierung_csv = (
|
||||
self.testordner_path / f"{gefaelle_ausnahme_gleiche_orientierung}.csv"
|
||||
)
|
||||
gefaelle_ausnahme_gleiche_orientierung_dxf = (
|
||||
f"{gefaelle_ausnahme_gleiche_orientierung}.dxf"
|
||||
)
|
||||
gefaelle_ausnahme_gleiche_orientierung_json = (
|
||||
self.work_dir / f"{gefaelle_ausnahme_gleiche_orientierung}.json"
|
||||
)
|
||||
gefaelle_ausnahme_gleiche_orientierung_output = (
|
||||
self.work_dir / gefaelle_ausnahme_gleiche_orientierung_dxf
|
||||
)
|
||||
gefaelle_ausnahme_gleiche_orientierung_reference = (
|
||||
self.testordner_path / gefaelle_ausnahme_gleiche_orientierung_dxf
|
||||
)
|
||||
plant2dxf.main(
|
||||
gefaelle_ausnahme_gleiche_orientierung_csv,
|
||||
self.default_lib_path,
|
||||
self.cfg_path,
|
||||
self.allgemein_cfg_path,
|
||||
gefaelle_ausnahme_gleiche_orientierung_output,
|
||||
gefaelle_ausnahme_gleiche_orientierung_json,
|
||||
)
|
||||
self.assert_dxf_geometry_equal(
|
||||
gefaelle_ausnahme_gleiche_orientierung_output,
|
||||
gefaelle_ausnahme_gleiche_orientierung_reference,
|
||||
)
|
||||
|
||||
def test_gefaelle_ausnahme_unterschiedlich_orientierung_dxf_file(self):
|
||||
gefaelle_ausnahme_unterschiedlich_orientierung= "gefaelle_ausnahme_unterschiedlich_orientierung"
|
||||
gefaelle_ausnahme_unterschiedlich_orientierung_csv = self.testordner_path / f"{gefaelle_ausnahme_unterschiedlich_orientierung}.csv"
|
||||
gefaelle_ausnahme_unterschiedlich_orientierung_dxf = f"{gefaelle_ausnahme_unterschiedlich_orientierung}.dxf"
|
||||
gefaelle_ausnahme_unterschiedlich_orientierung_jason = self.work_dir /f"{gefaelle_ausnahme_unterschiedlich_orientierung}.jason"
|
||||
gefaelle_ausnahme_unterschiedlich_orientierung_output = self.work_dir / gefaelle_ausnahme_unterschiedlich_orientierung_dxf
|
||||
gefaelle_ausnahme_unterschiedlich_orientierung_reference = self.testordner_path / gefaelle_ausnahme_unterschiedlich_orientierung_dxf
|
||||
plant2dxf.main(gefaelle_ausnahme_unterschiedlich_orientierung_csv , self.default_lib_path, self.cfg_path, self.allgemein_cfg_path, gefaelle_ausnahme_unterschiedlich_orientierung_output,gefaelle_ausnahme_unterschiedlich_orientierung_jason)
|
||||
self.assert_dxf_geometry_equal(gefaelle_ausnahme_unterschiedlich_orientierung_output, gefaelle_ausnahme_unterschiedlich_orientierung_reference)
|
||||
gefaelle_ausnahme_unterschiedlich_orientierung = (
|
||||
"gefaelle_ausnahme_unterschiedlich_orientierung"
|
||||
)
|
||||
gefaelle_ausnahme_unterschiedlich_orientierung_csv = (
|
||||
self.testordner_path
|
||||
/ f"{gefaelle_ausnahme_unterschiedlich_orientierung}.csv"
|
||||
)
|
||||
gefaelle_ausnahme_unterschiedlich_orientierung_dxf = (
|
||||
f"{gefaelle_ausnahme_unterschiedlich_orientierung}.dxf"
|
||||
)
|
||||
gefaelle_ausnahme_unterschiedlich_orientierung_json = (
|
||||
self.work_dir / f"{gefaelle_ausnahme_unterschiedlich_orientierung}.json"
|
||||
)
|
||||
gefaelle_ausnahme_unterschiedlich_orientierung_output = (
|
||||
self.work_dir / gefaelle_ausnahme_unterschiedlich_orientierung_dxf
|
||||
)
|
||||
gefaelle_ausnahme_unterschiedlich_orientierung_reference = (
|
||||
self.testordner_path / gefaelle_ausnahme_unterschiedlich_orientierung_dxf
|
||||
)
|
||||
plant2dxf.main(
|
||||
gefaelle_ausnahme_unterschiedlich_orientierung_csv,
|
||||
self.default_lib_path,
|
||||
self.cfg_path,
|
||||
self.allgemein_cfg_path,
|
||||
gefaelle_ausnahme_unterschiedlich_orientierung_output,
|
||||
gefaelle_ausnahme_unterschiedlich_orientierung_json,
|
||||
)
|
||||
self.assert_dxf_geometry_equal(
|
||||
gefaelle_ausnahme_unterschiedlich_orientierung_output,
|
||||
gefaelle_ausnahme_unterschiedlich_orientierung_reference,
|
||||
)
|
||||
|
||||
def test_gefaelle_einzeln_verbunden_dxf_file(self):
|
||||
gefaelle_einzeln_verbunden= "gefaelle_einzeln_verbunden"
|
||||
gefaelle_einzeln_verbunden_csv = self.testordner_path / f"{gefaelle_einzeln_verbunden}.csv"
|
||||
gefaelle_einzeln_verbunden = "gefaelle_einzeln_verbunden"
|
||||
gefaelle_einzeln_verbunden_csv = (
|
||||
self.testordner_path / f"{gefaelle_einzeln_verbunden}.csv"
|
||||
)
|
||||
gefaelle_einzeln_verbunden_dxf = f"{gefaelle_einzeln_verbunden}.dxf"
|
||||
gefaelle_einzeln_verbunden_jason = self.work_dir /f"{gefaelle_einzeln_verbunden}.jason"
|
||||
gefaelle_einzeln_verbunden_output = self.work_dir / gefaelle_einzeln_verbunden_dxf
|
||||
gefaelle_einzeln_verbunden_reference = self.testordner_path / gefaelle_einzeln_verbunden_dxf
|
||||
plant2dxf.main(gefaelle_einzeln_verbunden_csv , self.default_lib_path, self.cfg_path, self.allgemein_cfg_path, gefaelle_einzeln_verbunden_output,gefaelle_einzeln_verbunden_jason)
|
||||
self.assert_dxf_geometry_equal(gefaelle_einzeln_verbunden_output, gefaelle_einzeln_verbunden_reference)
|
||||
|
||||
|
||||
|
||||
gefaelle_einzeln_verbunden_json = (
|
||||
self.work_dir / f"{gefaelle_einzeln_verbunden}.json"
|
||||
)
|
||||
gefaelle_einzeln_verbunden_output = (
|
||||
self.work_dir / gefaelle_einzeln_verbunden_dxf
|
||||
)
|
||||
gefaelle_einzeln_verbunden_reference = (
|
||||
self.testordner_path / gefaelle_einzeln_verbunden_dxf
|
||||
)
|
||||
plant2dxf.main(
|
||||
gefaelle_einzeln_verbunden_csv,
|
||||
self.default_lib_path,
|
||||
self.cfg_path,
|
||||
self.allgemein_cfg_path,
|
||||
gefaelle_einzeln_verbunden_output,
|
||||
gefaelle_einzeln_verbunden_json,
|
||||
)
|
||||
self.assert_dxf_geometry_equal(
|
||||
gefaelle_einzeln_verbunden_output, gefaelle_einzeln_verbunden_reference
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
|
||||
|
||||
+4
-3
@@ -14,7 +14,7 @@ def check_environment_var(env_str: str) -> Path:
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def setup_logger(log_dir: Path, name: str = 'app') -> logging.Logger:
|
||||
def setup_logger(log_dir: Path, name: str = "app") -> logging.Logger:
|
||||
"""
|
||||
Erstellt und konfiguriert einen Logger, der sowohl in eine Datei als auch auf die Konsole schreibt.
|
||||
Die Logdatei erhält einen Zeitstempel im Namen und ist UTF-8 kodiert.
|
||||
@@ -26,6 +26,7 @@ def setup_logger(log_dir: Path, name: str = 'app') -> logging.Logger:
|
||||
logging.Logger: Konfigurierter Logger
|
||||
"""
|
||||
from datetime import datetime
|
||||
|
||||
logger = logging.getLogger(name)
|
||||
logger.setLevel(logging.INFO)
|
||||
|
||||
@@ -38,7 +39,7 @@ def setup_logger(log_dir: Path, name: str = 'app') -> logging.Logger:
|
||||
|
||||
# Logdatei mit Zeitstempel im Namen erzeugen
|
||||
log_file = log_dir / f"{name}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log"
|
||||
file_handler = logging.FileHandler(log_file, encoding='utf-8')
|
||||
file_handler = logging.FileHandler(log_file, encoding="utf-8")
|
||||
file_handler.setLevel(logging.INFO)
|
||||
|
||||
# Handler für die Konsole
|
||||
@@ -46,7 +47,7 @@ def setup_logger(log_dir: Path, name: str = 'app') -> logging.Logger:
|
||||
console_handler.setLevel(logging.INFO)
|
||||
|
||||
# Einheitliches Log-Format definieren
|
||||
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
|
||||
formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
|
||||
file_handler.setFormatter(formatter)
|
||||
console_handler.setFormatter(formatter)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user