Unittests zu allen Elementen erstellt
This commit is contained in:
+491
-372
@@ -1,13 +1,286 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from pydantic import BaseModel, Field, field_validator
|
||||
import re
|
||||
"""
|
||||
Gefaellestrecke — Modell und Hilfsfunktionen für Gefällestrecken.
|
||||
|
||||
Enthält das Pydantic-Modell und statische Methoden zur Erstellung
|
||||
von DXF-Geometrie für Gefällestrecken zwischen Fördererkomponenten.
|
||||
|
||||
Refactoring-Änderungen:
|
||||
- @staticmethod auf alle Methoden, die self nicht nutzen
|
||||
- Bug fix Zeile 112: am_kreisel == 1 → am_kreisel = 1
|
||||
- Duplizierte Logik (Zeilen 69–90 vs 121–141) in _bestimme_position/_bestimme_gefaelle extrahiert
|
||||
- rotation_mit_zwei_verbunden aufgeteilt in Hilfsfunktionen
|
||||
- hat_motor_umlenk_station aufgeteilt: _pruefe_motor_umlenk_an_kurve, _bestimme_tefkurve
|
||||
- ein_motor_oder_eine_umlenk aufgeteilt: _add_station_mit_bogen, _add_station_gerade
|
||||
- Magic Numbers durch Konstanten ersetzt
|
||||
- Dokumentation hinzugefügt
|
||||
"""
|
||||
import math
|
||||
from ezdxf.math import Matrix44
|
||||
from lib import plant2dxf
|
||||
import re
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from lib import block_methoden
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# KONSTANTEN
|
||||
# ============================================================================
|
||||
|
||||
ROTATION_MAP = {"oben": 0, "unten": 180, "links": 90, "rechts": 270}
|
||||
"""Zuordnung von Gefälle-Richtung zu Rotationswinkel in Grad."""
|
||||
|
||||
LAYER_SP = "6-SP"
|
||||
"""DXF-Layer für Seitenprofile."""
|
||||
|
||||
WINKEL_3_GRAD = 3
|
||||
"""Standard-Bogenwinkel in Grad."""
|
||||
|
||||
STATIONS_LAENGE = 500
|
||||
"""Länge einer Motor-/Umlenkstation in mm."""
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# HILFSFUNKTIONEN
|
||||
# ============================================================================
|
||||
|
||||
|
||||
def _bestimme_position(richtung, x0_kreisel, x1_kreisel, y0_kreisel, y1_kreisel, hight_position):
|
||||
"""
|
||||
Bestimmt die relative Position basierend auf Richtung und Kreiselkoordinaten.
|
||||
|
||||
Args:
|
||||
richtung: "Vertikal" oder "Horizontal"
|
||||
x0_kreisel, y0_kreisel: Koordinaten erstes Kreisel
|
||||
x1_kreisel, y1_kreisel: Koordinaten zweites Kreisel
|
||||
hight_position: "higher" oder "lower"
|
||||
|
||||
Returns:
|
||||
Position-String z.B. "higher_links", "lower_rechts"
|
||||
"""
|
||||
if richtung == "Vertikal":
|
||||
suffix = "_links" if x0_kreisel < x1_kreisel else "_rechts"
|
||||
else:
|
||||
suffix = "_higher" if y0_kreisel > y1_kreisel else "_lower"
|
||||
return hight_position + suffix
|
||||
|
||||
|
||||
def _bestimme_gefaelle(richtung, position):
|
||||
"""
|
||||
Bestimmt die Gefälle-Richtung basierend auf Richtung und Position.
|
||||
|
||||
Args:
|
||||
richtung: "Vertikal" oder "Horizontal"
|
||||
position: Position-String (z.B. "lower_rechts")
|
||||
|
||||
Returns:
|
||||
Gefälle-Richtung: "links", "rechts", "oben" oder "unten"
|
||||
"""
|
||||
if richtung == "Vertikal":
|
||||
return "links" if position in ("lower_rechts", "higher_links") else "rechts"
|
||||
elif richtung == "Horizontal":
|
||||
return "oben" if position in ("lower_lower", "higher_higher") else "unten"
|
||||
return "links" # Fallback für unbekannte Richtung
|
||||
|
||||
|
||||
def _tausche_drehungen_und_hoehe(drehung0, drehung1, hight_position):
|
||||
"""
|
||||
Tauscht Drehungen und invertiert die Höhe-Position.
|
||||
|
||||
Returns:
|
||||
(neue_drehung0, neue_drehung1, neue_hight_position)
|
||||
"""
|
||||
neue_hight = "lower" if hight_position == "higher" else "higher"
|
||||
return drehung1, drehung0, neue_hight
|
||||
|
||||
|
||||
def _bestimme_tefkurve(kurvenrichtung, tefkurve):
|
||||
"""
|
||||
Bestimmt die effektive Tefkurve-Richtung aus Kurvenrichtung und Tefkurve.
|
||||
|
||||
Args:
|
||||
kurvenrichtung: "links" oder "rechts"
|
||||
tefkurve: "außen" oder "innen"
|
||||
|
||||
Returns:
|
||||
"rechts" oder "links"
|
||||
"""
|
||||
if (kurvenrichtung == "links" and tefkurve == "außen") or (
|
||||
kurvenrichtung == "rechts" and tefkurve == "innen"
|
||||
):
|
||||
return "rechts"
|
||||
return "links"
|
||||
|
||||
|
||||
def _ist_umlenk_position(rotation, x, y, x_angetrieben, y_angetrieben):
|
||||
"""
|
||||
Prüft ob die Position eine Umlenkposition ist (gleiche-Höhe-Fall).
|
||||
|
||||
Basiert auf Rotationswinkel und relativer Position zur angetriebenen Strecke.
|
||||
|
||||
Args:
|
||||
rotation: Drehung in Grad
|
||||
x, y: Position des Gefällestreckens
|
||||
x_angetrieben, y_angetrieben: Position der angetriebenen Strecke
|
||||
|
||||
Returns:
|
||||
True wenn Umlenkposition, sonst False (Motorposition)
|
||||
"""
|
||||
rotation_zwischen = rotation if rotation != 0.0 else -360.0
|
||||
return (
|
||||
((-360.0 <= rotation_zwischen < -270.0) and y > y_angetrieben)
|
||||
or ((-90.0 < rotation < 0.0) and y > y_angetrieben)
|
||||
or ((-270.0 < rotation_zwischen < -90.0) and y < y_angetrieben)
|
||||
or (rotation == -90.0 and x < x_angetrieben)
|
||||
or (rotation == -270.0 and x < x_angetrieben)
|
||||
)
|
||||
|
||||
|
||||
def _normalize_deltas(*delta_lists):
|
||||
"""Setzt negative Werte in Delta-Listen auf positiv."""
|
||||
for delta_list in delta_lists:
|
||||
for i, val in enumerate(delta_list):
|
||||
if val < 0:
|
||||
delta_list[i] = abs(val)
|
||||
|
||||
|
||||
def _laedt_bogen_deltas(block_name, lib_doc, doc):
|
||||
"""
|
||||
Lädt Bogen-Delta-Attribute und normalisiert negative Werte.
|
||||
|
||||
Args:
|
||||
block_name: Name des Bogen-Blocks
|
||||
lib_doc: Bibliotheks-Dokument
|
||||
doc: Ziel-Dokument
|
||||
|
||||
Returns:
|
||||
Dict mit DELTA_SP_0 und DELTA_SP_1 als normalisierten Listen
|
||||
"""
|
||||
attrib = block_methoden.import_block(block_name, lib_doc, doc)
|
||||
deltas = {}
|
||||
for key in ("DELTA_SP_0", "DELTA_SP_1"):
|
||||
values = [float(v) for v in re.split(r"[;,]", attrib[key])]
|
||||
deltas[key] = [abs(v) if v < 0 else v for v in values]
|
||||
return deltas
|
||||
|
||||
|
||||
def _add_station_mit_bogen(
|
||||
block, bogen_block, station_block, position, x, y, hoehe,
|
||||
deltas_0, deltas_1, vorzeichen, rotation_bogen
|
||||
):
|
||||
"""
|
||||
Fügt Station mit Bogen-Übergang hinzu.
|
||||
|
||||
Args:
|
||||
block: DXF-Block zum Hinzufügen
|
||||
bogen_block: Blockname des Bogens
|
||||
station_block: Blockname der Station
|
||||
position: [x, y, z] aktuelle Position
|
||||
x, y: Offset-Koordinaten
|
||||
hoehe: Höhe des Gefälles
|
||||
deltas_0, deltas_1: Delta-Werte des Bogens [x, y, z]
|
||||
vorzeichen: -1 für Motor (Anfang), +1 für Umlenk (Ende)
|
||||
rotation_bogen: Rotation des Bogenblocks
|
||||
|
||||
Returns:
|
||||
Neue Position nach Station-Platzierung
|
||||
"""
|
||||
v = vorzeichen
|
||||
# Bogen hinzufügen
|
||||
block.add_blockref(
|
||||
bogen_block,
|
||||
(position[0] - x, position[1] + v * deltas_0[0] - y, position[2] + v * deltas_0[2] - hoehe),
|
||||
dxfattribs={"rotation": rotation_bogen},
|
||||
)
|
||||
# Position nach Bogen aktualisieren
|
||||
new_pos = [
|
||||
position[0],
|
||||
position[1] + v * (deltas_0[0] + deltas_1[0]),
|
||||
position[2] + v * (deltas_0[2] + deltas_1[2]),
|
||||
]
|
||||
# Station hinzufügen
|
||||
winkel_rad = math.radians(WINKEL_3_GRAD)
|
||||
block.add_blockref(
|
||||
station_block,
|
||||
(
|
||||
new_pos[0] - x,
|
||||
new_pos[1] + v * (STATIONS_LAENGE / 2) * math.cos(winkel_rad) - y,
|
||||
new_pos[2] + v * (STATIONS_LAENGE / 2) * math.sin(winkel_rad) - hoehe,
|
||||
),
|
||||
dxfattribs={"rotation": 270},
|
||||
)
|
||||
new_pos[1] += v * STATIONS_LAENGE * math.cos(winkel_rad)
|
||||
new_pos[2] += v * STATIONS_LAENGE * math.sin(winkel_rad)
|
||||
return new_pos
|
||||
|
||||
|
||||
def _add_station_gerade(block, station_block, position, x, y, hoehe, vorzeichen):
|
||||
"""
|
||||
Fügt Station ohne Bogen (gerade) hinzu.
|
||||
|
||||
Args:
|
||||
block: DXF-Block zum Hinzufügen
|
||||
station_block: Blockname der Station
|
||||
position: [x, y, z] aktuelle Position
|
||||
x, y: Offset-Koordinaten
|
||||
hoehe: Höhe des Gefälles
|
||||
vorzeichen: -1 für Motor, +1 für Umlenk
|
||||
|
||||
Returns:
|
||||
Neue Position nach Station-Platzierung
|
||||
"""
|
||||
v = vorzeichen
|
||||
block.add_blockref(
|
||||
station_block,
|
||||
(position[0] - x, position[1] + v * (STATIONS_LAENGE / 2) - y, position[2] - hoehe),
|
||||
dxfattribs={"rotation": 270},
|
||||
)
|
||||
new_pos = list(position)
|
||||
new_pos[1] += v * STATIONS_LAENGE
|
||||
return new_pos
|
||||
|
||||
|
||||
def _pruefe_motor_umlenk_an_kurve(
|
||||
upper_hoehe, lower_hoehe, vario_hoehe_0, vario_hoehe_1,
|
||||
rotation, x, y, x_angetrieben, y_angetrieben
|
||||
):
|
||||
"""
|
||||
Prüft ob Motor oder Umlenk an einer Kurve benötigt wird.
|
||||
|
||||
Args:
|
||||
upper_hoehe: Obere Höhe des Gefällestreckens
|
||||
lower_hoehe: Untere Höhe des Gefällestreckens
|
||||
vario_hoehe_0, vario_hoehe_1: Höhen der Nachbarn
|
||||
rotation: Drehung in Grad
|
||||
x, y: Position des Gefällestreckens
|
||||
x_angetrieben, y_angetrieben: Position der angetriebenen Strecke
|
||||
|
||||
Returns:
|
||||
(hat_motor, hat_umlenk, ist_gerade)
|
||||
"""
|
||||
if upper_hoehe > lower_hoehe:
|
||||
if vario_hoehe_0 == upper_hoehe or vario_hoehe_1 == upper_hoehe:
|
||||
return True, False, False
|
||||
return False, True, False
|
||||
elif upper_hoehe < lower_hoehe:
|
||||
if vario_hoehe_0 == lower_hoehe or vario_hoehe_1 == lower_hoehe:
|
||||
return True, False, False
|
||||
return False, True, False
|
||||
else: # Gleiche Höhe → Positionsbasierte Bestimmung
|
||||
ist_umlenk = _ist_umlenk_position(rotation, x, y, x_angetrieben, y_angetrieben)
|
||||
if ist_umlenk:
|
||||
return False, True, True
|
||||
return True, False, True
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# GEFAELLESTRECKE KLASSE
|
||||
# ============================================================================
|
||||
|
||||
|
||||
class Gefaellestrecke(BaseModel):
|
||||
"""Modell für Gefällestrecken zwischen Fördererkomponenten."""
|
||||
|
||||
teileid: str
|
||||
x: float = Field(description="X-Koordinate des Foerder-Zentrums")
|
||||
y: float = Field(description="Y-Koordinate des Foerder-Zentrums")
|
||||
@@ -20,12 +293,24 @@ class Gefaellestrecke(BaseModel):
|
||||
|
||||
@property
|
||||
def hight_zwischen(self):
|
||||
"""Mittlere Höhe zwischen h0 und h1."""
|
||||
return (self.h0 + self.h1) / 2
|
||||
|
||||
@classmethod
|
||||
def from_merkmale(
|
||||
cls, teileid: str, x: float, y: float, merkmale: dict
|
||||
) -> "Gefaellestrecke":
|
||||
"""
|
||||
Erstellt ein Gefaellestrecke-Objekt aus einem Merkmale-Dictionary.
|
||||
|
||||
Args:
|
||||
teileid: Teile-Identifikator
|
||||
x, y: Koordinaten in mm
|
||||
merkmale: Dictionary mit Eigenschaftswerten
|
||||
|
||||
Returns:
|
||||
Gefaellestrecke-Instanz
|
||||
"""
|
||||
h0 = float(merkmale.get("Höhe unten")) * 1000
|
||||
h1 = float(merkmale.get("Höhe oben")) * 1000
|
||||
laenge = float(merkmale.get("Länge in Meter")) * 1000
|
||||
@@ -41,16 +326,29 @@ class Gefaellestrecke(BaseModel):
|
||||
anzahl_separatoren=int(merkmale.get("Anzahl der Separatoren")),
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def erstehlung_von_gefalle_ohne_aussnahmen(
|
||||
msp, x, y, upper_hoehe_gefaelle, lower_hoehe_gefaelle, halbe_laenge, winkel
|
||||
):
|
||||
"""
|
||||
Zeichnet eine Gefällelinie ohne Motor-/Umlenk-Ausnahmen.
|
||||
|
||||
Args:
|
||||
msp: DXF-Modelspace
|
||||
x, y: Zentrum der Gefällelinie
|
||||
upper_hoehe_gefaelle: Höhe am oberen Ende
|
||||
lower_hoehe_gefaelle: Höhe am unteren Ende
|
||||
halbe_laenge: Halbe Länge der Strecke
|
||||
winkel: Rotationswinkel
|
||||
"""
|
||||
dx = halbe_laenge * math.sin(winkel * -1)
|
||||
dy = halbe_laenge * math.cos(winkel)
|
||||
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"
|
||||
line.dxf.layer = LAYER_SP
|
||||
|
||||
@staticmethod
|
||||
def rotation_mit_zwei_verbunden(
|
||||
gefaellestrecke_nachbarn,
|
||||
richtung2,
|
||||
@@ -59,6 +357,23 @@ class Gefaellestrecke(BaseModel):
|
||||
kreisel_verbunden,
|
||||
hight_position,
|
||||
):
|
||||
"""
|
||||
Berechnet Rotation wenn zwei Kreise verbunden sind.
|
||||
|
||||
Bestimmt die Gefälle-Richtung und passt Drehungen an,
|
||||
damit der 1. Kreisel in der Liste konsistent am Kreisel verbunden ist.
|
||||
|
||||
Args:
|
||||
gefaellestrecke_nachbarn: Dict mit Drehungen und Kreisel-Positionen
|
||||
richtung2: Richtung des zweiten Kreisels ("DEFAULT", "Vertikal", "Horizontal")
|
||||
richtung0: Richtung des ersten Kreisels
|
||||
am_kreisel: Kreisel-Index (0, 1 oder 2)
|
||||
kreisel_verbunden: Anzahl verbundener Kreisel
|
||||
hight_position: "higher" oder "lower"
|
||||
|
||||
Returns:
|
||||
(rotation, drehung0, drehung1, hight_position)
|
||||
"""
|
||||
drehung0 = gefaellestrecke_nachbarn.get("Drehung0")
|
||||
drehung1 = gefaellestrecke_nachbarn.get("Drehung1")
|
||||
x0_kreisel = float(gefaellestrecke_nachbarn.get("x0"))
|
||||
@@ -66,100 +381,44 @@ class Gefaellestrecke(BaseModel):
|
||||
x1_kreisel = float(gefaellestrecke_nachbarn.get("x1"))
|
||||
y1_kreisel = float(gefaellestrecke_nachbarn.get("y1"))
|
||||
|
||||
if richtung2 == "DEFAULT":
|
||||
if richtung0 == "Vertikal":
|
||||
if x0_kreisel < x1_kreisel:
|
||||
position = hight_position + "_links"
|
||||
else:
|
||||
position = hight_position + "_rechts"
|
||||
else:
|
||||
if y0_kreisel > y1_kreisel:
|
||||
position = hight_position + "_higher"
|
||||
else:
|
||||
position = hight_position + "_lower"
|
||||
# DEFAULT → richtung0 verwenden, sonst richtung2
|
||||
effektive_richtung = richtung0 if richtung2 == "DEFAULT" else richtung2
|
||||
|
||||
if richtung0 == "Vertikal":
|
||||
if position == "lower_rechts" or position == "higher_links":
|
||||
gefaelle = "links"
|
||||
else:
|
||||
gefaelle = "rechts"
|
||||
elif richtung0 == "Horizontal":
|
||||
if position == "lower_lower" or position == "higher_higher":
|
||||
gefaelle = "oben"
|
||||
else:
|
||||
gefaelle = "unten"
|
||||
# vertausch der drehung und der höhe für die namens gebung des blockes
|
||||
# Einheitliche Position- und Gefälle-Bestimmung (eliminiert Duplikation)
|
||||
position = _bestimme_position(
|
||||
effektive_richtung, x0_kreisel, x1_kreisel, y0_kreisel, y1_kreisel, hight_position
|
||||
)
|
||||
gefaelle = _bestimme_gefaelle(effektive_richtung, position)
|
||||
|
||||
if richtung2 == "DEFAULT":
|
||||
# Vertausch wenn Position rechts/lower und Drehungen verschieden
|
||||
if (
|
||||
(
|
||||
position == "higher_rechts"
|
||||
or position == "lower_rechts"
|
||||
or position == "higher_lower"
|
||||
or position == "lower_lower"
|
||||
)
|
||||
position in ("higher_rechts", "lower_rechts", "higher_lower", "lower_lower")
|
||||
and drehung0 != drehung1
|
||||
and am_kreisel == 0
|
||||
):
|
||||
drehung_2 = drehung0
|
||||
drehung0 = drehung1
|
||||
drehung1 = drehung_2
|
||||
if hight_position == "higher":
|
||||
hight_position = "lower"
|
||||
else:
|
||||
hight_position = "higher"
|
||||
drehung0, drehung1, hight_position = _tausche_drehungen_und_hoehe(
|
||||
drehung0, drehung1, hight_position
|
||||
)
|
||||
|
||||
# austausch der werte damit immer davon ausgehen dass der 1 kreisel in unserer Liste am Kreisel verbuden ist
|
||||
# Austausch damit der 1. Kreisel in der Liste am Kreisel verbunden ist
|
||||
if kreisel_verbunden == 1 and am_kreisel == 2:
|
||||
am_kreisel == 1
|
||||
drehung_2 = drehung0
|
||||
drehung0 = drehung1
|
||||
drehung1 = drehung_2
|
||||
if hight_position == "higher":
|
||||
hight_position = "lower"
|
||||
else:
|
||||
hight_position = "higher"
|
||||
am_kreisel = 1 # BUG FIX: war "am_kreisel == 1" (Vergleich statt Zuweisung)
|
||||
drehung0, drehung1, hight_position = _tausche_drehungen_und_hoehe(
|
||||
drehung0, drehung1, hight_position
|
||||
)
|
||||
else:
|
||||
if richtung2 == "Vertikal":
|
||||
if x0_kreisel < x1_kreisel:
|
||||
position = hight_position + "_links"
|
||||
else:
|
||||
position = hight_position + "_rechts"
|
||||
else:
|
||||
if y0_kreisel > y1_kreisel:
|
||||
position = hight_position + "_higher"
|
||||
else:
|
||||
position = hight_position + "_lower"
|
||||
|
||||
if richtung2 == "Vertikal":
|
||||
if position == "lower_rechts" or position == "higher_links":
|
||||
gefaelle = "links"
|
||||
else:
|
||||
gefaelle = "rechts"
|
||||
elif richtung2 == "Horizontal":
|
||||
if position == "lower_lower" or position == "higher_higher":
|
||||
gefaelle = "oben"
|
||||
else:
|
||||
gefaelle = "unten"
|
||||
# austausch der werte damit immer davon ausgehen dass der 1 kreisel in unserer Liste am Kreisel verbuden ist
|
||||
# Austausch wenn am_kreisel == 2
|
||||
if am_kreisel == 2:
|
||||
am_kreisel = 1
|
||||
drehung_2 = drehung0
|
||||
drehung0 = drehung1
|
||||
drehung1 = drehung_2
|
||||
if hight_position == "higher":
|
||||
hight_position = "lower"
|
||||
else:
|
||||
hight_position = "higher"
|
||||
# Erstellung der Rotation
|
||||
if gefaelle == "oben":
|
||||
rotation = 0
|
||||
elif gefaelle == "unten":
|
||||
rotation = 180
|
||||
elif gefaelle == "links":
|
||||
rotation = 90
|
||||
elif gefaelle == "rechts":
|
||||
rotation = 270
|
||||
drehung0, drehung1, hight_position = _tausche_drehungen_und_hoehe(
|
||||
drehung0, drehung1, hight_position
|
||||
)
|
||||
|
||||
rotation = ROTATION_MAP[gefaelle]
|
||||
return rotation, drehung0, drehung1, hight_position
|
||||
|
||||
@staticmethod
|
||||
def ein_motor_oder_eine_umlenk(
|
||||
x,
|
||||
y,
|
||||
@@ -179,37 +438,35 @@ class Gefaellestrecke(BaseModel):
|
||||
umlenk_gerade,
|
||||
motor_gerade,
|
||||
):
|
||||
"""
|
||||
Platziert Motor- und/oder Umlenkstation mit optionalen Bögen.
|
||||
|
||||
Args:
|
||||
x, y: Zentrum des Förderers
|
||||
start, ende: Start-/End-Punkt der Gefällelinie
|
||||
doc, lib_doc: DXF-Dokumente
|
||||
hoehe_gefaelle: Höhe der Gefällelinie
|
||||
block_Vario_Umlenkstation_500mm: Block-Name Umlenkstation rechts
|
||||
block_Vario_Motorstation_500mm: Block-Name Motorstation rechts
|
||||
blockname_motor_links: Block-Name Motorstation links
|
||||
blockname_umlenk_links: Block-Name Umlenkstation links
|
||||
hat_motor_0, hat_umlenk_0: Ob Motor/Umlenk vorhanden
|
||||
tefkurve_0: "links" oder "rechts"
|
||||
block: DXF-Block zum Hinzufügen
|
||||
umlenk_gerade, motor_gerade: Ob Station gerade (keine Bögen)
|
||||
|
||||
Returns:
|
||||
(start, ende) nach Platzierung
|
||||
"""
|
||||
# Bogen-Blöcke laden und Deltas extrahieren
|
||||
block_Vario_Bogen_auf = "Vario_Bogen_auf_3°"
|
||||
block_Vario_Bogen_ab = "Vario_Bogen_ab_3°"
|
||||
block_Vario_Bogen_auf_links = block_Vario_Bogen_auf + "_links"
|
||||
block_Vario_Bogen_ab_links = block_Vario_Bogen_ab + "_links"
|
||||
|
||||
ab_deltas = _laedt_bogen_deltas(block_Vario_Bogen_ab, lib_doc, doc)
|
||||
auf_deltas = _laedt_bogen_deltas(block_Vario_Bogen_auf, lib_doc, doc)
|
||||
|
||||
block_Vario_Bogen_auf = f"Vario_Bogen_auf_3°"
|
||||
block_Vario_Bogen_ab = f"Vario_Bogen_ab_3°"
|
||||
block_Vario_Bogen_auf_links = (f"Vario_Bogen_auf_3°") + "_links"
|
||||
block_Vario_Bogen_ab_links = (f"Vario_Bogen_ab_3°") + "_links"
|
||||
auf_attrib = block_methoden.import_block(block_Vario_Bogen_auf, lib_doc, doc)
|
||||
ab_attrib = block_methoden.import_block(block_Vario_Bogen_ab, lib_doc, doc)
|
||||
Vario_Bogen_auf_Delta_SP_0 = list(
|
||||
float(att) for att in re.split(r"[;,]", auf_attrib["DELTA_SP_0"])
|
||||
)
|
||||
Vario_Bogen_auf_Delta_SP_1 = list(
|
||||
float(att) for att in re.split(r"[;,]", auf_attrib["DELTA_SP_1"])
|
||||
)
|
||||
Vario_Bogen_ab_Delta_SP_0 = list(
|
||||
float(att) for att in re.split(r"[;,]", ab_attrib["DELTA_SP_0"])
|
||||
)
|
||||
Vario_Bogen_ab_Delta_SP_1 = list(
|
||||
float(att) for att in re.split(r"[;,]", ab_attrib["DELTA_SP_1"])
|
||||
)
|
||||
for i, wert in enumerate(Vario_Bogen_auf_Delta_SP_0):
|
||||
if wert < 0:
|
||||
Vario_Bogen_auf_Delta_SP_0[i] = abs(wert)
|
||||
for i, wert in enumerate(Vario_Bogen_auf_Delta_SP_1):
|
||||
if wert < 0:
|
||||
Vario_Bogen_auf_Delta_SP_1[i] = abs(wert)
|
||||
for i, wert in enumerate(Vario_Bogen_ab_Delta_SP_0):
|
||||
if wert < 0:
|
||||
Vario_Bogen_ab_Delta_SP_0[i] = abs(wert)
|
||||
for i, wert in enumerate(Vario_Bogen_ab_Delta_SP_1):
|
||||
if wert < 0:
|
||||
Vario_Bogen_ab_Delta_SP_1[i] = abs(wert)
|
||||
block_methoden.turn_two_blocks_left(
|
||||
doc,
|
||||
block_Vario_Bogen_auf,
|
||||
@@ -217,167 +474,71 @@ class Gefaellestrecke(BaseModel):
|
||||
block_Vario_Bogen_ab_links,
|
||||
block_Vario_Bogen_auf_links,
|
||||
)
|
||||
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_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_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_gefaelle),
|
||||
dxfattribs={"rotation": 270},
|
||||
)
|
||||
start[1] = start[1] - 500
|
||||
|
||||
# --- Motor-Station ---
|
||||
if hat_motor_0:
|
||||
ist_links = (tefkurve_0 == "links")
|
||||
# Motor: tefkurve "links" → bogen_links + station_links
|
||||
bogen_motor = block_Vario_Bogen_ab_links if ist_links else block_Vario_Bogen_ab
|
||||
station_motor = blockname_motor_links if ist_links else block_Vario_Motorstation_500mm
|
||||
station_motor_gerade = (
|
||||
"Vario_Motorstation_500mm_links" if ist_links else "Vario_Motorstation_500mm"
|
||||
)
|
||||
|
||||
if not motor_gerade:
|
||||
start = _add_station_mit_bogen(
|
||||
block, bogen_motor, station_motor, start,
|
||||
x, y, hoehe_gefaelle,
|
||||
ab_deltas["DELTA_SP_0"], ab_deltas["DELTA_SP_1"],
|
||||
vorzeichen=-1, rotation_bogen=270,
|
||||
)
|
||||
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_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_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_gefaelle),
|
||||
dxfattribs={"rotation": 270},
|
||||
)
|
||||
start[1] = start[1] - 500
|
||||
start = _add_station_gerade(
|
||||
block, station_motor_gerade, start,
|
||||
x, y, hoehe_gefaelle, vorzeichen=-1,
|
||||
)
|
||||
|
||||
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_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_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_gefaelle),
|
||||
dxfattribs={"rotation": 270},
|
||||
)
|
||||
ende[1] = ende[1] + 500
|
||||
# --- Umlenk-Station ---
|
||||
if hat_umlenk_0:
|
||||
ist_links = (tefkurve_0 == "links")
|
||||
# Umlenk: Bogen-Blockname ist INVERTIERT relativ zu tefkurve
|
||||
bogen_umlenk = block_Vario_Bogen_auf if ist_links else block_Vario_Bogen_auf_links
|
||||
station_umlenk = blockname_umlenk_links if ist_links else block_Vario_Umlenkstation_500mm
|
||||
station_umlenk_gerade = (
|
||||
"Vario_Umlenkstation_500mm_links" if ist_links else "Vario_Umlenkstation_500mm"
|
||||
)
|
||||
|
||||
if not umlenk_gerade:
|
||||
ende = _add_station_mit_bogen(
|
||||
block, bogen_umlenk, station_umlenk, ende,
|
||||
x, y, hoehe_gefaelle,
|
||||
auf_deltas["DELTA_SP_0"], auf_deltas["DELTA_SP_1"],
|
||||
vorzeichen=+1, rotation_bogen=90,
|
||||
)
|
||||
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_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_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_gefaelle),
|
||||
dxfattribs={"rotation": 270},
|
||||
)
|
||||
ende[1] = ende[1] + 500
|
||||
ende = _add_station_gerade(
|
||||
block, station_umlenk_gerade, ende,
|
||||
x, y, hoehe_gefaelle, vorzeichen=+1,
|
||||
)
|
||||
|
||||
return start, ende
|
||||
|
||||
@staticmethod
|
||||
def hat_motor_umlenk_station(gefaelle_objekt, gefaellestrecke_nachbarn):
|
||||
"""
|
||||
Analysiert Nachbar-Daten und bestimmt Motor-/Umlenkstation-Zuordnung.
|
||||
|
||||
Untersucht ob an jedem Ende der Gefällelinie eine Motorstation
|
||||
oder eine Umlenkstation angeschlossen ist.
|
||||
|
||||
Args:
|
||||
gefaelle_objekt: Gefaellestrecke-Instanz mit h0, h1, drehung, x, y
|
||||
gefaellestrecke_nachbarn: Dict mit Kurven- und Höhen-Informationen
|
||||
|
||||
Returns:
|
||||
Dict mit hat_motor_0/1, hat_umlenk_0/1, tefkurve_0/1,
|
||||
umlenk_gerade, motor_gerade
|
||||
"""
|
||||
hat_motor_0 = None
|
||||
hat_motor_1 = None
|
||||
hat_umlenk_0 = None
|
||||
@@ -392,111 +553,69 @@ class Gefaellestrecke(BaseModel):
|
||||
x = gefaelle_objekt.x
|
||||
y = gefaelle_objekt.y
|
||||
|
||||
if "Kurvenrichtung" in gefaellestrecke_nachbarn:
|
||||
vario_hoehe_0 = float(gefaellestrecke_nachbarn.get("vario_hoehe_0"))
|
||||
vario_hoehe_1 = float(gefaellestrecke_nachbarn.get("vario_hoehe_1"))
|
||||
kurvenrichtung = gefaellestrecke_nachbarn.get("Kurvenrichtung")
|
||||
tefkurve_0 = gefaellestrecke_nachbarn.get("Tefkurve")
|
||||
x_angetrieben = gefaellestrecke_nachbarn.get("X_angetrieben")
|
||||
y_angetrieben = gefaellestrecke_nachbarn.get("Y_angetrieben")
|
||||
if "Kurvenrichtung" not in gefaellestrecke_nachbarn:
|
||||
return {
|
||||
"hat_motor_0": hat_motor_0,
|
||||
"hat_motor_1": hat_motor_1,
|
||||
"hat_umlenk_0": hat_umlenk_0,
|
||||
"hat_umlenk_1": hat_umlenk_1,
|
||||
"tefkurve_0": tefkurve_0,
|
||||
"tefkurve_1": tefkurve_1,
|
||||
"umlenk_gerade": umlenk_gerade,
|
||||
"motor_gerade": motor_gerade,
|
||||
}
|
||||
|
||||
# --- Erster Nachbar ---
|
||||
vario_hoehe_0 = float(gefaellestrecke_nachbarn.get("vario_hoehe_0"))
|
||||
vario_hoehe_1 = float(gefaellestrecke_nachbarn.get("vario_hoehe_1"))
|
||||
kurvenrichtung = gefaellestrecke_nachbarn.get("Kurvenrichtung")
|
||||
tefkurve_0 = gefaellestrecke_nachbarn.get("Tefkurve")
|
||||
x_angetrieben = gefaellestrecke_nachbarn.get("X_angetrieben")
|
||||
y_angetrieben = gefaellestrecke_nachbarn.get("Y_angetrieben")
|
||||
|
||||
tefkurve_0 = _bestimme_tefkurve(kurvenrichtung, tefkurve_0)
|
||||
|
||||
hat_motor_0, hat_umlenk_0, ist_gerade_0 = _pruefe_motor_umlenk_an_kurve(
|
||||
upper_hoehe_gefaelle, lower_hoehe_gefaelle,
|
||||
vario_hoehe_0, vario_hoehe_1,
|
||||
rotation, x, y, x_angetrieben, y_angetrieben,
|
||||
)
|
||||
# Gerade-Flag nur setzen im gleiche-Höhe-Fall
|
||||
if ist_gerade_0:
|
||||
if hat_umlenk_0:
|
||||
umlenk_gerade = True
|
||||
if hat_motor_0:
|
||||
motor_gerade = True
|
||||
|
||||
# --- Zweiter Nachbar (falls vorhanden) ---
|
||||
if "Kurvenrichtung_1" in gefaellestrecke_nachbarn:
|
||||
vario_hoehe_0_1 = float(gefaellestrecke_nachbarn.get("vario_hoehe_0_1"))
|
||||
vario_hoehe_1_1 = float(gefaellestrecke_nachbarn.get("vario_hoehe_1_1"))
|
||||
kurvenrichtung_1 = gefaellestrecke_nachbarn.get("Kurvenrichtung_1")
|
||||
tefkurve_1 = gefaellestrecke_nachbarn.get("Tefkurve_1")
|
||||
x_angetrieben_1 = gefaellestrecke_nachbarn.get("X_angetrieben_1")
|
||||
y_angetrieben_1 = gefaellestrecke_nachbarn.get("Y_angetrieben_1")
|
||||
if (
|
||||
(kurvenrichtung == "links" and tefkurve_0 == "außen")
|
||||
or kurvenrichtung == "rechts"
|
||||
and tefkurve_0 == "innen"
|
||||
):
|
||||
tefkurve_0 = "rechts"
|
||||
else:
|
||||
tefkurve_0 = "links"
|
||||
|
||||
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_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
|
||||
else:
|
||||
rotation_zwischen = rotation
|
||||
if rotation_zwischen == 0.0:
|
||||
rotation_zwischen = -360.0
|
||||
if (
|
||||
((-360.0 <= rotation_zwischen < -270.0) and y > y_angetrieben)
|
||||
or ((-90.0 < rotation < 0.0) and y > y_angetrieben)
|
||||
or ((-270.0 < rotation_zwischen < -90.0) and y < y_angetrieben)
|
||||
or (rotation == -90.0 and x < x_angetrieben)
|
||||
or ((rotation == -270.0) and x < x_angetrieben)
|
||||
):
|
||||
hat_umlenk_0 = True
|
||||
tefkurve_1 = _bestimme_tefkurve(kurvenrichtung_1, tefkurve_1)
|
||||
|
||||
hat_motor_1, hat_umlenk_1, ist_gerade_1 = _pruefe_motor_umlenk_an_kurve(
|
||||
upper_hoehe_gefaelle, lower_hoehe_gefaelle,
|
||||
vario_hoehe_0_1, vario_hoehe_1_1,
|
||||
rotation, x, y, x_angetrieben_1, y_angetrieben_1,
|
||||
)
|
||||
if ist_gerade_1:
|
||||
if hat_umlenk_1:
|
||||
umlenk_gerade = True
|
||||
else:
|
||||
hat_motor_0 = True
|
||||
if hat_motor_1:
|
||||
motor_gerade = True
|
||||
|
||||
if "Kurvenrichtung_1" in gefaellestrecke_nachbarn:
|
||||
vario_hoehe_0_1 = float(gefaellestrecke_nachbarn.get("vario_hoehe_0_1"))
|
||||
vario_hoehe_1_1 = float(gefaellestrecke_nachbarn.get("vario_hoehe_1_1"))
|
||||
kurvenrichtung_1 = gefaellestrecke_nachbarn.get("Kurvenrichtung_1")
|
||||
tefkurve_1 = gefaellestrecke_nachbarn.get("Tefkurve_1")
|
||||
if (
|
||||
(kurvenrichtung_1 == "links" and tefkurve_1 == "außen")
|
||||
or kurvenrichtung_1 == "rechts"
|
||||
and tefkurve_1 == "innen"
|
||||
):
|
||||
tefkurve_1 = "rechts"
|
||||
else:
|
||||
tefkurve_1 = "links"
|
||||
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_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
|
||||
else:
|
||||
rotation_zwischen = rotation
|
||||
if rotation_zwischen == 0.0:
|
||||
rotation_zwischen = -360.0
|
||||
if (
|
||||
((-360.0 <= rotation_zwischen < -270.0) and y > y_angetrieben_1)
|
||||
or ((-90.0 < rotation < 0.0) and y > y_angetrieben_1)
|
||||
or (
|
||||
(-270.0 < rotation_zwischen < -90.0) and y < y_angetrieben_1
|
||||
)
|
||||
or (rotation == -90.0 and x < x_angetrieben_1)
|
||||
or ((rotation == -270.0) and x < x_angetrieben_1)
|
||||
):
|
||||
hat_umlenk_1 = True
|
||||
umlenk_gerade = True
|
||||
else:
|
||||
hat_motor_1 = True
|
||||
motor_gerade = True
|
||||
hat_zusatz = {}
|
||||
hat_zusatz["hat_motor_0"] = hat_motor_0
|
||||
hat_zusatz["hat_motor_1"] = hat_motor_1
|
||||
hat_zusatz["hat_umlenk_0"] = hat_umlenk_0
|
||||
hat_zusatz["hat_umlenk_1"] = hat_umlenk_1
|
||||
hat_zusatz["tefkurve_0"] = tefkurve_0
|
||||
hat_zusatz["tefkurve_1"] = tefkurve_1
|
||||
hat_zusatz["umlenk_gerade"] = umlenk_gerade
|
||||
hat_zusatz["motor_gerade"] = motor_gerade
|
||||
return hat_zusatz
|
||||
return {
|
||||
"hat_motor_0": hat_motor_0,
|
||||
"hat_motor_1": hat_motor_1,
|
||||
"hat_umlenk_0": hat_umlenk_0,
|
||||
"hat_umlenk_1": hat_umlenk_1,
|
||||
"tefkurve_0": tefkurve_0,
|
||||
"tefkurve_1": tefkurve_1,
|
||||
"umlenk_gerade": umlenk_gerade,
|
||||
"motor_gerade": motor_gerade,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user