diff --git a/doc/plant2dxf_dokumentation.md b/doc/plant2dxf_dokumentation.md index e0b3623..c95a628 100644 --- a/doc/plant2dxf_dokumentation.md +++ b/doc/plant2dxf_dokumentation.md @@ -1,5 +1,41 @@ # plant2dxf - Dokumentation +## ⚠️ Wichtiger Hinweis + +**Zukünftige Anpassungen erforderlich:** + +Aufgrund möglicher Änderungen im CSV-Dateiformat von RuleDesigner müssen in Zukunft möglicherweise folgende Berechnungen und Logiken angepasst werden: + +### AS/ES-Element-Berechnungen + +Die Logik zur Bestimmung und Platzierung von AS- und ES-Elementen bei Gefällestrecken und Vario-Förderern basiert auf dem aktuellen CSV-Format. Bei Änderungen der Datenstruktur oder der verfügbaren Informationen müssen folgende Methoden in `as_es_methoden.py` überprüft und angepasst werden: + +- `erstellung_gefaelle_block_verbunenden_am_einen()`: Erstellt AS/ES-Elemente für Gefällestrecken, die mit einem Kreisel verbunden sind +- `gefaellegerade_erstellung()`: Erstellt AS/ES-Elemente für Gefällestrecken, die mit zwei Kreiseln verbunden sind +- `am_kreisel_direct_verbunden()`: Prüft, ob eine Gefällestrecke/Vario-Förderer direkt mit einem Kreisel verbunden ist (ohne Stahlband) + +### Höhenvergleiche für Kreisel-Logik + +Die Höhenvergleiche zur Bestimmung der Verbindungsart zwischen Gefällestrecken/Vario-Förderern und Kreiseln (z.B. ob die Gefällestrecke mit dem höheren oder niedrigeren Teil des Kreisels verbunden ist) basieren auf den aktuellen CSV-Datenfeldern. Änderungen in der Struktur der Höheninformationen erfordern Anpassungen in: + +**Handler-Funktionen (`lib/plant2dxf.py`):** + +- `handle_ils_2_0_gefaellestrecke()`: Haupt-Handler für Gefällestrecken +- `handle_ils_2_0_variofoerderer()`: Haupt-Handler für Vario-Förderer + +**Gefällestrecke-Methoden (`lib/Elemente/Gefaehllestrecke.py`):** + +- `rotation_mit_zwei_verbunden()`: Berechnet Rotation bei Verbindung mit zwei Kreiseln (verwendet Höhenvergleiche) + +**Vario-Förderer-Methoden (`lib/Elemente/VarioFoerderer.py`):** +- `vario_verbuden_am_kreisel()`: Erstellt Gefällestrecken-Komponenten bei direkter Kreisel-Verbindung (verwendet Höhenvergleiche mit Kreiseln) + +**Betroffene Dateien:** +- `lib/as_es_methoden.py`: AS/ES-Element-Berechnungen +- `lib/plant2dxf.py`: Handler-Funktionen für Gefällestrecken und Vario-Förderer +- `lib/Elemente/Gefaehllestrecke.py`: Höhenvergleiche und Verbindungslogik +- `lib/Elemente/VarioFoerderer.py`: Höhenvergleiche und Verbindungslogik + ## Übersicht `plant2dxf` ist ein Python-Skript, das aus einer RuleDesigner-CSV-Datei DXF-Elemente erzeugt. Das Skript liest eine CSV-Datei mit Angaben über alle in einer Anlage enthaltenen Elemente und generiert daraus eine DXF-Datei der kompletten Anlage. diff --git a/lib/Elemente/Omniflo.py b/lib/Elemente/Omniflo.py index 4a04fa7..45e230d 100644 --- a/lib/Elemente/Omniflo.py +++ b/lib/Elemente/Omniflo.py @@ -9,14 +9,18 @@ class Omniflo(BaseModel): 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_separatoren: Optional [int] = Field(default=0, description="Anzahl der Separatoren") + @property + def hight_zwischen(self): + return ((self.h0 + self.h1) /2) @classmethod def from_merkmale(cls, teileid,x,y, merkmale): sivasnummer = merkmale.get("SivasNummer") @@ -40,6 +44,14 @@ class Omniflo(BaseModel): h1 = float(merkmale.get("Höhe oben")) except Exception: h1 = 0.0 + try: + anzahl_scanner = int(merkmale.get("Anzahl der Scanner", "0").replace(",", ".")) * 1000 # Meter → mm + except Exception: + anzahl_scanner = 0 + try: + anzahl_separatoren = float(merkmale.get("Anzahl der Separatoren", "0").replace(",", ".")) * 1000 # Meter → mm + except Exception: + anzahl_separatoren = 0 return cls( teileid= teileid, x=x, @@ -49,13 +61,17 @@ class Omniflo(BaseModel): drehung = winkel, hoehe = hoehe, h0 = h0, - h1 = h1 + h1 = h1, + anzahl_scanner = anzahl_scanner, + anzahl_separatoren = anzahl_separatoren ) - def Omniflo_geraden_erstellung(msp, x, y, doc, tefsivas, omniflo_objekt): + def Omniflo_geraden_erstellung(msp, doc, tefsivas, omniflo_objekt): """Erstellung der Tef gerade und Omniflo gerade""" winkel_rad = math.radians(omniflo_objekt.drehung) halbe_laenge = omniflo_objekt.laenge / 2 - # Man muss bei sin -1 machen wegen des links koordinaten system + x = omniflo_objekt.x + y = omniflo_objekt.y + # 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 ) @@ -69,15 +85,17 @@ class Omniflo(BaseModel): linie.dxf.layer = "F-1" else: linie.dxf.layer = "A-2" - def omniflo_foerdererstellung(msp, x, y, doc, lib_doc, omniflo_objekt, rotation): + 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) - + x = omniflo_objekt.x + y = omniflo_objekt.y + rotation = omniflo_objekt.drehung laenge = omniflo_objekt.laenge h0 = omniflo_objekt.h0 h1 = omniflo_objekt.h1 - h_zwischen = (h0 + h1)/2 + h_zwischen = omniflo_objekt.hight_zwischen blockname = (f"OF_Förderer_{laenge}_{h_zwischen}") winkel_rad = math.radians(rotation) halbe_laenge = laenge / 2 diff --git a/lib/Elemente/VarioFoerderer.py b/lib/Elemente/VarioFoerderer.py index ec6a539..8da439c 100644 --- a/lib/Elemente/VarioFoerderer.py +++ b/lib/Elemente/VarioFoerderer.py @@ -307,8 +307,12 @@ class VarioFoerderer(BaseModel): return winkel_VP_offset_vorne,winkel_VP_offset_hinten - def horizontale_ausrichtung(x, y, voerder_richtung, rotation, x0_kreisel, y0_kreisel): + def horizontale_ausrichtung(foerderer, x0_kreisel, y0_kreisel): """Schaut was für eine Ausrichtung der Horizontale Förder hat""" + voerder_richtung = foerderer.foerderer_richtung + rotation = foerderer.drehung + x = foerderer.x + y = foerderer.y # mit_horizontal_verbunden None als String für einen späteren vergleich mit_horizontal_verbunden = "None" if voerder_richtung == "Horizontal": diff --git a/lib/as_es_methoden.py b/lib/as_es_methoden.py index beb1134..6b0e9a2 100644 --- a/lib/as_es_methoden.py +++ b/lib/as_es_methoden.py @@ -111,8 +111,20 @@ def erstellung_gefaelle_block_verbunenden_am_einen(msp,x, y, doc, lib_doc, upper msp.add_blockref(block_es,(ende[0],ende[1]+esoffset_y,lower_hoehe_gefaehlle),dxfattribs={"rotation": as_es_rotation,"layer":layer,"color":color}) return True -def gefaellegerade_erstellung(x, y, doc, lib_doc, upper_hoehe_gefaehlle, lower_hoehe_gefaehlle, hoehe_gefaehlle,richtung2, drehung0, drehung1, laenge, hight_position, blockname,config, block_vario = None,voerder_richtung = None, am_kreisel = None, erster_kreisel_höher = None,y1=None,z1 =None): +def gefaellegerade_erstellung(objekt,doc, lib_doc,richtung2, drehung0, drehung1,hight_position, blockname,config, block_vario = None, am_kreisel = None, erster_kreisel_höher = None,y1=None,z1 =None): """erstellung des blockes falls die gefaelle strecke mit einem kreisel verbunden ist, mehrere variation von selben weil diese nötig sind sobald man die richtigen inserts bekommen""" + if hasattr(objekt,"foerderer_richtung"): + voerder_richtung = objekt.foerderer_richtung + else: + voerder_richtung = None + + laenge =objekt.laenge + upper_hoehe_gefaehlle = objekt.h1 + lower_hoehe_gefaehlle = objekt.h0 + x = objekt.x + y = objekt.y + hoehe_gefaehlle = objekt.hight_zwischen + asoffset = float(config.get("ILS 2.0 Gefällestrecke", "asoffset")) esoffset = float(config.get("ILS 2.0 Gefällestrecke", "esoffset")) winkel_as = float(config.get("Ils 2.0 core winkel", "winkel_as")) diff --git a/lib/plant2dxf.py b/lib/plant2dxf.py index 54dc5b7..1b48acf 100644 --- a/lib/plant2dxf.py +++ b/lib/plant2dxf.py @@ -97,10 +97,9 @@ def handle_ils_2_0_gefaellestrecke(msp, teileid, merkmale, x, y, doc, lib_doc, v doc.layers.add(name="6-SP", color=7) gefaelle_layer = "6-SP" verbunden_am_einen = False - richtung2 ="DEFAULT" unterschiedlich = False - anzahl_seperatoren_oder_scan(msp, x, y, doc, lib_doc, gefaelle_objekt, hoehe_gefaehlle, rotation) + anzahl_seperatoren_oder_scan(msp, doc, lib_doc, gefaelle_objekt) for nachbarn in strecken_nachbarn: if teileid == nachbarn.get("Id"): gefaellestrecke_nachbarn = nachbarn @@ -264,7 +263,7 @@ def handle_ils_2_0_gefaellestrecke(msp, teileid, merkmale, x, y, doc, lib_doc, v blockname = f"Ils_2.0_Gefaellestrecke_{laenge}_{hoehe_gefaehlle}_{drehung0}_{drehung1}_{hight_position}_{verbunden_am_einen}" else: blockname = f"Ils_2.0_Gefaellestrecke_{laenge}_{hoehe_gefaehlle}_{drehung0}_{drehung1}_{hight_position}_{unterschiedlich}_{richtung2}_{verbunden_am_einen}" - as_es_methoden.gefaellegerade_erstellung(x, y, doc, lib_doc, upper_hoehe_gefaehlle, lower_hoehe_gefaehlle, hoehe_gefaehlle,richtung2,drehung0, drehung1, laenge, hight_position,blockname,config) + as_es_methoden.gefaellegerade_erstellung(gefaelle_objekt, doc, lib_doc,richtung2,drehung0, drehung1, hight_position,blockname,config) bref =msp.add_blockref(blockname,(x,y,hoehe_gefaehlle),dxfattribs={"rotation": rotation, "layer": gefaelle_layer}) a = bref.add_attrib( tag= "NAME", @@ -337,7 +336,7 @@ def handle_ils_2_0_variofoerderer(msp, teileid, merkmale, x, y, doc, lib_doc, ve upper_hoehe_vario= foerderer.h1 lower_hoehe_vario = foerderer.h0 hoehe_vario= foerderer.hight_zwischen - anzahl_seperatoren_oder_scan(msp, x, y, doc, lib_doc, foerderer, hoehe_vario, rotation) + anzahl_seperatoren_oder_scan(msp, doc, lib_doc, foerderer) as_es_methoden.vertausch_der_höhe(foerderer) upper_hoehe_vario = foerderer.h1 lower_hoehe_vario = foerderer.h0 @@ -364,7 +363,7 @@ def handle_ils_2_0_variofoerderer(msp, teileid, merkmale, x, y, doc, lib_doc, ve ein_kreisel_höher = True else: ein_kreisel_höher = False - mit_horizontal_verbunden = VarioFoerderer.VarioFoerderer.horizontale_ausrichtung(x, y, voerder_richtung, rotation, x0_eckrad, y0_eckrad) + mit_horizontal_verbunden = VarioFoerderer.VarioFoerderer.horizontale_ausrichtung(foerderer, x0_eckrad, y0_eckrad) blockname = (f"Vario_Foerderer_{winkel}_{voerder_richtung}_{laenge}_{hoehe_vario}_rechts_{ein_kreisel_höher}_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}_{mit_horizontal_verbunden}") block_name_links = (f"Vario_Foerderer_{winkel}_{voerder_richtung}_{laenge}_{hoehe_vario}_links_{ein_kreisel_höher}_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}_{mit_horizontal_verbunden}") if blockname not in doc.blocks: @@ -418,7 +417,7 @@ def handle_ils_2_0_variofoerderer(msp, teileid, merkmale, x, y, doc, lib_doc, ve richtung0 = float(gefaellestrecke_vario.get("rotation0")) richtung_rad0= math.radians(richtung0) - mit_horizontal_verbunden = VarioFoerderer.VarioFoerderer.horizontale_ausrichtung(x, y, voerder_richtung, rotation, x0_kreisel, y0_kreisel) + mit_horizontal_verbunden = VarioFoerderer.VarioFoerderer.horizontale_ausrichtung(foerderer, x0_kreisel, y0_kreisel) am_kreisel,kreseil_verbunden =as_es_methoden.am_kreisel_direct_verbunden(x, y, upper_hoehe_vario, lower_hoehe_vario, x0_kreisel, y0_kreisel, richtung_rad0, abstand0, dx, dy, None, None, None, None ) if am_kreisel == 1: # Erstellung der blockname für wenn die Motorstation rechts und links @@ -565,7 +564,7 @@ def handle_ils_2_0_variofoerderer(msp, teileid, merkmale, x, y, doc, lib_doc, ve # Schauen welche es oder as element man braucht man braucht und diese in den block einfügen # Entnehmen von start und end Werte für spätere vario erstellung - start, ende = as_es_methoden.gefaellegerade_erstellung(x, y, doc, lib_doc, upper_hoehe_vario, lower_hoehe_vario, hoehe_vario,richtung2, drehung0, drehung1, laenge, None, blockname,config,block_vario,voerder_richtung, am_kreisel,erster_kreisel_höher,y1,z1) + start, ende = as_es_methoden.gefaellegerade_erstellung(foerderer, doc, lib_doc,richtung2, drehung0, drehung1, None, blockname,config,block_vario, am_kreisel,erster_kreisel_höher,y1,z1) # Erstellung der Vario gefälle selber VarioFoerderer.VarioFoerderer.vario_erstellung(foerderer, doc, lib_doc, config, block_vario,block_name_links, start, ende,voerder_richtung ,winkel_VP_offset_vorne,winkel_VP_offset_hinten) # Reintuen des endblockes in den Modelspace @@ -593,7 +592,7 @@ def handle_ils_2_0_variofoerderer(msp, teileid, merkmale, x, y, doc, lib_doc, ve # Schauen welche es oder as element man braucht man braucht und diese in den block einfügen # Entnehmen von start und end Werte für spätere vario erstellung - start, ende = as_es_methoden.gefaellegerade_erstellung(x, y, doc, lib_doc, upper_hoehe_vario, lower_hoehe_vario, hoehe_vario,richtung2, drehung0, drehung1, laenge, None, blockname,config,block_vario,voerder_richtung) + start, ende = as_es_methoden.gefaellegerade_erstellung(foerderer, doc, lib_doc,richtung2, drehung0, drehung1, None, blockname,config,block_vario) # Erstellung des Vario selber VarioFoerderer.VarioFoerderer.vario_erstellung(foerderer, doc, lib_doc, config, block_vario,block_name_links, start, ende,voerder_richtung,winkel_VP_offset_vorne,winkel_VP_offset_hinten ) # Reintuen des endblockes in den Modelspace @@ -689,10 +688,12 @@ def handle_omniflo(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols, omniflo_objekt = Omniflo.Omniflo.from_merkmale(teileid,x,y,merkmale) rotation = omniflo_objekt.drehung if omniflo_objekt.sivasnummer == omnisivas or omniflo_objekt.sivasnummer == tefsivas: - Omniflo.Omniflo.Omniflo_geraden_erstellung(msp, x, y, doc, tefsivas, omniflo_objekt) - + Omniflo.Omniflo.Omniflo_geraden_erstellung(msp, doc, tefsivas, omniflo_objekt) + if omniflo_objekt.sivasnummer == omnisivas: + anzahl_seperatoren_oder_scan(msp, doc, lib_doc, omniflo_objekt) elif omniflo_objekt.sivasnummer == foerderer: - Omniflo.Omniflo.omniflo_foerdererstellung(msp, x, y, doc, lib_doc, omniflo_objekt, rotation) + Omniflo.Omniflo.omniflo_foerdererstellung(msp, doc, lib_doc, omniflo_objekt) + return # Sonst wie gehabt: Block mit SivasNummer else: if not lib_doc: @@ -710,10 +711,14 @@ def handle_omniflo(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols, layer, color = block_methoden.get_insert_color_layer(lib_doc, omniflo_objekt.sivasnummer) msp.add_blockref(blockname, (x, y,omniflo_objekt.hoehe), dxfattribs={"rotation": rotation,"layer": layer, "color": color}) -def anzahl_seperatoren_oder_scan(msp, x, y, doc, lib_doc, klassen_objekt, hoehe, rotation): +def anzahl_seperatoren_oder_scan(msp, doc, lib_doc, klassen_objekt): """Importiert alle seperatoren und/oder scanner für das nötige objekt""" separatoren = klassen_objekt.anzahl_separatoren scanner = klassen_objekt.anzahl_scanner + x = klassen_objekt.x + y = klassen_objekt.y + hoehe =klassen_objekt.hight_zwischen + rotation = klassen_objekt.drehung # Schauen welche Ausrichtung das Objekt hat, damit man die Separtoren unbd Scanner nicht in das Objekt tut if rotation == 0 or rotation == -180: ausrichtung = "V"