feat: Kettenfoerderer (Schraegfoerderer Stahl) als parametrische 3D-Baugruppe
Neues Modul KettenFoerderer.lsp: baut aus KF_UM_<winkel>, KF_LAENGE und KF_AN_<winkel> (je KS_AUS auf KS_EIN) plus der Draufsicht KF_2D einen Block KF_<n>. Die Bausteine werden aufgerichtet eingebaut (Rz*Rx(90)*Rz), die Hoehe laeuft in Z; KF_2D liegt deckungsgleich mit der Kette. Der Einbauwinkel jedes Folgebausteins wird aus der Richtung des KS_AUS seines Vorgaengers gemessen, KF_LAENGE ueber die Einbauhoehe skaliert. - Dialog (DCL-Vorlage, Typ als Radiobuttons), Hoehe per Zahl oder aus zwei Punkten, Doppelklick auf KF_n oeffnet KF_EDIT mit Neuaufbau - eigenstaendiges Attribut-Schema, Auswahllisten mit Sivas-Optionstexten in data/json/kettenfoerderer.json - Sivas-Export: Merkmale 350, 353-357, 359-361, 391, baugleiche Foerderer werden zu einer Zeile zusammengefasst (Artikelnummer 6120) - ssg_ks_insert.lsp: neue Primitiven ks-xy-winkel, ks-block-messen, insert-block-ks-skaliert und insert-block-ks-matrix (freie 3x3-Rotation); ensure-block-loaded nimmt Bloecke ohne Dimensionssuffix unveraendert - Menueeintrag KettenFoerderer aktiviert, toter Dummy OMNI_KettenFoerderer entfernt; KF_* im Export-Pattern, in der ID-Vergabe und im Dispatcher SSG_BLOCKEDIT (vor dem Omniflo-Zweig) - Unit-Tests tu-tests-kf fuer die reinen Rechenkerne; Modul wird in der MNL vorgeladen, dbg-Schalter kf-zeit zur Laufzeitmessung Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -101,6 +101,18 @@ def get_id(block):
|
||||
# Sprachdatei, da rein Sivas-seitig.
|
||||
GERUEST_TYP_ANZEIGE = sivas_mapping.load_flat_mapping("geruest_typ_anzeige")
|
||||
|
||||
# Kettenfoerderer: Attribut WINKEL fuehrt den Neigungswinkel als nackte Zahl
|
||||
# ("26"/"30"), Sivas-Merkmal 359 erwartet den Optionstext mit Gradzeichen.
|
||||
# Gleiche Bauart und derselbe Grund wie GERUEST_TYP_ANZEIGE.
|
||||
KF_TYP_ANZEIGE = sivas_mapping.load_flat_mapping("kf_typ_anzeige")
|
||||
|
||||
# TeileArt-Spalte der Kettenfoerderer-Zeilen. Fester Wert statt Block-Attribut:
|
||||
# er ist fuer jeden Kettenfoerderer gleich, stuende also an jedem Block nur
|
||||
# redundant herum. Die Erkennung laeuft ueber den Blocknamen
|
||||
# (pattern_kettenfoerderer), nicht ueber TEILEART. Ein Block, der das Attribut
|
||||
# doch mitbringt (Altbestand), hat weiterhin Vorrang.
|
||||
KF_TEILEART = "Schraegfoerderer Stahl"
|
||||
|
||||
SEPARATOR_BEARBEITUNG_ANZEIGE = "ohne HARTCOAT HRC 50 ± 5"
|
||||
|
||||
# Sivas-Merkmale "Streckengruppe - Variofoerderer 001..005 - Hoehe in Meter".
|
||||
@@ -113,6 +125,12 @@ def geruest_typ_anzeige(wert):
|
||||
return GERUEST_TYP_ANZEIGE.get(wert, wert)
|
||||
|
||||
|
||||
def kf_typ_anzeige(wert):
|
||||
"""Wandelt den Kettenfoerderer-Winkel ("26"/"30") in die Sivas-Anzeige
|
||||
zu Merkmal 359 um ("Schrägförderer Stahl 26°")."""
|
||||
return KF_TYP_ANZEIGE.get(str(wert).strip(), wert)
|
||||
|
||||
|
||||
def ja_nein(flag_1_0):
|
||||
"""Wandelt ein "0"/"1"-Attribut in die Sivas-Anzeige "Ja"/"Nein" um."""
|
||||
return "Ja" if flag_1_0 == "1" else "Nein"
|
||||
@@ -191,6 +209,7 @@ def es_seite(wert, attribs):
|
||||
TRANSFORMS = {
|
||||
"ja_nein": ja_nein,
|
||||
"geruest_typ_anzeige": geruest_typ_anzeige,
|
||||
"kf_typ_anzeige": kf_typ_anzeige,
|
||||
"mm_zu_m": mm_zu_m,
|
||||
"as_es_vorhanden": as_es_vorhanden,
|
||||
"as_es_winkel": as_es_winkel,
|
||||
@@ -275,6 +294,42 @@ def eckrad_signature(block):
|
||||
)
|
||||
|
||||
|
||||
def kettenfoerderer_signature(block):
|
||||
"""
|
||||
Schluessel zur Gruppierung gleichartiger Kettenfoerderer (KF_n): baugleiche
|
||||
Bloecke landen in EINER Sivas-Zeile, deren Anzahl das Merkmal 353 ("Anzahl
|
||||
der gleichen Schraegfoerderer") traegt.
|
||||
|
||||
In den Schluessel gehoert JEDES Attribut, aus dem ein Merkmal der Zeile
|
||||
entsteht - sonst verschmelzen zwei unterschiedlich ausgefuehrte Foerderer
|
||||
zu einer Zeile, und die Merkmale des ERSTEN Blocks gelten fuer beide
|
||||
(gleiche Ueberlegung wie bei gefaellestrecke_signature/as_es_signatur).
|
||||
Die Kommentare nennen darum je Attribut die Merkmalnummer; einzige
|
||||
Ausnahme ist 353, das erst aus der Gruppengroesse entsteht.
|
||||
|
||||
Das ist zugleich die Voraussetzung dafuer, dass items_zusammenfassen (fuer
|
||||
die _zusammengefasst.csv) zwei KF-Zeilen NIE verschmelzen kann: gleiche
|
||||
Merkmale wuerden schon hier dieselbe Gruppe ergeben. Sonst wuerde dort
|
||||
"anzahl" addiert, waehrend 353 unveraendert stehen bliebe.
|
||||
|
||||
Die Laenge des Zwischenstuecks (L_KF_mm) ist eine FOLGE der Einbauhoehe und
|
||||
steht darum nicht eigens im Schluessel.
|
||||
"""
|
||||
attribs = block.get("attribs", {})
|
||||
return (
|
||||
attribs.get("WINKEL", "26"), # 359
|
||||
attribs.get("STANDARD_STEUERUNG", "0"), # 361
|
||||
attribs.get("FOERDERERTYP", ""), # 350
|
||||
attribs.get("H_EINBAUHOEHE_mm", "0"), # 360
|
||||
attribs.get("FARBE", ""), # 354
|
||||
attribs.get("ANTRIEBSMOTOR", ""), # 355
|
||||
attribs.get("ANTRIEBSART", ""), # 357
|
||||
attribs.get("MOVIMOT", "0"), # 356
|
||||
attribs.get("VERBINDUNGSELEMENTE", "Nein"), # 391
|
||||
attribs.get("ARTINR", ""),
|
||||
)
|
||||
|
||||
|
||||
def gefaellestrecke_signature(block):
|
||||
"""
|
||||
Schluessel zur Gruppierung gleichartiger Gefaellestrecken: Bloecke mit
|
||||
@@ -404,6 +459,7 @@ SIVAS_MAPPING_KREISEL = sivas_mapping.load_section_mapping("kreisel")
|
||||
SIVAS_MAPPING_ECKRAD = sivas_mapping.load_section_mapping("eckrad")
|
||||
SIVAS_MAPPING_GERUEST = sivas_mapping.load_section_mapping("geruest")
|
||||
SIVAS_MAPPING_WEICHEN = sivas_mapping.load_section_mapping("weichen")
|
||||
SIVAS_MAPPING_KETTENFOERDERER = sivas_mapping.load_section_mapping("kettenfoerderer")
|
||||
|
||||
|
||||
def build_kreisel_details(block):
|
||||
@@ -431,6 +487,21 @@ def build_eckrad_details(block):
|
||||
return sivas_mapping.anwenden(SIVAS_MAPPING_ECKRAD, attribs, TRANSFORMS)
|
||||
|
||||
|
||||
def build_kettenfoerderer_details(block, anzahl=1):
|
||||
"""Merkmale-Dict fuer eine Gruppe baugleicher Kettenfoerderer (KF_n,
|
||||
Lisp/KettenFoerderer.lsp).
|
||||
|
||||
350/359/354/356/360/391 kommen flach aus cfg/sivas.cfg [kettenfoerderer].
|
||||
353 ("Anzahl der gleichen Schraegfoerderer") entsteht erst hier aus der
|
||||
Gruppengroesse und kann darum nicht im Mapping stehen - gleiche Bauart wie
|
||||
3510/3512 beim Kreisel.
|
||||
"""
|
||||
attribs = block.get("attribs", {})
|
||||
details = sivas_mapping.anwenden(SIVAS_MAPPING_KETTENFOERDERER, attribs, TRANSFORMS)
|
||||
details["353"] = str(anzahl)
|
||||
return details
|
||||
|
||||
|
||||
# def build_geruest_details(block):
|
||||
#"""Merkmale-Dict fuer eine GR_-Geruest-Baugruppe (siehe pattern_geruest in
|
||||
#cfg/export.cfg, GeruestInsert.lsp *geruest-attrib-defs*). ARTINR/
|
||||
@@ -549,6 +620,8 @@ def process_blocks(blocks, anzahl_weichen_ils=0):
|
||||
btmt_beladung_ids = [] # IDs aller BTMT-Beladung*-Bloecke (eine gruppierte Zeile)
|
||||
btmt_entladung_ids = [] # IDs aller SC_Entladung*-Bloecke (eine gruppierte Zeile)
|
||||
geruest_list = [] # Liste von GR_-Geruest-Baugruppenbloecken, je einer Zeile
|
||||
# Kettenfoerderer: kettenfoerderer_signature(block) -> {"block", "ids", "anzahl"}
|
||||
kettenfoerderer_groups = {}
|
||||
|
||||
counters = {
|
||||
"anzahl_kreisel": 0,
|
||||
@@ -571,6 +644,7 @@ def process_blocks(blocks, anzahl_weichen_ils=0):
|
||||
"anzahl_btbeladung": 0,
|
||||
"anzahl_abwurfstationen": 0,
|
||||
"anzahl_geruest": 0,
|
||||
"anzahl_kettenfoerderer": 0,
|
||||
}
|
||||
|
||||
for block in blocks:
|
||||
@@ -620,6 +694,22 @@ def process_blocks(blocks, anzahl_weichen_ils=0):
|
||||
counters["anzahl_geruest"] += 1
|
||||
continue
|
||||
|
||||
# --- Kettenfoerderer / Schraegfoerderer Stahl (KF_n) ---
|
||||
# MUSS vor dem allgemeinen Omniflo-Zweig stehen: die KF-Baugruppe
|
||||
# traegt TEILEART "Omniflo Kettenfoerderer ..." und wuerde dort sonst
|
||||
# ueber ARTINR aufgeloest - ihre eigenen Merkmale (350/353/354/356/
|
||||
# 359/360/391) gingen dabei verloren. Anders als das Geruest werden
|
||||
# BAUGLEICHE Foerderer zu einer Zeile zusammengefasst, weil Merkmal
|
||||
# 353 genau diese Stueckzahl verlangt.
|
||||
if matches_any(bname, BLOCKPATTERNS.get("pattern_kettenfoerderer", [])):
|
||||
sig = kettenfoerderer_signature(block)
|
||||
if sig not in kettenfoerderer_groups:
|
||||
kettenfoerderer_groups[sig] = {"block": block, "ids": [], "anzahl": 0}
|
||||
kettenfoerderer_groups[sig]["anzahl"] += 1
|
||||
kettenfoerderer_groups[sig]["ids"].append(get_id(block))
|
||||
counters["anzahl_kettenfoerderer"] += 1
|
||||
continue
|
||||
|
||||
# --- Omniflo Gerade (AP110) ---
|
||||
# VOR dem allgemeinen Omniflo-Zweig: Geraden tragen ggf. ebenfalls
|
||||
# TEILEART "Omniflo ...", brauchen aber die Laengensumme.
|
||||
@@ -886,6 +976,31 @@ def process_blocks(blocks, anzahl_weichen_ils=0):
|
||||
})
|
||||
nr += 1
|
||||
|
||||
# Kettenfoerderer / Schraegfoerderer Stahl (KF_n) - eine Zeile je Gruppe
|
||||
# BAUGLEICHER Foerderer, deren Groesse als Merkmal 353 mitgefuehrt wird.
|
||||
# Die Sivasnr kommt - wie beim Geruest - aus dem ARTINR-Attribut (gepflegt
|
||||
# als "sivas_id" je Variante in data/json/kettenfoerderer.json); ist dort
|
||||
# nichts hinterlegt, bleibt die Spalte leer und die Zeile traegt allein
|
||||
# ihre Merkmale. Die drei Bausteine des Foerderers (Umlenkstation,
|
||||
# skaliertes Zwischenstueck, Antriebsstation) bekommen KEINE eigenen
|
||||
# Zeilen - der Schraegfoerderer ist in Sivas EIN Artikel.
|
||||
for gruppe in kettenfoerderer_groups.values():
|
||||
block = gruppe["block"]
|
||||
attribs = block.get("attribs", {})
|
||||
items.append({
|
||||
"nr": nr,
|
||||
"teileart": attribs.get("TEILEART") or attribs.get("FOERDERERTYP") or KF_TEILEART,
|
||||
"sivasnr": attribs.get("ARTINR", ""),
|
||||
"sivasnr_quoted": True,
|
||||
"bezeichnung": attribs.get("Bezeichnung", ""),
|
||||
"dispgruppe": 20,
|
||||
"anzahl": gruppe["anzahl"],
|
||||
"laenge_mm": attribs.get("L_KF_mm", ""),
|
||||
"ids": gruppe["ids"],
|
||||
"details": build_kettenfoerderer_details(block, gruppe["anzahl"]),
|
||||
})
|
||||
nr += 1
|
||||
|
||||
# VarioFoerderer-Compound-Bloecke (VF_N) - je Block eine eigene Zeile mit
|
||||
# vollstaendigen Gefaelle-/Angetrieben-Teilgruppen (immer TYP "Streckengruppe").
|
||||
for block in vario_list:
|
||||
|
||||
Reference in New Issue
Block a user