From 3f916a6fedce81e9bd2a0c7a9499b1c9983eb79d Mon Sep 17 00:00:00 2001 From: Michael Stangl Date: Wed, 22 Jul 2026 11:25:09 +0200 Subject: [PATCH 1/6] Kreisel: Attribut Geruest_Einzelmodul hinzugefuegt (Erzeugung, Edit-Dialog, Export) Jeder Kreisel bekommt bei der Erzeugung das neue Attribut GERUEST_EINZELMODUL (Default false), im KreiselEdit-Dialog per Checkbox "Geruest fuer Einzelmodul" umschaltbar. Fliesst als echter JSON-Bool ins details-Feld von EXPORTSIVAS/ EXPORTCSV und wird bei der Sivas-Gruppierung gleichartiger Kreisel beruecksichtigt. --- Lisp/KreiselInsert.lsp | 9 +++++- dcl/kreisel_edit.dcl | 5 +++ lib/export_csv.py | 1 + lib/export_sivas.py | 72 +++++++++++++++++++++++++++++++----------- 4 files changed, 68 insertions(+), 19 deletions(-) diff --git a/Lisp/KreiselInsert.lsp b/Lisp/KreiselInsert.lsp index d4dde50..ee48fd5 100644 --- a/Lisp/KreiselInsert.lsp +++ b/Lisp/KreiselInsert.lsp @@ -82,6 +82,7 @@ ("ABSTAND" "2300") ("NUMMER" "0") ("HOEHE" "0") + ("GERUEST_EINZELMODUL" "0") ("ID" "")) ) @@ -856,7 +857,7 @@ (defun c:KreiselEdit ( / sel ss ent ed attribs basePoint rotation dcl-pfad dat ergebnis dlg-name dlg-abstand dlg-hoehe dlg-ausrichtung - dlg-drehrichtung dlg-kreiselart + dlg-drehrichtung dlg-kreiselart dlg-geruest-einzelmodul newAbstand newRotation ausrichtLabels) ;; Implied Selection VOR ssg-start pruefen (ssg-start hebt Selektion auf) @@ -951,6 +952,9 @@ (end_list) (set_tile "kreiselart" (if (equal (cdr (assoc "KREISELART" attribs)) "PIN") "1" "0")) + (set_tile "geruest_einzelmodul" + (if (equal (cdr (assoc "GERUEST_EINZELMODUL" attribs)) "1") "1" "0")) + ;; Actions (action_tile "accept" (strcat @@ -960,6 +964,7 @@ "(setq dlg-ausrichtung (get_tile \"ausrichtung\"))" "(setq dlg-drehrichtung (get_tile \"drehrichtung\"))" "(setq dlg-kreiselart (get_tile \"kreiselart\"))" + "(setq dlg-geruest-einzelmodul (get_tile \"geruest_einzelmodul\"))" "(done_dialog 1)" ) ) @@ -986,6 +991,8 @@ (setq attribs (subst (cons "DREHRICHTUNG" (if (= dlg-drehrichtung "1") "GUZ" "UZS")) (assoc "DREHRICHTUNG" attribs) attribs)) + (setq attribs (subst (cons "GERUEST_EINZELMODUL" dlg-geruest-einzelmodul) + (assoc "GERUEST_EINZELMODUL" attribs) attribs)) ;; Alten Block loeschen (command "_.ERASE" ent "") diff --git a/dcl/kreisel_edit.dcl b/dcl/kreisel_edit.dcl index b715316..82801b7 100644 --- a/dcl/kreisel_edit.dcl +++ b/dcl/kreisel_edit.dcl @@ -47,6 +47,11 @@ kreisel_edit : dialog { } } + : toggle { + key = "geruest_einzelmodul"; + label = "Geruest fuer Einzelmodul"; + } + } ok_cancel; diff --git a/lib/export_csv.py b/lib/export_csv.py index 4865dce..d1a6b4c 100644 --- a/lib/export_csv.py +++ b/lib/export_csv.py @@ -215,6 +215,7 @@ def build_kreisel_merkmale(block): "Drehrichtung": attribs.get("DREHRICHTUNG", "UZS"), "Drehung": block.get("rotation", 0.0), "Name": attribs.get("Bezeichnung", ""), + "Geruest fuer Einzelmodul": attribs.get("GERUEST_EINZELMODUL", "0") == "1", } diff --git a/lib/export_sivas.py b/lib/export_sivas.py index c0a1739..8036362 100644 --- a/lib/export_sivas.py +++ b/lib/export_sivas.py @@ -4,16 +4,20 @@ export_sivas.py - Erzeugt Sivas-Export-CSV mit gruppierten Zeilen und Summierungszeilen. Neues CSV-Format: - Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];details + Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];IDs;details - Bezeichnung: Wert des Attributs "Bezeichnung" (Kreisel/Eckrad/VF/GF/Strecke). Bei gruppierten Zeilen (mehrere Bloecke je Zeile) kommasepariert. Bei Omniflo-Zeilen (Bogen/Weiche/Gerade) und der Automation-Summenzeile bleibt das Feld leer, da es sich um Sammlungen gleichartiger Objekte handelt. + - IDs: kommaseparierte Liste der ID-Attribute aller Bloecke der Zeile + (eigene Spalte, nicht mehr Teil des details-JSON). + - Omniflo Bogen/Weiche: gruppiert nach SivasNummer, Anzahl summiert - Omniflo Gerade: gruppiert nach ARTINR-Attribut, Laenge[mm] summiert - - ILS 2.0 Kreisel: je Kreisel eine Zeile, details = JSON mit Parametern + - ILS 2.0 Kreisel: gruppiert nach Kreiselart+Abstand+Anzahl Separatoren/ + Scanner/Rampen, Anzahl summiert - ILS 2.0 Automation: Summierungszeile (nur wenn ILS-Elemente vorhanden) Aufruf: @@ -119,7 +123,6 @@ def build_gefaellestrecke_details(block): return "0" return { - "IDs": [get_id(block)], "Bezeichnung": attribs.get("Bezeichnung", block.get("block_name", "")), "Hoehe oben": mm_to_m("HOEHE_VON_mm"), "Hoehe unten": mm_to_m("HOEHE_BIS_mm"), @@ -131,6 +134,23 @@ def build_gefaellestrecke_details(block): } +def kreisel_signature(block): + """ + Schluessel zur Gruppierung gleichartiger Kreisel: Kreiselart, Abstand, + Anzahl der Separatoren, Anzahl der Scanner und Anzahl der Rampen + entscheiden, ob Kreisel in derselben Sivas-Zeile summiert werden. + """ + attribs = block.get("attribs", {}) + return ( + attribs.get("KREISELART", "STANDARD"), + attribs.get("ABSTAND", "2300"), + attribs.get("ANZAHL_SEPARATOR", attribs.get("N_SEPARATOREN", "2")), + attribs.get("ANZAHL_SCANNER", attribs.get("N_SCANNER", "0")), + attribs.get("N_RAMPEN", "0"), + attribs.get("GERUEST_EINZELMODUL", "0"), + ) + + def gefaellestrecke_signature(block): """ Schluessel zur Gruppierung gleichartiger Gefaellestrecken: Bloecke mit @@ -182,7 +202,6 @@ def build_variofoerderer_details(block): return 0 return { - "IDs": [get_id(block)], "Anzahl Foerdergruppen": to_int("ANZAHL_VF"), "Anzahl Gefaellegruppen": to_int("ANZAHL_GF"), "Hoehe in m": attribs.get("MONTAGEHOEHE_m", "0"), @@ -235,8 +254,7 @@ def build_kreisel_details(block): "Anzahl der Separatoren": attribs.get("ANZAHL_SEPARATOR", attribs.get("N_SEPARATOREN", "2")), "Anzahl der Scanner": attribs.get("ANZAHL_SCANNER", attribs.get("N_SCANNER", "0")), "Anzahl der Rampen": attribs.get("N_RAMPEN", "0"), - "Drehrichtung": attribs.get("DREHRICHTUNG", "UZS"), - "Drehung": block.get("rotation", 0.0), + "Geruest fuer Einzelmodul": attribs.get("GERUEST_EINZELMODUL", "0") == "1", } @@ -468,7 +486,8 @@ def process_blocks(blocks, lookup): "anzahl": g["anzahl"], "laenge_mm": "", "hoehe_m": format_hoehe_m(g["hoehe_mm"]), - "details": {"IDs": g["ids"]}, + "ids": g["ids"], + "details": {}, }) nr += 1 @@ -483,7 +502,8 @@ def process_blocks(blocks, lookup): "anzahl": g["anzahl"], "laenge_mm": "", "hoehe_m": format_hoehe_m(g["hoehe_mm"]), - "details": {"IDs": g["ids"]}, + "ids": g["ids"], + "details": {}, }) nr += 1 @@ -498,25 +518,36 @@ def process_blocks(blocks, lookup): "anzahl": g["anzahl"], "laenge_mm": int(g["laenge_mm"]), "hoehe_m": format_hoehe_m(g["hoehe_mm"]), - "details": {"IDs": g["ids"]}, + "ids": g["ids"], + "details": {}, }) nr += 1 + # Gleichartige Kreisel (gleiche Kreiselart und gleicher Abstand) zu einer + # Zeile zusammenfassen - nur IDs/Bezeichnung bleiben je Block unterschiedlich. + kreisel_groups = {} for block in kreisel_list: + sig = kreisel_signature(block) + if sig not in kreisel_groups: + kreisel_groups[sig] = {"ids": [], "bezeichnungen": [], "block": block} + kreisel_groups[sig]["ids"].append(get_id(block)) + kreisel_groups[sig]["bezeichnungen"].append( + block.get("attribs", {}).get("Bezeichnung", "")) + + for group in kreisel_groups.values(): sivasnr, teileart = ILS_SIVASNR["kreisel"] - details = build_kreisel_details(block) - details["ID"] = get_id(block) items.append({ "nr": nr, "teileart": teileart, "sivasnr": sivasnr, "sivasnr_quoted": True, - "bezeichnung": block.get("attribs", {}).get("Bezeichnung", ""), + "bezeichnung": ", ".join(b for b in group["bezeichnungen"] if b), "dispgruppe": 20, - "anzahl": 1, + "anzahl": len(group["ids"]), "laenge_mm": "", "hoehe_m": "", - "details": details, + "ids": group["ids"], + "details": build_kreisel_details(group["block"]), }) nr += 1 @@ -532,7 +563,8 @@ def process_blocks(blocks, lookup): "anzahl": counters["anzahl_eckraeder"], "laenge_mm": "", "hoehe_m": "", - "details": {"IDs": eckrad_ids}, + "ids": eckrad_ids, + "details": {}, }) nr += 1 @@ -551,7 +583,8 @@ def process_blocks(blocks, lookup): "anzahl": len(strecke_ids), "laenge_mm": "", "hoehe_m": "", - "details": {"IDs": strecke_ids}, + "ids": strecke_ids, + "details": {}, }) nr += 1 @@ -569,6 +602,7 @@ def process_blocks(blocks, lookup): "anzahl": 1, "laenge_mm": "", "hoehe_m": "", + "ids": [get_id(block)], "details": build_variofoerderer_details(block), }) nr += 1 @@ -587,7 +621,6 @@ def process_blocks(blocks, lookup): for group in gefaelle_groups.values(): sivasnr, teileart = ILS_SIVASNR["gefaellestrecke"] details = build_gefaellestrecke_details(group["block"]) - details["IDs"] = group["ids"] details["Bezeichnung"] = group["bezeichnungen"] items.append({ "nr": nr, @@ -599,6 +632,7 @@ def process_blocks(blocks, lookup): "anzahl": len(group["ids"]), "laenge_mm": "", "hoehe_m": "", + "ids": group["ids"], "details": details, }) nr += 1 @@ -652,6 +686,7 @@ def format_csv_line(item): """Formatiert eine CSV-Zeile im neuen Sivas-Format.""" details_json = json.dumps(item["details"], ensure_ascii=False) sivasnr = f'"{item["sivasnr"]}"' if item["sivasnr_quoted"] else item["sivasnr"] + ids_str = ", ".join(str(i) for i in item.get("ids", []) if i) return ( f'{item["nr"]}' f';"{item["teileart"]}"' @@ -661,6 +696,7 @@ def format_csv_line(item): f';{item["anzahl"]}' f';{item["laenge_mm"]}' f';{item["hoehe_m"]}' + f';"{ids_str}"' f';{details_json}' ) @@ -688,7 +724,7 @@ def main(): items, _ = process_blocks(blocks, lookup) - header = "Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];details" + header = "Nr;TeileArt;SivasNummer;Bezeichnung;Dispogruppe;Anzahl;Laenge[mm];Hoehe[m];IDs;details" with open(output_csv, "w", encoding="utf-8") as f: f.write(header + "\n") for item in items: From bb92b8ef69bb592cdae51ffbb81ef141923ef26f Mon Sep 17 00:00:00 2001 From: Michael Stangl Date: Wed, 22 Jul 2026 11:44:33 +0200 Subject: [PATCH 2/6] =?UTF-8?q?Artinr.=20mit=20Punkt=20ist=20keine=20gute?= =?UTF-8?q?=20Idee=20f=C3=BCr=20eine=20Attributbezeichnung.=20Ge=C3=A4nder?= =?UTF-8?q?t?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Lisp/ssg_core.lsp | 4 ++-- Lisp/vf_core.lsp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Lisp/ssg_core.lsp b/Lisp/ssg_core.lsp index 03c945f..054b481 100644 --- a/Lisp/ssg_core.lsp +++ b/Lisp/ssg_core.lsp @@ -440,13 +440,13 @@ ;; (Gefaellestrecke + VarioFoerderer, feste Reihenfolge) ;; ============================================================ ;; Vorderteil (immer vorhanden). Bezeichnung = Blockname (GF_n/VF_n), -;; Artinr. fest 6220 (alle GF/VF). TYP-Wert wird zur Laufzeit gesetzt. +;; ARTINR fest 6220 (alle GF/VF). TYP-Wert wird zur Laufzeit gesetzt. ;; ID zuerst (global, jeder eingefuegte Baustein - Kreisel/GF/VF - erhaelt eine ;; neue ID), danach Bezeichnung (= Blockname). Hoehen/Delta mit Einheit _mm. (setq *strecke-attr-front* '(("ID" "") ("Bezeichnung" "") - ("Artinr." "6220") + ("ARTINR" "6220") ("MONTAGEHOEHE_m" "0.000") ("HOEHE_VON_mm" "0") ("HOEHE_BIS_mm" "0") diff --git a/Lisp/vf_core.lsp b/Lisp/vf_core.lsp index 25883bd..61f5bcd 100644 --- a/Lisp/vf_core.lsp +++ b/Lisp/vf_core.lsp @@ -1116,7 +1116,7 @@ (ssg-attrib-set-on vf-insert (list (cons "Bezeichnung" vf-bname) - ;; Artinr. bleibt auf Schema-Vorgabe "6220" + ;; ARTINR bleibt auf Schema-Vorgabe "6220" (cons "MONTAGEHOEHE_m" (rtos montagehoehe-m 2 3)) (cons "HOEHE_VON_mm" (itoa (fix hoehe-von))) (cons "HOEHE_BIS_mm" (itoa (fix hoehe-bis))) From efdf6224ff5cdf702c93a9147e14bea1eb569730 Mon Sep 17 00:00:00 2001 From: Michael Stangl Date: Wed, 22 Jul 2026 11:46:59 +0200 Subject: [PATCH 3/6] Noch einen Eintrag vergessen gehabt --- Lisp/KreiselInsert.lsp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lisp/KreiselInsert.lsp b/Lisp/KreiselInsert.lsp index 47d8762..8dc5b46 100644 --- a/Lisp/KreiselInsert.lsp +++ b/Lisp/KreiselInsert.lsp @@ -72,13 +72,13 @@ ;; Attribut-Definitionen: ((TAG DEFAULT) ...) ;; Anzeige-/Attributreihenfolge im Block (ID zuerst, dann Bezeichnung, -;; Artinr. fest 6200, Montage-/Hoehendaten, dann Ausstattung). +;; ARTINR fest 6200, Montage-/Hoehendaten, dann Ausstattung). ;; NUMMER steht am Ende (wird intern fuer Nummerierung/Blockname ;; benoetigt; Entfernen erfordert Refactor der Nummernvergabe). (setq *kreisel-attrib-defs* '(("ID" "") ("Bezeichnung" "") - ("Artinr." "6200") + ("ARTINR" "6200") ("MONTAGEHOEHE_m" "0.000") ("HOEHE" "0") ("KREISELART" "STANDARD") From 4159132ce15394523bce3b7a40750e987c59dbd6 Mon Sep 17 00:00:00 2001 From: Michael Stangl Date: Wed, 22 Jul 2026 12:09:42 +0200 Subject: [PATCH 4/6] Bezeichner war im json Export noch drin, obwohl es eigene Spalte ist --- lib/export_sivas.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/export_sivas.py b/lib/export_sivas.py index 6eb8661..95ef94f 100644 --- a/lib/export_sivas.py +++ b/lib/export_sivas.py @@ -123,7 +123,6 @@ def build_gefaellestrecke_details(block): return "0" return { - "Bezeichnung": attribs.get("Bezeichnung", block.get("block_name", "")), "Hoehe oben": mm_to_m("HOEHE_VON_mm"), "Hoehe unten": mm_to_m("HOEHE_BIS_mm"), "Laenge in Meter": attribs.get("L_GF_m", ""), @@ -621,7 +620,6 @@ def process_blocks(blocks, lookup): for group in gefaelle_groups.values(): sivasnr, teileart = ILS_SIVASNR["gefaellestrecke"] details = build_gefaellestrecke_details(group["block"]) - details["Bezeichnung"] = group["bezeichnungen"] items.append({ "nr": nr, "teileart": teileart, From c0f06b68cda73ccc943d8676f0a7d83dabf3b1bb Mon Sep 17 00:00:00 2001 From: Yuelin Wang Date: Wed, 22 Jul 2026 12:42:18 +0200 Subject: [PATCH 5/6] =?UTF-8?q?=20Fehler=20f=C3=BCr=20Etage-VF=20korrigier?= =?UTF-8?q?t.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Lisp/vf_etage.lsp | 164 ++++++++++++++++++++++++++++++---------------- 1 file changed, 107 insertions(+), 57 deletions(-) diff --git a/Lisp/vf_etage.lsp b/Lisp/vf_etage.lsp index aac4444..be9b798 100644 --- a/Lisp/vf_etage.lsp +++ b/Lisp/vf_etage.lsp @@ -40,7 +40,11 @@ (setq FESTE_ETAGE_MITTE 1000) (setq ETAGE_SCHRAEG_LAENGE 700) -(setq ETAGE_HZ_WINKEL 60) +;; Schwenkwinkel der Ein-/Auslauf-Schraegsektionen: 30 Grad (AS_30/ES_30 + +;; 30-Grad-Gefaellebogen). War frueher 60. Nur noch im Laengen-/Hoehen-Budget +;; berechne-winkel-etage (schraeg-cos) verwendet; die fruehere absolute +;; hz-Platzierung wurde durch Frame-Verkettung (cur-hz) ersetzt. +(setq ETAGE_HZ_WINKEL 30) ;; ============================================================ ;; TEIL 2: BIBLIOTHEK INITIALISIEREN (ETAGE-SPEZIFISCH) @@ -127,8 +131,8 @@ ) ) - ;; Gefaellebogen_links_60 Masse extrahieren - (setq gefaelle-blockname "Gefaellebogen_links_60_R500") + ;; Gefaellebogen_links_30 Masse extrahieren + (setq gefaelle-blockname "Gefaellebogen_links_30_R500") (princ (ssg-textf "vfe-extrahiere-block-mass" (list gefaelle-blockname))) (ensure-block-loaded gefaelle-blockname) (if (tblsearch "BLOCK" gefaelle-blockname) @@ -160,8 +164,8 @@ ) (princ (ssg-textf "vfe-gefaellebogen-links-mass" (list (rtos etage-gef-dx-links 2 2) (rtos etage-gef-dz-links 2 2)))) - ;; Gefaellebogen_rechts_60 Masse extrahieren - (setq gefaelle-blockname "Gefaellebogen_rechts_60_R500") + ;; Gefaellebogen_rechts_30 Masse extrahieren + (setq gefaelle-blockname "Gefaellebogen_rechts_30_R500") (princ (ssg-textf "vfe-extrahiere-block-mass" (list gefaelle-blockname))) (ensure-block-loaded gefaelle-blockname) (if (tblsearch "BLOCK" gefaelle-blockname) @@ -597,64 +601,83 @@ ;; ============================================================ ;; Gibt endpunkt zurueck. ;; VF_*-Block-Erstellung erfolgt zentral im Dispatcher (vf_core.lsp). -;; hz: Parameter fuer Registry-Kompatibilitaet mit variofoerderer-einfuegen -;; (siehe c:VarioFoerderer) - wird hier NICHT verwendet: die Etage-Anlage hat -;; bereits eine eigene, fest verdrahtete horizontale Geometrie (hz-anfang/ -;; hz-ende fuer den 60-Grad-Uebereinander-Versatz) und unterstuetzt aktuell -;; keine zusaetzliche globale Fahrtrichtung. +;; hz: Richtung der Hauptlinie (Default 0 = horizontal/X). AS-KS_EIN und +;; ES-KS_AUS liegen koaxial auf dieser Linie; die Kette wird frame-verkettet +;; aufgebaut (cur-hz laeuft durch, Boegen drehen um ihren gemessenen Schwenk). (defun etage-foerderanlage-einfuegen (deltaL deltaH richtung best-winkel L_GF1 L_GF2 L_VF startpunkt seite hz / aktueller-punkt bogen-name endpunkt bogen-mass bogen-dx bogen-dz as-block es-block gefaelle-blockname - hz-vorzeichen hz-anfang hz-ende) + as-hz as-ksinfo + cur-hz bogen-info es-info + perp-sin perp-cos p2b-perp es-place-rad + es-wx es-wy es-perp perp-rate L-exit) (setq aktueller-punkt startpunkt) - ;; Horizontalwinkel-Vorzeichen je nach Seite: - ;; rechts: Anfang +60 Grad (links), Ende -60 Grad (rechts) - ;; links: Anfang -60 Grad, Ende +60 Grad - (setq hz-vorzeichen (if (= seite "rechts") 1 -1)) - (setq hz-anfang (* hz-vorzeichen ETAGE_HZ_WINKEL)) - (setq hz-ende (* (- hz-vorzeichen) ETAGE_HZ_WINKEL)) + ;; hz = Richtung der Hauptlinie (AS-KS_EIN / ES-KS_AUS liegen darauf). + ;; Default 0 (horizontal), falls der Aufrufer nichts uebergibt. + (if (null hz) (setq hz 0.0)) + (setq hz (float hz)) (setq as-block (strcat "AS_Element_30_" seite)) (setq es-block (strcat "ES_Element_30_" seite)) + ;; Gefaellebogen auf der GEGENSEITE des AS-Elements (Nutzer-Vorgabe + ;; 2026-07-21): AS links -> Boegen rechts, AS rechts -> Boegen links. + ;; Beide Etage-Boegen nutzen dieselbe (Gegen-)Seite. (setq gefaelle-blockname (if (= seite "rechts") - "Gefaellebogen_rechts_60_R500" - "Gefaellebogen_links_60_R500" + "Gefaellebogen_links_30_R500" + "Gefaellebogen_rechts_30_R500" )) ;; Sentinel: Bibliothek neu initialisieren wenn Bloecke fehlen (if (and *etage-lib-initialized* (not (tblsearch "BLOCK" "AS_Element_30_rechts"))) (setq *etage-lib-initialized* nil)) (if (not *etage-lib-initialized*) (init-bibliothek-etage)) - ;; 1. AS_30 + ;; 1. AS_30 - KS_EIN koaxial zur Hauptlinie (hz) ausrichten. + ;; vf-element-ks-info liefert (ein-ang aus-ang vx vy): ein-ang/aus-ang sind die + ;; Ebenen-Winkel der KS_EIN- bzw. KS_AUS-Achse IM BLOCK (bei Einbau-Rotation 0). + ;; Platzierungs-hz = (hz - ein-ang) dreht die KS_EIN-Achse von ein-ang auf hz + ;; -> KS_EIN liegt koaxial auf der Hauptlinie (Abnahmekriterium). (princ (ssg-textf "vfe-step1-as30" (list as-block))) - (setq aktueller-punkt (insert-block-by-ks as-block aktueller-punkt 0.0)) + (setq as-ksinfo (vf-element-ks-info as-block)) + (setq aktueller-punkt + (insert-block-by-ks as-block aktueller-punkt (- hz (car as-ksinfo)))) + ;; KS_AUS-Richtung (absolut) = hz + Schwenk (aus-ang - ein-ang); die folgende + ;; GF laeuft in dieser Richtung weiter (Frame-Verkettung wie im Linienzug). + (setq as-hz (+ hz (- (cadr as-ksinfo) (car as-ksinfo)))) - ;; 2. Staustrecke 400mm (hz-anfang, 3 Grad vert, KS_EIN) - (princ (ssg-textf "vfe-step2" (list (itoa hz-anfang)))) + ;; 2. Staustrecke 400mm (folgt der AS-Richtung as-hz, 3 Grad vert, KS_EIN) + (princ (ssg-textf "vfe-step2" (list (rtos as-hz 2 1)))) (setq aktueller-punkt (insert-hz-scaled-block-by-ks "Staustrecke_SP_1000_mm" aktueller-punkt - 400 hz-anfang 3)) + 400 as-hz 3)) - ;; 3. Separator (hz-anfang, 3 Grad vert) - (princ (ssg-textf "vfe-step3" (list (itoa hz-anfang)))) + ;; 3. Separator (folgt der AS-Richtung as-hz, 3 Grad vert) + (princ (ssg-textf "vfe-step3" (list (rtos as-hz 2 1)))) (setq aktueller-punkt (insert-hz-rotated-block-with-ks "Staustrecke_Separator_SP_300_mm" aktueller-punkt - hz-anfang 3 300 0)) + as-hz 3 300 0)) - ;; 4. Gefaellebogen Anfang (hz-anfang, 0 Grad vert, KS_EIN) - (princ (ssg-textf "vfe-step4" (list gefaelle-blockname (itoa hz-anfang)))) + ;; Ab hier laufende Richtung cur-hz mitfuehren (frame-verkettet). Start = + ;; KS_AUS-Richtung des AS (as-hz). Jeder Gefaellebogen dreht cur-hz um seinen + ;; gemessenen Schwenk (Vorzeichen/Seite kommen aus dem Block). + (setq cur-hz as-hz) + + ;; 4. Gefaellebogen Anfang (verkettet: KS_EIN auf cur-hz, dann cur-hz drehen) + (setq bogen-info (vf-element-ks-info gefaelle-blockname)) + (princ (ssg-textf "vfe-step4" (list gefaelle-blockname (rtos cur-hz 2 1)))) (setq aktueller-punkt - (insert-hz-rotated-block-by-ks gefaelle-blockname aktueller-punkt hz-anfang 0)) + (insert-hz-rotated-block-by-ks gefaelle-blockname aktueller-punkt + (- cur-hz (car bogen-info)) 0)) + (setq cur-hz (+ cur-hz (- (cadr bogen-info) (car bogen-info)))) ;; 5. L_GF1 (3 Grad geneigt) (if (> L_GF1 0.1) (progn (princ (ssg-textf "vfe-step5-strecke" (list (rtos L_GF1 2 2)))) (setq aktueller-punkt - (insert-inclined-scaled-block "Staustrecke_SP_1000_mm" aktueller-punkt L_GF1 3 0.0)) + (insert-inclined-scaled-block "Staustrecke_SP_1000_mm" aktueller-punkt L_GF1 3 cur-hz)) ) (princ (ssg-text "vfe-step5-skip")) ) @@ -662,7 +685,7 @@ ;; 6. Umlenkstation (3 Grad geneigt) (princ (ssg-text "vfe-step6")) (setq aktueller-punkt - (insert-rotated-block-with-ks "Vario_Umlenkstation_500mm" aktueller-punkt 3 500 0 0.0)) + (insert-rotated-block-with-ks "Vario_Umlenkstation_500mm" aktueller-punkt 3 500 0 cur-hz)) ;; 7. 1. Vertikalbogen (3 Grad geneigt) (if (= richtung "Auf") @@ -678,7 +701,7 @@ (setq bogen-dx (car bogen-mass) bogen-dz (caddr bogen-mass)) (princ (ssg-textf "vfe-step7" (list bogen-name))) (setq aktueller-punkt - (insert-rotated-block-with-ks bogen-name aktueller-punkt 3 bogen-dx bogen-dz 0.0)) + (insert-rotated-block-with-ks bogen-name aktueller-punkt 3 bogen-dx bogen-dz cur-hz)) ;; 8. Variable Strecke L_VF (if (> L_VF 0.1) @@ -688,13 +711,13 @@ (princ (ssg-textf "vfe-step8-auf" (list (itoa (- (- best-winkel 3))) (rtos L_VF 2 2)))) (setq aktueller-punkt (insert-inclined-scaled-block "Staustrecke_SP_1000_mm" aktueller-punkt - L_VF (- (- best-winkel 3)) 0.0)) + L_VF (- (- best-winkel 3)) cur-hz)) ) (progn (princ (ssg-textf "vfe-step8-ab" (list (itoa (+ best-winkel 3)) (rtos L_VF 2 2)))) (setq aktueller-punkt (insert-inclined-scaled-block "Staustrecke_SP_1000_mm" aktueller-punkt - L_VF (+ best-winkel 3) 0.0)) + L_VF (+ best-winkel 3) cur-hz)) ) ) ) @@ -719,56 +742,83 @@ " (" (itoa (- 3 best-winkel)) " Grad geneigt)")) (setq aktueller-punkt (insert-rotated-block-with-ks bogen-name aktueller-punkt - (- 3 best-winkel) bogen-dx bogen-dz 0.0)) + (- 3 best-winkel) bogen-dx bogen-dz cur-hz)) ) (progn (princ (strcat "\n\n9/15: " bogen-name " (" (itoa (+ best-winkel 3)) " Grad geneigt)")) (setq aktueller-punkt (insert-rotated-block-with-ks bogen-name aktueller-punkt - (+ best-winkel 3) bogen-dx bogen-dz 0.0)) + (+ best-winkel 3) bogen-dx bogen-dz cur-hz)) ) ) ;; 10. Motorstation (3 Grad geneigt) (princ "\n\n10/15: Motorstation (500mm, 3 Grad geneigt)") (setq aktueller-punkt - (insert-rotated-block-with-ks "Vario_Motorstation_500mm" aktueller-punkt 3 500 0 0.0)) + (insert-rotated-block-with-ks "Vario_Motorstation_500mm" aktueller-punkt 3 500 0 cur-hz)) ;; 11. L_GF2 (3 Grad geneigt) (if (> L_GF2 0.1) (progn (princ (strcat "\n\n11/15: Gefaellestrecke (3 Grad, L=" (rtos L_GF2 2 2) " mm)")) (setq aktueller-punkt - (insert-inclined-scaled-block "Staustrecke_SP_1000_mm" aktueller-punkt L_GF2 3 0.0)) + (insert-inclined-scaled-block "Staustrecke_SP_1000_mm" aktueller-punkt L_GF2 3 cur-hz)) ) (princ "\n\n11/15: L_GF2 (uebersprungen)") ) - ;; 12. Gefaellebogen Ende (via KS_EIN, 0 Grad vert) - (princ (strcat "\n\n12/15: " gefaelle-blockname " (Ende, KS_EIN)")) - (setq aktueller-punkt (insert-block-by-ks gefaelle-blockname aktueller-punkt 0.0)) - - ;; 13. Separator Ende (hz-ende, 3 Grad vert) - (princ (strcat "\n\n13/15: Separator (300mm, " - (itoa hz-ende) " Grad hz, 3 Grad vert)")) + ;; 12. Gefaellebogen Ende (verkettet: KS_EIN auf cur-hz, dann cur-hz drehen) + (setq bogen-info (vf-element-ks-info gefaelle-blockname)) + (princ (strcat "\n\n12/15: " gefaelle-blockname + " (Ende, verkettet cur-hz=" (rtos cur-hz 2 1) ")")) (setq aktueller-punkt - (insert-hz-rotated-block-with-ks "Staustrecke_Separator_SP_300_mm" aktueller-punkt - hz-ende 3 300 0)) + (insert-block-by-ks gefaelle-blockname aktueller-punkt (- cur-hz (car bogen-info)))) + (setq cur-hz (+ cur-hz (- (cadr bogen-info) (car bogen-info)))) - ;; 14. Staustrecke 400mm Ende (hz-ende, 3 Grad vert, KS_EIN) - (princ (strcat "\n\n14/15: Staustrecke 400mm (" - (itoa hz-ende) " Grad hz, 3 Grad vert, KS_EIN)")) + ;; --- Auslauf RUECKWAERTS vom ES gerechnet (analog Linienzug Modus 2): + ;; die Auslauf-Staustrecke wird variabel, sodass das ES-KS_AUS OHNE + ;; seitlichen Versatz auf der Hauptachse landet. Reihenfolge (Nutzer-Vorgabe): + ;; Staustrecke -> Separator -> ES. + (setq es-info (vf-element-ks-info es-block)) + ;; perp = Einheitsvektor senkrecht zur Hauptlinie hz: (-sin hz, cos hz) + (setq perp-sin (sin (* hz (/ pi 180.0))) + perp-cos (cos (* hz (/ pi 180.0)))) + ;; seitliche Lage nach Bogen2 (perp-Abstand des aktuellen Punkts zu startpunkt) + (setq p2b-perp (+ (* (- (car aktueller-punkt) (car startpunkt)) (- perp-sin)) + (* (- (cadr aktueller-punkt) (cadr startpunkt)) perp-cos))) + ;; ES-Eigenversatz KS_EIN->KS_AUS (Block vx/vy) in Auslaufrichtung gedreht -> perp + (setq es-place-rad (* (- cur-hz (car es-info)) (/ pi 180.0))) + (setq es-wx (- (* (caddr es-info) (cos es-place-rad)) (* (cadddr es-info) (sin es-place-rad)))) + (setq es-wy (+ (* (caddr es-info) (sin es-place-rad)) (* (cadddr es-info) (cos es-place-rad)))) + (setq es-perp (+ (* es-wx (- perp-sin)) (* es-wy perp-cos))) + ;; perp-Auslenkung pro Laengeneinheit bei cur-hz (Neigung 3 Grad) + (setq perp-rate (* (cos (* 3.0 (/ pi 180.0))) + (sin (* (- cur-hz hz) (/ pi 180.0))))) + ;; Loesen: p2b-perp + (L_exit + 300)*perp-rate + es-perp = 0 + (setq L-exit + (if (> (abs perp-rate) 1e-6) + (- (/ (- (+ p2b-perp es-perp)) perp-rate) 300.0) + 400.0)) + (if (< L-exit 50.0) (setq L-exit 50.0)) ; Schutz gegen negative/zu kurze GF + + ;; 13. Auslauf-Staustrecke (variabel, folgt cur-hz, 3 Grad vert, KS_EIN) + (princ (strcat "\n\n13/15: Staustrecke (variabel L=" (rtos L-exit 2 1) + ", cur-hz=" (rtos cur-hz 2 1) ")")) (setq aktueller-punkt (insert-hz-scaled-block-by-ks "Staustrecke_SP_1000_mm" aktueller-punkt - 400 hz-ende 3)) + L-exit cur-hz 3)) - ;; 15. ES_30 (hz-ende, 0 Grad vert) - (princ (strcat "\n\n15/15: " es-block - " (Ende, " (itoa hz-ende) " Grad hz, 0 Grad vert)")) + ;; 14. Separator (verkettet, folgt cur-hz, 3 Grad vert) + (princ (strcat "\n\n14/15: Separator (300mm, cur-hz=" (rtos cur-hz 2 1) ")")) + (setq aktueller-punkt + (insert-hz-rotated-block-with-ks "Staustrecke_Separator_SP_300_mm" aktueller-punkt + cur-hz 3 300 0)) + + ;; 15. ES_30 (verkettet: KS_EIN auf cur-hz; KS_AUS auf der Hauptlinie) + (princ (strcat "\n\n15/15: " es-block " (Ende, verkettet cur-hz=" (rtos cur-hz 2 1) ")")) (setq endpunkt - (insert-hz-rotated-block-with-ks es-block aktueller-punkt - hz-ende 0 etage-ein-dx etage-ein-dz)) + (insert-block-by-ks es-block aktueller-punkt (- cur-hz (car es-info)))) (princ "\n\n=========================================") (princ "\n>>> Etage-VarioFoerderer eingefuegt! <<<") From c6d5a4e8eb3ebb071778c189678e715766fe584f Mon Sep 17 00:00:00 2001 From: Yuelin Wang Date: Wed, 22 Jul 2026 12:43:29 +0200 Subject: [PATCH 6/6] Doppelklick-GF-Edit repariert --- Lisp/Gefaellestrecke.lsp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Lisp/Gefaellestrecke.lsp b/Lisp/Gefaellestrecke.lsp index 355700f..79f3117 100644 --- a/Lisp/Gefaellestrecke.lsp +++ b/Lisp/Gefaellestrecke.lsp @@ -2089,6 +2089,10 @@ hoehe-bis)) (setq hz-vf (rem (+ hz 180.0) 360.0)) (setq vf-seite as-seite) ; VF-AS/ES-Seite: Default = GF-AS-Seite + (princ (strcat "\n[DEBUG-VFPAR] GF-hz=" (rtos hz 2 1) " -> VF-hz=" (rtos hz-vf 2 1) + " | as-seite=" as-seite + " | gf-start=" (vl-princ-to-string gf-start) + " | vf-start=" (vl-princ-to-string vf-start))) (vfs-standard-dialog-berechnen-einfuegen (vf-next-number) deltaL deltaH "Auf" vf-start hz-vf vf-seite nil) (princ (ssg-text "gf-vf-gebaut")) @@ -2171,7 +2175,10 @@ (setq as-seite (cond ((cdr (assoc "SEITE_AS" attribs))) ("links"))) (setq hoehe-bis (atof (cond ((cdr (assoc "HOEHE_BIS_mm" attribs))) ("0")))) - (setq dlg-werte (gf-dialog-eingabe prefill)) + ;; 2. Argument (hoehe-vorbelegung) explizit nil: BricsCAD verlangt die exakte + ;; Argumentzahl (setzt fehlende NICHT automatisch auf nil). Im Edit kommt die + ;; Einfuegehoehe aus prefill, keine separate Punkt-Vorbelegung noetig. + (setq dlg-werte (gf-dialog-eingabe prefill nil)) (cond ((null dlg-werte) (princ (ssg-text "gf-status-abgebrochen")))