VF-Linienzug: baubare Hoehen-Vorschlaege (Ab/Auf) statt unveraenderter Ist-Hoehe, negative Restlaenge nach AS-Element abgefangen

- Hoehe-Prompt/Wizard-Dialog schlagen jetzt zwei tatsaechlich baubare
  Zielhoehen vor (Ab/Auf) statt der unveraenderten Kettenhoehe, die bei
  direkter Uebernahme immer als deltaH=0 abgelehnt wurde (Linie-GF,
  Linie-VF, automatische Linie, VF-Kette fortsetzen, Kettenende-Abschluss)
- Nach dem AS-Element-Einfuegen kann die real gemessene Restlaenge negativ
  werden (Klickpunkt zu nah); Linie-GF und automatische Linie pruefen das
  jetzt und brechen sauber ab statt eine entartete GF-Strecke zu bauen
- Debug-Log (Modus 1) protokolliert jetzt Erfolg/Misserfolg der
  Geometrieerzeugung inkl. der verwendeten Werte
- Neue Lisp/vf_konstanten.lsp: zentrale, dokumentierte Sammlung aller
  Laengen-/Winkel-Magic-Numbers aus dem VarioFoerderer-Cluster als
  Nachschlagewerk (Module selbst noch unveraendert)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-27 13:27:25 +02:00
parent 9fdc1b8bdd
commit 308d49fc96
6 changed files with 851 additions and 195 deletions
+1 -1
View File
@@ -93,7 +93,7 @@ Detaillierte Dokumentation aller Funktionen und Befehle: siehe `Lisp/README.md`.
| `ssg_dialog.lsp` | - | DCL-Dialog-Vorlagen und Hilfsfunktionen |
| `ssg_layer.lsp` | - | Layer-Verwaltung |
| `KreiselInsert.lsp` | KreiselInsert, KreiselConnect, KreiselRedraw, KreiselQuick, KreiselEdit, KreiselParams, KreiselLabelSetup, KreiselLabelPos, KreiselLabelHoehe, ILS_Eckrad | ILS Kreisel und Eckrad komplett in AutoLISP |
| `VarioFoerderer.lsp` (Wrapper fuer `vf_core.lsp`/`vf_standard.lsp`/`vf_etage.lsp`/`vf_linienzug.lsp`) | FOERDERANLAGE, VARIOFOERDERER_EDIT, VARIOFOERDERER_NACHRUESTEN, Vario_Kette_Merge, VF_WIZARD_AN, VF_WIZARD_AUS | Vario-Foerderanlagen Generator (Typen Standard/Etage/Linienzug); Standard- UND Etage-Typ: Werteingabe per DCL-Dialog (`vfs-standard-dialog-ablauf` in vf_standard.lsp bzw. `vfe-etage-dialog-ablauf` in vf_etage.lsp, beide nutzen dieselben Dialoge `vfs-dialog-eingabe-basis`/`vfs-dialog-winkel-verteilung`); Doppelklick auf VF_n-Block ruft VARIOFOERDERER_EDIT, das per SSG_VF_EDIT-XDATA-Marker ("standard"/"etage"/"linienzug") in den passenden Neuaufbau-Zweig dispatcht (`vfe-edit-ent` fuer Etage, `vfl-edit-ent` fuer Linienzug); Altbestand-Bloecke ohne Marker werden abgewiesen. Linienzug (Modus 1, `vf-linienzug-modus`) zeichnet jede interaktive Eingabe in einem Journal auf (`vfl-in-point`/`-string`/`-real`/`-int`) und schreibt es als XDATA auf den fertigen `VF_n`-Block; ein Abbruch (ESC) loescht dadurch nichts mehr, sondern wickelt die bis dahin gebaute Teil-Geometrie ebenso zu einem Block (`vfl-modus-abbruch-sichern`) - sie bleibt stehen und ist sofort per Doppelklick weiter editierbar/fortsetzbar. Der komplette Linienzug-Hauptstrang (Menue-Fragen von AS-Element bis Kettenende, inkl. GF-Bogen/Vario-Kurve/VF-Einheit-Fortsetzung) laeuft per Default ueber DCL-Dialoge statt Konsole (`*vfl-wizard-mode*`, Befehle VF_WIZARD_AN/VF_WIZARD_AUS): `vfl-in-string`/`-int`/`-real` zeigen bei aktivem Wizard-Modus generische Dialoge aus `dcl/vf_linienzug_wizard.dcl` (Zahl-Eingabe bzw. Mehrfachauswahl aus `vfl-menu`/`vfl-menu-int`) statt `getstring`/`getint`/`getreal` aufzurufen; die ORIGINALEN Konsolen-Fragen (princ + get*, de/en ueber ssg-text) bleiben unveraendert im Code (Fallback bei Fehlern via `vl-catch-all-apply`, siehe `doc/variofoerderer.md`). `vfl-edit-ent` liest das Journal, zeigt die Sektionen ueber einen DCL-Dialog (`vfl-dlg-position`, `dcl/vfl_edit.dcl`) an, kuerzt bei Bedarf auf eine gewaehlte Sektion (stummer Replay der behaltenen Eingaben, umgeht den Wizard-Zweig komplett) und baut danach interaktiv weiter. Linienzug Modus 2 (Pfad+Zielhoehe-Solver, `vf-linienzug-modus2`) nutzt dieselben Wrapper PLUS die neue Objektauswahl-Wrapper-Funktion `vfl-in-selection` (Pfad-Objekte als stabile Entity-Handles journalisiert, neue Journal-Art `"OBJS"`) und schreibt sein Journal unter dem eigenen XDATA-Marker `"linienzug2"`; Doppelklick baut hier NICHT abschnittsweise, sondern per vollem Reset 1:1 aus dem Journal neu auf (`vfl-edit-ent2`, dispatcht aus `vfl-edit-ent` per Marker) - Modus 3 (Vorwaerts-Nachbau) bleibt bewusst reine Konsole (im Code selbst als Legacy/"wird umgebaut" markiert). `Vario_Kette_Merge` (in vf_linienzug.lsp) fuehrt mehrere einzeln gebaute VF_n-Bloecke ab einem gewaehlten Start-Baustein ueber die reale KS_AUS->KS_EIN-Nachbarschaft zu einem Gesamt-Block zusammen (aggregierte Attribute, Luecken-Erkennung). Details/Entscheidungsbaum: `doc/variofoerderer.md` |
| `VarioFoerderer.lsp` (Wrapper fuer `vf_core.lsp`/`vf_standard.lsp`/`vf_etage.lsp`/`vf_linienzug.lsp`) | FOERDERANLAGE, VARIOFOERDERER_EDIT, VARIOFOERDERER_NACHRUESTEN, Vario_Kette_Merge, VF_WIZARD_AN, VF_WIZARD_AUS | Vario-Foerderanlagen Generator (Typen Standard/Etage/Linienzug); Standard- UND Etage-Typ: Werteingabe per DCL-Dialog (`vfs-standard-dialog-ablauf` in vf_standard.lsp bzw. `vfe-etage-dialog-ablauf` in vf_etage.lsp, beide nutzen dieselben Dialoge `vfs-dialog-eingabe-basis`/`vfs-dialog-winkel-verteilung`); Doppelklick auf VF_n-Block ruft VARIOFOERDERER_EDIT, das per SSG_VF_EDIT-XDATA-Marker ("standard"/"etage"/"linienzug") in den passenden Neuaufbau-Zweig dispatcht (`vfe-edit-ent` fuer Etage, `vfl-edit-ent` fuer Linienzug); Altbestand-Bloecke ohne Marker werden abgewiesen. Linienzug (Modus 1, `vf-linienzug-modus`) zeichnet jede interaktive Eingabe in einem Journal auf (`vfl-in-point`/`-string`/`-real`/`-int`) und schreibt es als XDATA auf den fertigen `VF_n`-Block; ein Abbruch (ESC) loescht dadurch nichts mehr, sondern wickelt die bis dahin gebaute Teil-Geometrie ebenso zu einem Block (`vfl-modus-abbruch-sichern`) - sie bleibt stehen und ist sofort per Doppelklick weiter editierbar/fortsetzbar. Der komplette Linienzug-Hauptstrang (Menue-Fragen von AS-Element bis Kettenende, inkl. GF-Bogen/Vario-Kurve/VF-Einheit-Fortsetzung) laeuft per Default ueber DCL-Dialoge statt Konsole (`*vfl-wizard-mode*`, Befehle VF_WIZARD_AN/VF_WIZARD_AUS): `vfl-in-string`/`-int`/`-real` zeigen bei aktivem Wizard-Modus generische Dialoge aus `dcl/vf_linienzug_wizard.dcl` (Zahl-Eingabe bzw. Mehrfachauswahl aus `vfl-menu`/`vfl-menu-int`) statt `getstring`/`getint`/`getreal` aufzurufen; die ORIGINALEN Konsolen-Fragen (princ + get*, de/en ueber ssg-text) bleiben unveraendert im Code (Fallback bei Fehlern via `vl-catch-all-apply`, siehe `doc/variofoerderer.md`). `vfl-edit-ent` liest das Journal, zeigt die Sektionen ueber einen DCL-Dialog (`vfl-dlg-position`, `dcl/vfl_edit.dcl`) an, kuerzt bei Bedarf auf eine gewaehlte Sektion (stummer Replay der behaltenen Eingaben, umgeht den Wizard-Zweig komplett) und baut danach interaktiv weiter. Linienzug Modus 2 (Pfad+Zielhoehe-Solver, `vf-linienzug-modus2`) nutzt dieselben Wrapper PLUS die neue Objektauswahl-Wrapper-Funktion `vfl-in-selection` (Pfad-Objekte als stabile Entity-Handles journalisiert, neue Journal-Art `"OBJS"`) und schreibt sein Journal unter dem eigenen XDATA-Marker `"linienzug2"`; Doppelklick baut hier NICHT abschnittsweise, sondern per vollem Reset 1:1 aus dem Journal neu auf (`vfl-edit-ent2`, dispatcht aus `vfl-edit-ent` per Marker) - Modus 3 (Vorwaerts-Nachbau) bleibt bewusst reine Konsole (im Code selbst als Legacy/"wird umgebaut" markiert). `Vario_Kette_Merge` (in vf_linienzug.lsp) fuehrt mehrere einzeln gebaute VF_n-Bloecke ab einem gewaehlten Start-Baustein ueber die reale KS_AUS->KS_EIN-Nachbarschaft zu einem Gesamt-Block zusammen (aggregierte Attribute, Luecken-Erkennung). `vf_konstanten.lsp` (von vf_core.lsp vor den drei Submodulen geladen) sammelt alle Laengen-/Winkel-/Toleranz-Magic-Numbers aus dem VarioFoerderer-Cluster als dokumentierte `*vfk-*`-Konstanten - aktuell reines Nachschlagewerk, die Module selbst nutzen weiterhin ihre eigenen Werte (Migration steht noch aus). Details/Entscheidungsbaum: `doc/variofoerderer.md` |
| `Gefaellestrecke.lsp` | GEFAELLESTRECKE, GEFAELLESTRECKE_EDIT | Gefaelle-Foerderanlage (AUS -> Staustrecke skaliert -> Separator -> EIN); Modus 1 per DCL-Dialog (Einfuegehoehe, Element-Winkel 30/90); Doppelklick auf GF_n-Block ruft GEFAELLESTRECKE_EDIT (Dialog vorbelegt, Neuaufbau) |
| `export.lsp` | EXPORTSIVAS, EXPORTCSV, OMNI_UPDATE_ATTRIBS | JSON-Sammlung und Python-Export (Omniflo-Merkmale/Sum-Zeile via lib/export_csv.py) |
| `OmniModulInsert.lsp` | OMNI_LOAD, OMNI_APB_*, OMNI_W*_*, OMNI_AP60/AP110, OMNI_TEF_*, OMNI_TV_*, OMNI_APBW_*, OMNI_EDIT | Omniflo-Komponenten: Boegen, Weichen, Verbinder, Transferwagen, Edit-Dialog |
+1
View File
@@ -1222,6 +1222,7 @@
)
(if *vf-lisp-pfad*
(progn
(load (strcat *vf-lisp-pfad* "/vf_konstanten.lsp"))
(load (strcat *vf-lisp-pfad* "/vf_standard.lsp"))
(load (strcat *vf-lisp-pfad* "/vf_etage.lsp"))
(load (strcat *vf-lisp-pfad* "/vf_linienzug.lsp"))
+259
View File
@@ -0,0 +1,259 @@
;; ============================================================
;; VF_KONSTANTEN - Zentrale Sammlung aller Laengen-/Winkel-/Toleranz-
;; Magic-Numbers aus vf_core.lsp, vf_standard.lsp, vf_etage.lsp,
;; vf_linienzug.lsp
;; ============================================================
;; ZWECK dieser Datei: Nachschlagewerk + Grundlage fuer eine schrittweise
;; Migration - NICHT (noch) die aktive Quelle der Werte. Die vier vf_*.lsp-
;; Module verwenden ihre Werte weiterhin direkt (eigene *vfl-*/*vfs-*/
;; FESTE_*-Variablen bzw. rohe Literale, teils ueber ssg-cfg-or). Aendert
;; sich ein Wert hier, hat das AKTUELL KEINE Wirkung auf den Bauablauf -
;; die entsprechende Stelle im jeweiligen Modul muss weiterhin dort separat
;; angepasst werden. Diese Datei macht nur sichtbar, WELCHE Werte es gibt,
;; wo sie herkommen und wo sie (noch) dupliziert sind.
;;
;; Migrationsidee (spaeter, schrittweise, EIN Modul nach dem anderen):
;; einzelne Aufrufstellen von rohem Literal auf *vfk-*-Konstante umstellen,
;; mit Test in BricsCAD nach jedem Modul. Bei den bereits ueber ssg-cfg-or
;; konfigurierbaren Werten (gefaelle_winkel, bogen_winkel, feste_horizontal,
;; staustrecke_basis, separator_block_dx/dz, station_block_dx/dz,
;; skalierung_basis) bleibt die Config-Anbindung die fuehrende Quelle -
;; *vfk-*-Konstanten hier sind dafuer nur Fallback/Dokumentation, siehe
;; jeweiliger Kommentar.
;;
;; Geladen von vf_core.lsp VOR vf_standard/vf_etage/vf_linienzug (siehe
;; dortige Ladereihenfolge, dieselbe Guard-Systematik wie in den anderen
;; vf_*.lsp-Dateien: atoms-family-Check verhindert Doppel-Laden).
;; ============================================================
(if (not (car (atoms-family 1 '("VF-TYP-REGISTRIEREN"))))
(progn
(setq *vf-konst-core-pfad*
(cond
((getenv "DXFM_LISP")
(vl-string-translate "\\" "/" (getenv "DXFM_LISP")))
((and (boundp '*ssg-lisp-pfad*) *ssg-lisp-pfad*)
*ssg-lisp-pfad*)
(t nil)
)
)
(if *vf-konst-core-pfad*
(load (strcat *vf-konst-core-pfad* "/vf_core.lsp"))
(princ "\n[WARNUNG] vf_konstanten.lsp: DXFM_LISP/ssg-lisp-pfad nicht gesetzt.")
)
)
)
;; ============================================================
;; TEIL 1: WINKEL (Grad)
;; ============================================================
;; Basis-Neigungswinkel jeder Gefaellestrecke (GF) - AKTIVE Quelle bleibt
;; (ssg-cfg-or "vario" "gefaelle_winkel" 3), an >15 Stellen korrekt darueber
;; bezogen. ABER an mindestens 12 weiteren Stellen als rohes 3.0/3-Literal
;; dupliziert, OHNE Bezug zur Config (vf_standard.lsp Z.309/412;
;; vf_etage.lsp Z.449-450/479/654ff/793; vf_linienzug.lsp Z.1071/1554/2873/
;; 3394/4159/4273/4278) - eine Aenderung des Winkels ueber Config wuerde
;; diese Stellen NICHT mitziehen.
(if (null *vfk-gefaelle-winkel*) (setq *vfk-gefaelle-winkel* 3.0))
;; Toleranzband (Grad) um *vfk-gefaelle-winkel*: liegt der natuerliche
;; Neigungswinkel eines fallenden Segments innerhalb Toleranz, gilt es als
;; reine Gefaellestrecke statt VF. Bereits als *vfl-gf-winkel-toleranz* in
;; vf_linienzug.lsp benannt (Wert 0.5) - hier nur gespiegelt/dokumentiert.
(if (null *vfk-gf-winkel-toleranz*) (setq *vfk-gf-winkel-toleranz* 0.5))
;; Diskrete Bogenwinkel-Tabelle fuer VF-Boegen (auf/ab). AKTIVE Quelle in
;; vf_standard.lsp/vf_linienzug.lsp: (ssg-cfg-or "vario" "bogen_winkel" ...)
;; mit demselben Fallback. INKONSISTENZ: in vf_etage.lsp (Zeile ~447) fest
;; verdrahtet OHNE Config-Anbindung - eine Config-Aenderung wuerde dort
;; nicht greifen.
(if (null *vfk-bogen-winkel*) (setq *vfk-bogen-winkel* '(3 6 9 12 15 18 21 27 33 39 45 51)))
;; GF-Bogen-Winkel (horizontale Kurve): 30/60/90 Grad, ueberall als
;; Menue-Auswahl hartcodiert (KEIN Config-Bezug, auch nicht ueber
;; ssg-cfg-or) - Blocknamen "Gefaellebogen_<seite>_<winkel>_R500" leiten
;; sich direkt aus diesen drei Werten ab.
(if (null *vfk-gf-bogen-winkel*) (setq *vfk-gf-bogen-winkel* '(30 60 90)))
;; Etage-Typ: Schwenkwinkel der Ein-/Auslauf-Schraegsektion. Bereits als
;; ETAGE_HZ_WINKEL in vf_etage.lsp benannt (Wert 30, Kommentar "war frueher
;; 60") - hier nur gespiegelt.
(if (null *vfk-etage-hz-winkel*) (setq *vfk-etage-hz-winkel* 30.0))
;; Eckwinkel-Toleranz bei der automatischen Pfad-Klassifizierung (Modus 3,
;; vf-linienzug-modus3 -> vfl2-pruefe-eckwinkel). Rohes Literal in
;; vf_linienzug.lsp Zeile ~3386, keine Konstante bisher.
(if (null *vfk-eckwinkel-toleranz*) (setq *vfk-eckwinkel-toleranz* 5.0))
;; Schwellwert (Grad), ab dem ein Frame noch als "flach" (~0 Grad) gilt.
;; Rohes Literal in vfl-frame-flach-p (vf_linienzug.lsp), keine Konstante.
(if (null *vfk-frame-flach-toleranz*) (setq *vfk-frame-flach-toleranz* 1.5))
;; ============================================================
;; TEIL 2: HORIZONTALE BUDGETS (mm) - Umlenk-/Motorstation + Separatoren
;; ============================================================
;; ACHTUNG: vier verschiedene, NICHT austauschbare Werte fuer "horizontales
;; Budget der festen Elemente einer VF-Einheit", je nach Kontext - das ist
;; die verwirrendste Stelle im ganzen Modul-Satz:
;; - Standard-VF (2 Separatoren, Ein+Aus): FESTE_HORIZONTAL = 1600
;; (vf_standard.lsp Z.38, ssg-cfg-or "vario" "feste_horizontal" 1600)
;; - Linienzug-VF (1 Separator, nur Einlauf): *vfl-feste-horizontal* = 1300
;; (vf_linienzug.lsp Z.63)
;; - Etage-VF (mittlere Sektion): FESTE_ETAGE_MITTE = 1000
;; (vf_etage.lsp Z.41)
;; - Linienzug-Kettenende/Body-Abschluss (nur Motor+1 Separator, KEIN
;; Umlenk-Anteil): 800 als rohes Literal an >10 Stellen in
;; vf_linienzug.lsp (vfl-body-zerlegung, vfl3-waehle-winkel, ...)
;; Diese vier NICHT vereinheitlichen ohne sorgfaeltige Pruefung - sie
;; entstehen aus unterschiedlicher Bauteil-Zusammensetzung (siehe jeweiliger
;; Kommentar im Modul), keine Kopiergleichheit.
(if (null *vfk-feste-horizontal-standard*) (setq *vfk-feste-horizontal-standard* 1600.0))
(if (null *vfk-feste-horizontal-linienzug*) (setq *vfk-feste-horizontal-linienzug* 1300.0))
(if (null *vfk-feste-horizontal-etage*) (setq *vfk-feste-horizontal-etage* 1000.0))
(if (null *vfk-feste-horizontal-kettenende*) (setq *vfk-feste-horizontal-kettenende* 800.0))
;; Umlenk-/Motorstation-Fussabdruck (mm), je EINE Station. AKTIVE Quelle in
;; vf_standard.lsp: (ssg-cfg-or "vario" "station_block_dx" 500). In
;; vf_etage.lsp/vf_linienzug.lsp ueberwiegend als rohes 500/500.0-Literal
;; direkt in Formeln/Blockaufrufen dupliziert (>10 Fundstellen), OHNE
;; Config-Bezug.
(if (null *vfk-stations-laenge*) (setq *vfk-stations-laenge* 500.0))
;; Separator-Laenge (mm). AKTIVE Quelle in vf_standard.lsp: (ssg-cfg-or
;; "vario" "separator_block_dx" 300). In vf_etage.lsp/vf_linienzug.lsp
;; ueberwiegend als rohes 300/300.0-Literal dupliziert (Blockname
;; "Staustrecke_Separator_SP_300_mm" traegt den Wert zusaetzlich im String).
(if (null *vfk-separator-laenge*) (setq *vfk-separator-laenge* 300.0))
;; Mindestlaenge (mm) fuer eine VF-Einheit (Umlenk+Motor = 2x
;; *vfk-stations-laenge*). Rohes 1000.0-Literal an 7 Stellen in
;; vf_linienzug.lsp dupliziert (vfl-vf-entscheidung, vfl-vf-machbar-p,
;; vfl-segment-entscheidung, vf-linienzug-modus mehrfach).
(if (null *vfk-vf-mindestlaenge*) (setq *vfk-vf-mindestlaenge* 1000.0))
;; Mindestlaenge (mm) am Linienzug-Kettenende-Abschluss (nur Motor+
;; Separator, kein Umlenk-Anteil - siehe *vfk-feste-horizontal-kettenende*).
;; Rohes 800.0-Literal, identisch zum Budget-Wert selbst.
(if (null *vfk-kettenende-mindestlaenge*) (setq *vfk-kettenende-mindestlaenge* 800.0))
;; Mindestlaenge (mm) fuer die 3-Grad-GF-Anschlussstrecke (GF1 am Einlauf
;; einer VF-Einheit). Bereits als *vfl-gf-min-laenge* in vf_linienzug.lsp
;; benannt (Wert 400.0) - hier nur gespiegelt. In vf_linienzug.lsp Zeile
;; ~4143 zusaetzlich als rohes 400.0-Literal dupliziert (br-gf1), ohne
;; Bezug auf *vfl-gf-min-laenge*.
(if (null *vfk-gf-anschluss-mindestlaenge*) (setq *vfk-gf-anschluss-mindestlaenge* 400.0))
;; ============================================================
;; TEIL 3: STRECKENLAENGEN-GRENZWERTE (mm)
;; ============================================================
;; Foerderer-Maximallaenge (Linienzug-Einzelsegment beim Picken). Rohes
;; 25000.0-Literal in vfl-neue-linie-messen (vf_linienzug.lsp), keine
;; Konstante bisher.
(if (null *vfk-segment-maximallaenge*) (setq *vfk-segment-maximallaenge* 25000.0))
;; 20-Meter-Regel (Warnschwelle Gesamtlaenge seit letzter Umlenkstation,
;; siehe Prinzipien-Dok Abschnitt 7). Rohes 20000.0-Literal in
;; vfl-20m-check (vf_linienzug.lsp), keine Konstante bisher.
(if (null *vfk-motorabstand-warnung*) (setq *vfk-motorabstand-warnung* 20000.0))
;; Unterer Clamp-Wert (mm) fuer diverse Restlaengen-Berechnungen
;; ("max 100.0 ..."), verhindert negative/entartete Kurzstrecken. Rohes
;; 100.0-Literal an >10 Stellen in vf_linienzug.lsp dupliziert
;; (vfl-baue-horizontal-koerper, vf-linienzug-modus3-Umfeld, ...).
(if (null *vfk-restlaenge-min-clamp*) (setq *vfk-restlaenge-min-clamp* 100.0))
;; Unterer Clamp-Wert (mm) fuer die variable Auslauf-Staustrecke im
;; Etage-Typ ("Schutz gegen negative/zu kurze GF"). Rohes 50.0-Literal in
;; etage-foerderanlage-einfuegen (vf_etage.lsp Zeile ~800).
(if (null *vfk-etage-auslauf-min-clamp*) (setq *vfk-etage-auslauf-min-clamp* 50.0))
;; ============================================================
;; TEIL 4: FALLBACK-VERSATZWERTE (mm) - AS-/ES-/Gefaellebogen-Masse, falls
;; die Blockdefinition/das Koordinatensystem nicht extrahierbar ist
;; ============================================================
;; Diese Werte sind EMPIRISCH aus den realen Blockmassen abgeleitet und
;; sollten bei einer Aenderung der zugrundeliegenden DWG-Bloecke ebenfalls
;; neu vermessen werden - keine "sauberen" Rundwerte.
;; AS-/ES-Element-Fallback-Versatz (dx, mm), Standard-Typ (90 Grad) und
;; Linienzug. Rohes 576.0-Literal an mehreren Stellen in vf_linienzug.lsp
;; dupliziert (Zeile ~3393/4030/4031: "(if aus-dx aus-dx 576.0)" bzw.
;; ein-dx-Aequivalent).
(if (null *vfk-as-es-fallback-dx*) (setq *vfk-as-es-fallback-dx* 576.0))
;; Etage-Typ (30 Grad): eigene Fallback-Masse fuer AS_Element_30 (dx/dz,
;; vf_etage.lsp Zeile ~90/96) und ES_Element_30 (Zeile ~124/130) - NICHT
;; identisch zu *vfk-as-es-fallback-dx* (anderer Blocktyp/Winkel).
(if (null *vfk-etage-as-fallback-dx*) (setq *vfk-etage-as-fallback-dx* 525.8))
(if (null *vfk-etage-as-fallback-dz*) (setq *vfk-etage-as-fallback-dz* -72.9))
(if (null *vfk-etage-es-fallback-dx*) (setq *vfk-etage-es-fallback-dx* 576.2))
(if (null *vfk-etage-es-fallback-dz*) (setq *vfk-etage-es-fallback-dz* -54.6))
;; Etage-Typ: Fallback-Versatz (dz, mm) fuer Gefaellebogen links/rechts,
;; falls Block/KS nicht extrahierbar (vf_etage.lsp Zeile ~156-195).
(if (null *vfk-etage-gefaellebogen-fallback-dz*) (setq *vfk-etage-gefaellebogen-fallback-dz* -10.0))
;; ============================================================
;; TEIL 5: BESCHRIFTUNG / TEXT (mm)
;; ============================================================
;; Texthoehe (mm) des sichtbaren ATTDEF/TEXT-Labels (vf-make-label,
;; vf_core.lsp Zeile ~1073). Rohes Literal, keine Konstante bisher.
(if (null *vfk-label-texthoehe*) (setq *vfk-label-texthoehe* 100.0))
;; Texthoehe (mm) der unsichtbaren ATTDEFs (vf-block-erstellen,
;; vf_core.lsp Zeile ~1125). Rohes Literal, keine Konstante bisher.
(if (null *vfk-attdef-texthoehe*) (setq *vfk-attdef-texthoehe* 50.0))
;; Y-Versatz (mm) zwischen aufeinanderfolgenden ATTDEF-Zeilen
;; (vf_core.lsp Zeile ~1131). Rohes Literal, keine Konstante bisher.
(if (null *vfk-attdef-zeilenabstand*) (setq *vfk-attdef-zeilenabstand* 100.0))
;; Beschriftungsversatz (mm) senkrecht zur Fahrtrichtung (vf-make-label,
;; vf_core.lsp Zeile ~1059-1060). Rohes 200.0-Literal.
(if (null *vfk-label-versatz*) (setq *vfk-label-versatz* 200.0))
;; ============================================================
;; TEIL 6: SONSTIGE
;; ============================================================
;; mm -> m Umrechnungsfaktor fuer die Montagehoehe-Mittelwertbildung
;; ("(/ (+ hoehe-von hoehe-bis) 2000.0)" = Mittelwert zweier mm-Werte,
;; direkt in m). Kommt identisch in vf_core.lsp Zeile ~1154 UND
;; vf_linienzug.lsp Zeile ~2258/4742 vor - inhaltlich einfach 1000.0*2,
;; aber nirgends so ausgedrueckt.
(if (null *vfk-mm-je-m*) (setq *vfk-mm-je-m* 1000.0))
;; Skalierungsbasis (mm) fuer insert-inclined-scaled-block. AKTIVE Quelle:
;; (ssg-cfg-or "vario" "skalierung_basis" 1000.0), vf_core.lsp Zeile ~821.
;; Hier nur gespiegelt/dokumentiert.
(if (null *vfk-skalierungsbasis*) (setq *vfk-skalierungsbasis* 1000.0))
;; Toleranzband (mm) der automatischen Ketten-Nachbarschaftserkennung
;; (Vario_Kette_Merge). Bereits als *vfl-kette-tol-eng*/*vfl-kette-tol-weit*
;; in vf_linienzug.lsp benannt (Werte 2.0/100.0) - hier nur gespiegelt.
(if (null *vfk-kette-tol-eng*) (setq *vfk-kette-tol-eng* 2.0))
(if (null *vfk-kette-tol-weit*) (setq *vfk-kette-tol-weit* 100.0))
;; Diagnose-Schwellwert (mm): ab wann ein Anschlussabstand beim
;; Ketten-Verfolgen als "spuerbar, aber noch sauber" gilt (vfl-kette-
;; verfolgen, vf_linienzug.lsp Zeile ~4617). Rohes 0.5-Literal.
(if (null *vfk-kette-anschluss-warnung*) (setq *vfk-kette-anschluss-warnung* 0.5))
;; Warnschwelle (Grad): Vario-Winkel oberhalb des Maximums der
;; Bogenwinkel-Tabelle (Modus 3, vf-linienzug-modus3 Zeile ~4018). Rohes
;; 51.0-Literal, dupliziert das Maximum von *vfk-bogen-winkel*.
(if (null *vfk-vario-winkel-max*) (setq *vfk-vario-winkel-max* 51.0))
;; Empirischer Korrekturfaktor (mm) fuer die Bruecken-Hoehenberechnung in
;; Modus 3 (vf-linienzug-modus3, "dH-adj", vf_linienzug.lsp Zeile ~4162).
;; UNKOMMENTIERTE Herleitung im Original - nur "Motor + auf_3/ab_3"-Notiz.
;; Bei Gelegenheit pruefen/nachvollziehen, ob sich der Wert geometrisch
;; herleiten laesst statt empirisch fixiert zu bleiben.
(if (null *vfk-bruecke-korrektur*) (setq *vfk-bruecke-korrektur* 10.48))
(setq *vfk-konstanten-geladen* t)
(princ "\nvf_konstanten geladen.")
(princ)
+582 -194
View File
@@ -536,15 +536,34 @@
;; Zahl (Default = aktuelle Kettenhoehe, wie im Original-Prompt). Nutzt
;; bewusst den generischen Einzel-Dialog vflw_zahl (kein Punkt-Button, der
;; faelschlich eine hier moegliche Punktwahl suggerieren wuerde).
;; hoehe-default: aktuelle Kettenhoehe (Vorbelegung, wie im Original-Prompt).
(defun vflw-gruppe-ziel-hoehe-impl (hoehe-default / dat dcl-pfad ergebnis dlg-wert)
;; hoehe-default: entweder eine Zahl (aktuelle Kettenhoehe, alte Vorbelegung -
;; die bei direkter Uebernahme immer als deltaH=0 abgelehnt wird), ODER eine
;; Liste (hoehe-ab hoehe-auf) mit zwei baubaren Vorschlaegen (siehe
;; vfl-vf-hoehe-vorschlaege/vfl-segment-hoehe-vorschlaege) - dann zeigt der
;; Kopftext beide Richtungen, vorbelegt wird die Ab-Variante (haeufigerer
;; Fall, siehe vfl-segment-entscheidung). Ist hoehe-ab nil (kein baubarer
;; Wert in der sondierten Zone gefunden), faellt die Vorbelegung auf die
;; unveraenderte Kettenhoehe zurueck (altes Verhalten) plus Warnhinweis.
(defun vflw-gruppe-ziel-hoehe-impl (hoehe-default / dat dcl-pfad ergebnis dlg-wert
zwei-werte hoehe-ab hoehe-auf hoehe-kette vorbelegt)
(setq zwei-werte (listp hoehe-default))
(if zwei-werte
(progn
(setq hoehe-ab (nth 0 hoehe-default) hoehe-auf (nth 1 hoehe-default))
(setq hoehe-kette (nth 2 hoehe-default))
(setq vorbelegt (if hoehe-ab hoehe-ab hoehe-kette)))
(setq vorbelegt hoehe-default))
(setq dat (load_dialog (vflw-dcl-pfad)))
(if (not (new_dialog "vflw_zahl" dat))
(if (and dat (>= dat 0)) (unload_dialog dat))
(progn
(set_tile "kopf" (vflw-clean (ssg-textf "vfl-prompt-hoehe-endpunkt"
(list (rtos hoehe-default 2 1)))))
(set_tile "wert" (rtos hoehe-default 2 1))
(set_tile "kopf"
(vflw-clean
(if (and zwei-werte hoehe-ab hoehe-auf)
(ssg-textf "vfl-prompt-hoehe-endpunkt-2"
(list (rtos hoehe-ab 2 1) (rtos hoehe-auf 2 1)))
(ssg-textf "vfl-prompt-hoehe-endpunkt" (list (rtos vorbelegt 2 1))))))
(set_tile "wert" (rtos vorbelegt 2 1))
(action_tile "accept" "(setq dlg-wert (get_tile \"wert\")) (done_dialog 1)")
(action_tile "cancel" "(done_dialog 0)")
(setq ergebnis (start_dialog))
@@ -1020,6 +1039,223 @@
)
)
;; Stumme Variante von berechne-alle-winkel: NUR die Machbarkeits-Pruefung
;; (mind. ein Winkel mit L_GF>=0 und L_VF>=0), OHNE die Diagnosetabelle auf
;; die Kommandozeile zu schreiben. Rechenweg 1:1 aus berechne-alle-winkel
;; (vf_standard.lsp) uebernommen - bei Aenderungen dort auch hier nachziehen.
;; Gebraucht von vfl-vf-machbar-p fuer die Sondierung in vfl-vf-min-deltah,
;; die viele Testwerte durchprobiert (dort wuerde die Tabellenausgabe von
;; berechne-alle-winkel die Konsole zuspammen).
(defun vfl-winkel-machbar-p (deltaL deltaH richtung feste-hz /
winkel-list cos3 sin3 mass1 mass2 rad5 rad7
bogen-x1 bogen-z1 bogen-x2 bogen-z2 cosa sina
A B winkel-eff cosEff sinEff L_GF L_VF
abs-dz-AUS abs-dz-EIN gefunden)
(if (null feste-hz) (setq feste-hz FESTE_HORIZONTAL))
(setq abs-dz-AUS (abs aus-dz) abs-dz-EIN (abs ein-dz))
(setq winkel-list (ssg-cfg-or "vario" "bogen_winkel"
'(3 6 9 12 15 18 21 27 33 39 45 51)))
(setq cos3 (cos (* (ssg-cfg-or "vario" "gefaelle_winkel" 3) (/ pi 180.0)))
sin3 (sin (* (ssg-cfg-or "vario" "gefaelle_winkel" 3) (/ pi 180.0))))
(setq gefunden nil)
(foreach winkel winkel-list
(if (not gefunden)
(progn
(if (= richtung "Auf")
(setq mass1 (get-bogen-mass bogen-auf winkel)
mass2 (get-bogen-mass bogen-ab winkel))
(setq mass1 (get-bogen-mass bogen-ab winkel)
mass2 (get-bogen-mass bogen-auf winkel)))
(if (and mass1 mass2)
(progn
(setq rad5 (* 3.0 (/ pi 180.0)))
(setq rad7 (* (float (if (= richtung "Auf") (- 3 winkel) (+ winkel 3)))
(/ pi 180.0)))
(setq bogen-x1 (+ (* (car mass1) (cos rad5)) (* (caddr mass1) (sin rad5))))
(setq bogen-z1 (+ (* (- (car mass1)) (sin rad5)) (* (caddr mass1) (cos rad5))))
(setq bogen-x2 (+ (* (car mass2) (cos rad7)) (* (caddr mass2) (sin rad7))))
(setq bogen-z2 (+ (* (- (car mass2)) (sin rad7)) (* (caddr mass2) (cos rad7))))
(setq cosa (cos (* winkel (/ pi 180.0)))
sina (sin (* winkel (/ pi 180.0))))
(setq A (- deltaL aus-dx ein-dx bogen-x1 bogen-x2 (* feste-hz cos3)))
(setq winkel-eff (if (= richtung "Auf") (- winkel 3) (+ winkel 3)))
(setq cosEff (cos (* winkel-eff (/ pi 180.0)))
sinEff (sin (* winkel-eff (/ pi 180.0))))
(if (= richtung "Auf")
(setq B (+ deltaH abs-dz-AUS abs-dz-EIN (- bogen-z1) (- bogen-z2)
(* feste-hz sin3)))
(setq B (+ (- deltaH abs-dz-AUS abs-dz-EIN (* feste-hz sin3))
bogen-z1 bogen-z2)))
(if (> (abs sina) 0.0001)
(progn
(setq L_GF (/ (- (* A sinEff) (* B cosEff)) sina))
(if (= richtung "Auf")
(setq L_VF (/ (+ (* A sin3) (* B cos3)) sina))
(setq L_VF (/ (- (* B cos3) (* A sin3)) sina)))
(if (and (numberp L_GF) (numberp L_VF) (>= L_GF 0) (>= L_VF 0))
(setq gefunden t))
)
)
)
)
)
)
)
gefunden
)
;; Nur-Machbarkeits-Check (kein interaktives Waehlen wie vfl-waehle-winkel):
;; T, wenn fuer deltaL/deltaH/richtung MINDESTENS ein gueltiger Winkel bzw.
;; die horizontale Mitte existiert - sonst nil. Nutzt dieselbe Fallunter-
;; scheidung wie vfl-vf-entscheidung, aber ohne Nutzer-Interaktion (fuer die
;; Sondierung in vfl-vf-min-deltah). aus-dx/aus-dz werden wie in vfl-vf-winkel
;; temporaer genullt (AS-Footprint an dieser Stelle bereits verbraucht) -
;; sonst wuerde die Sondierung ein zu kleines Budget sehen und einen
;; eigentlich baubaren Wert faelschlich als "nicht baubar" verwerfen.
(defun vfl-vf-machbar-p (deltaL deltaH richtung / horizontal-info save-ausdx save-ausdz ergebnis)
(if (or (not *lib-initialized*) (null bogen-auf)) (init-bibliothek))
(cond
((< deltaL 1000.0) nil)
((< deltaH 1.0) nil)
((= richtung "Auf")
(setq save-ausdx aus-dx save-ausdz aus-dz)
(setq aus-dx 0.0 aus-dz 0.0)
(setq ergebnis (vfl-winkel-machbar-p deltaL deltaH "Auf" *vfl-feste-horizontal*))
(setq aus-dx save-ausdx aus-dz save-ausdz)
ergebnis)
(t
(setq horizontal-info (berechne-horizontale-mitte deltaL deltaH "Ab"))
(if (and horizontal-info (caddr horizontal-info))
t
(progn
(setq save-ausdx aus-dx save-ausdz aus-dz)
(setq aus-dx 0.0 aus-dz 0.0)
(setq ergebnis (vfl-winkel-machbar-p deltaL deltaH "Ab" *vfl-feste-horizontal*))
(setq aus-dx save-ausdx aus-dz save-ausdz)
ergebnis)))
)
)
;; Kleinste baubare Hoehendifferenz (mm, > 0) fuer deltaL/richtung sondieren -
;; linearer Anstieg in 10-mm-Schritten (grob genug fuer einen Vorschlagswert,
;; fein genug um keine schmale gueltige Zone zu ueberspringen) bis 1/3 von
;; deltaL (grosszuegige Obergrenze; steilere Faelle braucht kein Vorschlag).
;; Rueckgabe: deltaH (mm) oder nil, wenn in diesem Bereich nichts baubar ist.
(defun vfl-vf-min-deltah (deltaL richtung / schritt grenze h gefunden)
(setq schritt 10.0)
(setq grenze (/ deltaL 3.0))
(setq h schritt gefunden nil)
(while (and (not gefunden) (<= h grenze))
(if (vfl-vf-machbar-p deltaL h richtung)
(setq gefunden h)
(setq h (+ h schritt)))
)
gefunden
)
;; Liefert zwei baubare Ziel-Hoehen-Vorschlaege (Ab zuerst, Auf danach) fuer
;; die aktuelle Kettenhoehe p-aktuell-z bei gegebenem deltaL - Ersatz fuer den
;; blossen "unveraenderte Ist-Hoehe"-Default, der bei direkter Uebernahme
;; immer als deltaH=0 ("kein sinnvolles VF") abgelehnt wird (siehe
;; vfl-vf-entscheidung). NUR-VF-Variante: fuer den expliziten "Linie-VF"-
;; Menuepunkt, wo GF keine Option ist (der Nutzer hat VF bereits gewaehlt).
;; Rueckgabe: (hoehe-ab hoehe-auf) - je nil, wenn in der sondierten Zone kein
;; baubarer Wert existiert.
(defun vfl-vf-hoehe-vorschlaege (p-aktuell-z deltaL / min-ab min-auf)
(setq min-ab (vfl-vf-min-deltah deltaL "Ab"))
(setq min-auf (vfl-vf-min-deltah deltaL "Auf"))
(list
(if min-ab (- p-aktuell-z min-ab) nil)
(if min-auf (+ p-aktuell-z min-auf) nil))
)
;; Wie vfl-vf-hoehe-vorschlaege, aber fuer den automatischen "Linie"-Menue-
;; punkt (vfl-segment-entscheidung: GF ODER VF). Der Ab-Vorschlag nutzt dort
;; NICHT die VF-Sondierung, sondern direkt die feste 3-Grad-GF-Neigung
;; (deltaH = deltaL*tan(3 Grad), wie im bestehenden Kurzsegment-Zweig,
;; vfl-baue-mehrsegment-linie oben) - bei exakt 3 Grad natuerlichem Winkel
;; greift IMMER der GF-Zweig von vfl-segment-entscheidung (Toleranzband um
;; 3 Grad), eine reine Gefaellestrecke hat keine deltaL-Mindestlaenge und ist
;; damit garantiert baubar, ohne die (teurere) VF-Sondierung zu brauchen. Der
;; Auf-Vorschlag bleibt VF-only (GF kann nicht steigen).
(defun vfl-segment-hoehe-vorschlaege (p-aktuell-z deltaL / min-ab min-auf rad3)
(setq rad3 (* (float (ssg-cfg-or "vario" "gefaelle_winkel" 3)) (/ pi 180.0)))
(setq min-ab (* deltaL (/ (sin rad3) (cos rad3))))
(setq min-auf (vfl-vf-min-deltah deltaL "Auf"))
(list
(- p-aktuell-z min-ab)
(if min-auf (+ p-aktuell-z min-auf) nil))
)
;; Hinweis auf die Konsole, wenn NUR EINE der beiden Richtungen einen
;; baubaren Vorschlag hat (die andere Richtung ist bei dieser Segmentlaenge
;; also aussichtslos) - macht sichtbar, warum der Dialog/Prompt dann nur
;; einen Wert zeigt, statt es wie einen Fehler wirken zu lassen.
(defun vfl-hoehe-hinweis-falls-noetig (hoehe-ab hoehe-auf)
(if (or (and hoehe-ab (not hoehe-auf)) (and hoehe-auf (not hoehe-ab)))
(princ (ssg-text "vfl-hinweis-hoehe-vorschlag-fehlt")))
(princ)
)
;; Wie vfl-vf-machbar-p, aber fuer das Budget von vfl-body-zerlegung
;; (Kettenende-Modus, "Ja - Motorstation setzen, Kettenende festlegen"):
;; feste-hz=800 (nur Motor+Separator, KEIN Umlenk-/AS-Anteil) statt
;; *vfl-feste-horizontal*, Mindestlaenge 800mm statt 1000mm, und bei
;; praktisch flachem Rest (deltaH<1) NUR die horizontale Mitte (kein
;; direkter GF-Fallback wie bei vfl-vf-machbar-p - vfl-body-zerlegung prueft
;; GF nur beim natuerlichen ~3-Grad-Fall weiter unten). aus-dx/aus-dz werden
;; wie im Original immer genullt (nicht nur bedingt wie bei vfl-vf-machbar-p),
;; da der Abschluss-Koerper nie einen AS-Fussabdruck traegt.
(defun vfl-body-machbar-p (deltaL deltaH richtung / horizontal-info save-ausdx save-ausdz ergebnis)
(if (or (not *lib-initialized*) (null bogen-auf)) (init-bibliothek))
(setq save-ausdx aus-dx save-ausdz aus-dz)
(setq aus-dx 0.0 aus-dz 0.0)
(setq ergebnis
(cond
((< deltaL 800.0) nil)
((< deltaH 1.0)
(setq horizontal-info (berechne-horizontale-mitte deltaL deltaH "Ab"))
(and horizontal-info (caddr horizontal-info) t))
((= richtung "Auf")
(vfl-winkel-machbar-p deltaL deltaH "Auf" 800.0))
(t
(setq horizontal-info (berechne-horizontale-mitte deltaL deltaH "Ab"))
(if (and horizontal-info (caddr horizontal-info))
t
(vfl-winkel-machbar-p deltaL deltaH "Ab" 800.0)))
)
)
(setq aus-dx save-ausdx aus-dz save-ausdz)
ergebnis
)
;; Wie vfl-vf-min-deltah, aber mit vfl-body-machbar-p (Budget von
;; vfl-body-zerlegung statt vfl-vf-entscheidung).
(defun vfl-body-min-deltah (deltaL richtung / schritt grenze h gefunden)
(setq schritt 10.0)
(setq grenze (/ deltaL 3.0))
(setq h schritt gefunden nil)
(while (and (not gefunden) (<= h grenze))
(if (vfl-body-machbar-p deltaL h richtung)
(setq gefunden h)
(setq h (+ h schritt)))
)
gefunden
)
;; Wie vfl-vf-hoehe-vorschlaege, aber fuer vfl-body-abschluss (Kettenende-
;; Modus): nutzt vfl-body-min-deltah (800mm-Budget) statt vfl-vf-min-deltah
;; (1300mm-Budget) - sonst wuerde ein Vorschlag als baubar erscheinen, der es
;; am Kettenende (kleineres Budget: nur Motor+Separator, kein Umlenk-Anteil)
;; tatsaechlich nicht ist.
(defun vfl-body-hoehe-vorschlaege (p-aktuell-z deltaL / min-ab min-auf)
(setq min-ab (vfl-body-min-deltah deltaL "Ab"))
(setq min-auf (vfl-body-min-deltah deltaL "Auf"))
(list
(if min-ab (- p-aktuell-z min-ab) nil)
(if min-auf (+ p-aktuell-z min-auf) nil))
)
;; Rueckgabe: (typ winkel L_GF L_VF)
;; typ="GF": winkel = kontinuierlicher Neigungswinkel, L_GF/L_VF ungenutzt (nil)
;; typ="VF": winkel = best-winkel (0 = Horizontale Mitte), L_GF/L_VF wie
@@ -1405,7 +1641,8 @@
;; Rueckgabe: (frame anzahl-koerper letzt-hz gf2-laenge) oder nil.
(defun vfl-body-abschluss (frame letzt-hz p-umlenk /
linie-mess dL hzn hn dH richtn rad3 dec typ w lgf lvf
gf2 cnt p0 tx ty)
gf2 cnt p0 tx ty
hoehe-vorschlaege hoehe-ab hoehe-auf hoehe-fallback)
;; Der Abschluss-Koerper (vfs-vf-koerper) und der Motor gehen von 3-Grad-Basis
;; aus - eine gerade laufende flache Zone hier mit ab_3 abschliessen.
(setq frame (vfl-nach-3grad frame))
@@ -1414,11 +1651,24 @@
(progn (princ (ssg-text "vfl-abgebrochen-kein-ziel")) nil)
(progn
(setq dL (car linie-mess) hzn (cadr linie-mess))
;; Baubare Vorschlaege (Ab/Auf) statt der unveraenderten Kettenhoehe als
;; Default - sonst waere dH=0 ("Auf", da (>= 0.0 0.0)) und der Rest wird
;; von vfl-body-zerlegung sofort als "nicht baubar" abgelehnt (kleineres
;; Budget als vfl-vf-entscheidung: nur Motor+Separator, 800mm statt
;; 1300mm) - siehe vfl-body-hoehe-vorschlaege/vfl-body-machbar-p.
(setq hoehe-vorschlaege (vfl-body-hoehe-vorschlaege (caddr (car frame)) dL))
(setq hoehe-ab (nth 0 hoehe-vorschlaege) hoehe-auf (nth 1 hoehe-vorschlaege))
(setq hoehe-fallback (if hoehe-ab hoehe-ab (caddr (car frame))))
(vfl-hoehe-hinweis-falls-noetig hoehe-ab hoehe-auf)
(if (vfl-wizard-aktiv)
(vl-catch-all-apply 'vflw-gruppe-ziel-hoehe-impl (list (caddr (car frame)))))
(setq hn (vfl-in-real (ssg-textf "vfl-prompt-hoehe-kettenende"
(list (rtos (caddr (car frame)) 2 1)))))
(if (null hn) (setq hn (caddr (car frame))))
(vl-catch-all-apply 'vflw-gruppe-ziel-hoehe-impl
(list (list hoehe-ab hoehe-auf (caddr (car frame))))))
(setq hn (vfl-in-real
(if (and hoehe-ab hoehe-auf)
(ssg-textf "vfl-prompt-hoehe-kettenende-2"
(list (rtos hoehe-ab 2 1) (rtos hoehe-auf 2 1)))
(ssg-textf "vfl-prompt-hoehe-kettenende" (list (rtos hoehe-fallback 2 1))))))
(if (null hn) (setq hn hoehe-fallback))
(setq dH (- hn (caddr (car frame))))
(setq richtn (if (>= dH 0.0) "Auf" "Ab"))
(setq dH (abs dH))
@@ -1430,8 +1680,15 @@
(if (null typ)
(progn
(princ (ssg-text "vfl-fehler-rest-nicht-baubar"))
(dbgmsg (strcat "GEOMETRIE FEHLGESCHLAGEN: Kettenende-Abschluss nicht baubar (dL="
(rtos dL 2 0) " dH=" (rtos dH 2 0) " richtung=" richtn ")"))
nil)
(progn
(dbgmsg (strcat "GEOMETRIE: vfl-body-zerlegung ERFOLG (dL=" (rtos dL 2 0)
" dH=" (rtos dH 2 0) " richtung=" richtn
" typ=" typ " winkel=" (rtos (float w) 2 1)
" L_GF=" (if lgf (rtos lgf 2 0) "nil")
" L_VF=" (if lvf (rtos lvf 2 0) "nil") ")"))
;; Soll-ES-Punkt fuer den Ist-Ziel-Report merken (Startpunkt +
;; projizierter Laenge entlang der Fahrtrichtung).
(setq p0 (car frame))
@@ -1460,6 +1717,8 @@
(princ (ssg-textf "vfl-hinweis-gf2-minimum"
(list (rtos gf2 2 0) (rtos *vfl-gf-min-laenge* 2 0))))
(setq gf2 *vfl-gf-min-laenge*)))
(dbgmsg (strcat "GEOMETRIE ERFOLG: Kettenende-Abschluss gebaut (cnt=" (itoa cnt)
" gf2=" (rtos gf2 2 0) "), neue Position=" (dbg-tostring (car frame))))
(list frame cnt hzn gf2)
)
)
@@ -1472,7 +1731,8 @@
p-umlenk vf-count antwort L_GF-eff L_GF1-bau L_GF2-bau
linie-mess dL dH hn hzn richtn ent typ w lgf lvf
letzt-hz fertig ziel-ende ziel-gf2 res3 gf2-eff entry-start
res-h vor-antwort es-gewuenscht es-antwort save-eindx save-eindz)
res-h vor-antwort es-gewuenscht es-antwort save-eindx save-eindz
hoehe-vorschlaege hoehe-ab hoehe-auf hoehe-fallback)
;; Vorbelegung: ES gewuenscht (Default) - nur bei "3 - Kettenende definieren"
;; wird explizit gefragt und ggf. auf nil gesetzt (siehe dort).
(setq es-gewuenscht t)
@@ -1620,11 +1880,25 @@
(setq dL (car linie-mess) hzn (cadr linie-mess))
(if (> dL 1.0)
(progn
;; NUR-VF-Vorschlaege (nicht vfl-segment-hoehe-vorschlaege):
;; dieser Zweig setzt eine bestehende VF-Kette fort und lehnt
;; ein hier zurueckkommendes typ="GF" explizit ab (siehe
;; "vfl-segment-gf-nicht-erlaubt" unten) - der GF-Vorschlag
;; (3-Grad-Formel) waere hier also gerade NICHT baubar.
(setq hoehe-vorschlaege (vfl-vf-hoehe-vorschlaege (caddr (car frame)) dL))
(setq hoehe-ab (nth 0 hoehe-vorschlaege) hoehe-auf (nth 1 hoehe-vorschlaege))
(setq hoehe-fallback (if hoehe-ab hoehe-ab (caddr (car frame))))
(vfl-hoehe-hinweis-falls-noetig hoehe-ab hoehe-auf)
(if (vfl-wizard-aktiv)
(vl-catch-all-apply 'vflw-gruppe-ziel-hoehe-impl (list (caddr (car frame)))))
(setq hn (vfl-in-real (ssg-textf "vfl-prompt-hoehe-endpunkt"
(list (rtos (caddr (car frame)) 2 1)))))
(if (null hn) (setq hn (caddr (car frame))))
(vl-catch-all-apply 'vflw-gruppe-ziel-hoehe-impl
(list (list hoehe-ab hoehe-auf (caddr (car frame))))))
(setq hn (vfl-in-real
(if (and hoehe-ab hoehe-auf)
(ssg-textf "vfl-prompt-hoehe-endpunkt-2"
(list (rtos hoehe-ab 2 1) (rtos hoehe-auf 2 1)))
(ssg-textf "vfl-prompt-hoehe-endpunkt"
(list (rtos hoehe-fallback 2 1))))))
(if (null hn) (setq hn hoehe-fallback))
(setq dH (- hn (caddr (car frame))))
(setq richtn (if (>= dH 0.0) "Auf" "Ab"))
(setq dH (abs dH))
@@ -1714,17 +1988,26 @@
(defun vfl-insert-gf-bogen-block (frame bwinkel bseite / blockname neuer-frame hz-gemessen hz-gesnappt)
(setq blockname (gf-bogen-blockname bwinkel bseite))
(princ (ssg-textf "vfl-fuege-block-ein" (list blockname)))
(dbgmsg (strcat "GEOMETRIE: vfl-insert-gf-bogen-block (block=" blockname
" bwinkel=" (itoa bwinkel) " bseite=" bseite ")"))
;; GF-Bogen zaehlen (Seite L/R + Winkel) -> Attribut GF_Bogen_L/R_xx
(setq *vfl-acc-gfbogen*
(vfl-inc-count *vfl-acc-gfbogen*
(strcat (if (= bseite "rechts") "R" "L") "_" (itoa bwinkel))))
(setq neuer-frame (insert-block-ks-to-ks blockname frame))
(setq hz-gemessen (car (frame->hz-winkel neuer-frame)))
(setq hz-gesnappt (vfl-hz-snappen-absolut hz-gemessen))
;; Reine Z-Drehung statt make-frame-from-dir-Neuaufbau: erhaelt die aus dem
;; Block gemessene Rollung (yu/zu) - siehe Kommentar bei vfl-frame-um-z-drehen.
(if (> (abs (- hz-gemessen hz-gesnappt)) 0.0001)
(setq neuer-frame (vfl-frame-um-z-drehen neuer-frame (- hz-gesnappt hz-gemessen))))
(if (null neuer-frame)
(dbgmsg (strcat "GEOMETRIE FEHLGESCHLAGEN: Block " blockname " nicht eingefuegt"))
(progn
(setq hz-gemessen (car (frame->hz-winkel neuer-frame)))
(setq hz-gesnappt (vfl-hz-snappen-absolut hz-gemessen))
;; Reine Z-Drehung statt make-frame-from-dir-Neuaufbau: erhaelt die aus dem
;; Block gemessene Rollung (yu/zu) - siehe Kommentar bei vfl-frame-um-z-drehen.
(if (> (abs (- hz-gemessen hz-gesnappt)) 0.0001)
(setq neuer-frame (vfl-frame-um-z-drehen neuer-frame (- hz-gesnappt hz-gemessen))))
(dbgmsg (strcat "GEOMETRIE ERFOLG: GF-Bogen gebaut, neue Position="
(dbg-tostring (car neuer-frame))))
)
)
neuer-frame
)
@@ -2126,7 +2409,8 @@
frame letzter-typ fertig linie-ende-modus rad3
anzahl-gf anzahl-vf vfl-nummer lastEnt
gf-max-winkel gf-ok kettenanfang pick-punkt
as-vorhanden erg old-error vfl-ins dbg-an)
as-vorhanden erg old-error vfl-ins dbg-an
hoehe-vorschlaege hoehe-ab hoehe-auf hoehe-fallback)
(princ "\n\n=========================================")
(princ (ssg-text "vfl-modus1-header"))
(princ "\n=========================================")
@@ -2327,10 +2611,17 @@
)
)
(if (< deltaL 1000.0)
(princ (ssg-text "vfl-fehler-horizontal-vf-kurz"))
(progn
(princ (ssg-text "vfl-fehler-horizontal-vf-kurz"))
(if dbg-an
(dbgmsg (strcat "GEOMETRIE FEHLGESCHLAGEN: Horizontal-VF zu kurz (deltaL="
(rtos deltaL 2 0) ")"))))
(progn
;; VF-Einheit mit horizontalem ersten Koerper (winkel=0, L_VF=deltaL,
;; L_GF = Mindestlaenge fuer den Einlauf-Anschluss).
(if dbg-an
(dbgmsg (strcat "GEOMETRIE: vfl-vf-einheit-abschluss horizontal (deltaL=" (rtos deltaL 2 0)
" L_GF=" (rtos *vfl-gf-min-laenge* 2 0) " L_VF=" (rtos deltaL 2 0) ")")))
(setq vf-einheit-res
(vfl-vf-einheit-abschluss frame hz-neu "Ab" 0 *vfl-gf-min-laenge* deltaL nil))
(setq frame (nth 0 vf-einheit-res))
@@ -2339,6 +2630,9 @@
(if (nth 3 vf-einheit-res) (setq es-seite (nth 3 vf-einheit-res)))
(setq letzter-typ "VF")
(setq p-aktuell (car frame))
(if dbg-an
(dbgmsg (strcat "GEOMETRIE ERFOLG: Horizontal-VF-Einheit gebaut, neue Position="
(dbg-tostring p-aktuell))))
)
)
)
@@ -2371,89 +2665,119 @@
(setq frame (nth 0 erg) deltaL (nth 1 erg) p-aktuell (car frame))
)
)
(setq gf-ok t)
(if (vfl-wizard-aktiv)
(vl-catch-all-apply 'vflw-gruppe-gefaelle-impl
(list (vfl-gf-hoehe-vorschlag (caddr p-aktuell)))))
(princ (ssg-text "vfl-gefaelle-festlegen-header"))
(princ (ssg-text "vfl-gefaelle-opt-hoehe"))
(princ (ssg-text "vfl-gefaelle-opt-winkel"))
(setq antwort (vfl-menu (ssg-text "prompt-wahl-1-2")
(list (ssg-text "vfl-gefaelle-opt-hoehe")
(ssg-text "vfl-gefaelle-opt-winkel")) 1
"vfl-gefaelle-festlegen-header"))
(if (= antwort "2")
;; Nach dem AS-Einfuegen kann die reale Restlaenge (aus dem
;; tatsaechlichen KS_AUS neu gemessen) kleiner als der urspruenglich
;; gepickte Rohwert sein - bei einem knapp gepickten Punkt sogar
;; NEGATIV (das AS-Element allein braucht bereits mehr Platz als bis
;; zum Klickpunkt vorhanden war). Ohne diese zweite Pruefung wuerde
;; vfl-insert-gf-segment mit negativem deltaL "erfolgreich" eine
;; entartete/unsichtbare GF-Strecke bauen (leerer Sprung zwischen AS
;; und dem naechsten Element) statt den Nutzer erneut picken zu
;; lassen - siehe vfl-fehler-linie-zu-kurz oben (dieselbe Meldung).
;; Sofortiger Abbruch DIESES Zweigs (kein Weiterfragen nach Winkel/
;; Hoehe fuer ein Segment, das ohnehin nicht gebaut werden kann) -
;; gf-ok wird unten sonst mehrfach ueberschrieben.
(if (< deltaL 1.0)
(princ (ssg-text "vfl-fehler-linie-zu-kurz"))
(progn
;; Winkel direkt vorgeben - deltaH ergibt sich aus deltaL*tan(winkel).
(setq winkel
(vfl-in-real (ssg-textf "vfl-prompt-neigungswinkel" (list (rtos gf-max-winkel 2 1)))))
(if (null winkel) (setq winkel gf-max-winkel))
(if (or (<= winkel 0.0) (> winkel gf-max-winkel))
(setq gf-ok t)
(if (vfl-wizard-aktiv)
(vl-catch-all-apply 'vflw-gruppe-gefaelle-impl
(list (vfl-gf-hoehe-vorschlag (caddr p-aktuell)))))
(princ (ssg-text "vfl-gefaelle-festlegen-header"))
(princ (ssg-text "vfl-gefaelle-opt-hoehe"))
(princ (ssg-text "vfl-gefaelle-opt-winkel"))
(setq antwort (vfl-menu (ssg-text "prompt-wahl-1-2")
(list (ssg-text "vfl-gefaelle-opt-hoehe")
(ssg-text "vfl-gefaelle-opt-winkel")) 1
"vfl-gefaelle-festlegen-header"))
(if (= antwort "2")
(progn
(alert (ssg-textf "vfl-alert-winkel-ungueltig"
(list (rtos winkel 2 1) (rtos gf-max-winkel 2 1))))
(setq gf-ok nil))
(progn
(setq richtung "Ab")
(setq deltaH (* deltaL (/ (sin (* winkel (/ pi 180.0)))
(cos (* winkel (/ pi 180.0))))))
;; Winkel direkt vorgeben - deltaH ergibt sich aus deltaL*tan(winkel).
(setq winkel
(vfl-in-real (ssg-textf "vfl-prompt-neigungswinkel" (list (rtos gf-max-winkel 2 1)))))
(if (null winkel) (setq winkel gf-max-winkel))
(if (or (<= winkel 0.0) (> winkel gf-max-winkel))
(progn
(alert (ssg-textf "vfl-alert-winkel-ungueltig"
(list (rtos winkel 2 1) (rtos gf-max-winkel 2 1))))
(setq gf-ok nil))
(progn
(setq richtung "Ab")
(setq deltaH (* deltaL (/ (sin (* winkel (/ pi 180.0)))
(cos (* winkel (/ pi 180.0))))))
)
)
)
)
)
(progn
;; Gegebene Hoehe - wie bisher, aber Winkel wird daraus abgeleitet
;; und gegen den GF-Maximalwinkel geprueft (GF kann nicht steigen).
;; p-aktuell ist ab hier immer der reale Referenzpunkt (bei
;; Kettenanfang das echte KS_AUS des AS-Elements). Vorschlag/
;; Enter-Default = vfl-gf-hoehe-vorschlag (siehe dort), NICHT
;; die unveraenderte Ist-Hoehe - sonst waere deltaH=0 und die
;; GF-Pruefung wiese den Wert als "kann nicht steigen" ab.
(setq hoehe-neu
(vfl-in-real (ssg-textf "vfl-prompt-hoehe-linienendpunkt"
(list (rtos (vfl-gf-hoehe-vorschlag (caddr p-aktuell)) 2 1)))))
(if (null hoehe-neu) (setq hoehe-neu (vfl-gf-hoehe-vorschlag (caddr p-aktuell))))
(setq deltaH (- hoehe-neu (caddr p-aktuell)))
(setq richtung (if (>= deltaH 0.0) "Auf" "Ab"))
(setq deltaH (abs deltaH))
(cond
((= richtung "Auf")
(alert (ssg-text "vfl-alert-gf-kann-nicht-steigen"))
(setq gf-ok nil))
(t
(setq winkel (* (atan (/ deltaH deltaL)) (/ 180.0 pi)))
(if (> winkel gf-max-winkel)
(progn
(alert (ssg-textf "vfl-alert-gefaelle-zu-steil"
(list (rtos winkel 2 1) (rtos gf-max-winkel 2 1))))
(progn
;; Gegebene Hoehe - wie bisher, aber Winkel wird daraus abgeleitet
;; und gegen den GF-Maximalwinkel geprueft (GF kann nicht steigen).
;; p-aktuell ist ab hier immer der reale Referenzpunkt (bei
;; Kettenanfang das echte KS_AUS des AS-Elements). Vorschlag/
;; Enter-Default = vfl-gf-hoehe-vorschlag (siehe dort), NICHT
;; die unveraenderte Ist-Hoehe - sonst waere deltaH=0 und die
;; GF-Pruefung wiese den Wert als "kann nicht steigen" ab.
(setq hoehe-neu
(vfl-in-real (ssg-textf "vfl-prompt-hoehe-linienendpunkt"
(list (rtos (vfl-gf-hoehe-vorschlag (caddr p-aktuell)) 2 1)))))
(if (null hoehe-neu) (setq hoehe-neu (vfl-gf-hoehe-vorschlag (caddr p-aktuell))))
(setq deltaH (- hoehe-neu (caddr p-aktuell)))
(setq richtung (if (>= deltaH 0.0) "Auf" "Ab"))
(setq deltaH (abs deltaH))
(cond
((= richtung "Auf")
(alert (ssg-text "vfl-alert-gf-kann-nicht-steigen"))
(if dbg-an
(dbgmsg (strcat "GEOMETRIE FEHLGESCHLAGEN: Linie-GF kann nicht steigen"
" (deltaL=" (rtos deltaL 2 0) " deltaH=" (rtos deltaH 2 0) ")")))
(setq gf-ok nil))
)
(t
(setq winkel (* (atan (/ deltaH deltaL)) (/ 180.0 pi)))
(if (> winkel gf-max-winkel)
(progn
(alert (ssg-textf "vfl-alert-gefaelle-zu-steil"
(list (rtos winkel 2 1) (rtos gf-max-winkel 2 1))))
(if dbg-an
(dbgmsg (strcat "GEOMETRIE FEHLGESCHLAGEN: Linie-GF zu steil (deltaL="
(rtos deltaL 2 0) " deltaH=" (rtos deltaH 2 0)
" winkel=" (rtos winkel 2 1) " max=" (rtos gf-max-winkel 2 1) ")")))
(setq gf-ok nil))
)
)
)
)
)
)
)
(if gf-ok
(progn
(setq frame (vfl-insert-gf-segment (car frame) hz-neu deltaL winkel))
(setq anzahl-gf (1+ anzahl-gf))
(vfl-acc-gf-seg (/ deltaL (cos (* (float winkel) (/ pi 180.0)))) winkel)
(setq letzter-typ "GF")
(setq p-aktuell (car frame))
(princ (ssg-text "vfl-ist-kettenende-header"))
(princ (ssg-text "vfl-kettenende-opt-ja-es"))
(princ (ssg-text "vfl-kettenende-opt-ja-ohne-es"))
(princ (ssg-text "vfl-kettenende-opt-nein"))
(setq antwort (vfl-menu (ssg-text "vfl-prompt-wahl-1-3-def3")
(list (ssg-text "vfl-kettenende-opt-ja-es")
(ssg-text "vfl-kettenende-opt-ja-ohne-es")
(ssg-text "vfl-kettenende-opt-nein")) 3
"vfl-ist-kettenende-header"))
(cond
((= antwort "1")
(setq es-seite (vfl-frage-es-seite))
(setq frame (vfl-insert-es-element "GF" frame hz-neu winkel
(caddr (car frame)) es-seite))
(setq fertig t))
((= antwort "2") (setq fertig t))
(if gf-ok
(progn
(if dbg-an
(dbgmsg (strcat "GEOMETRIE: vfl-insert-gf-segment (deltaL=" (rtos deltaL 2 0)
" hz=" (rtos hz-neu 2 1) " winkel=" (rtos winkel 2 1) ")")))
(setq frame (vfl-insert-gf-segment (car frame) hz-neu deltaL winkel))
(setq anzahl-gf (1+ anzahl-gf))
(vfl-acc-gf-seg (/ deltaL (cos (* (float winkel) (/ pi 180.0)))) winkel)
(setq letzter-typ "GF")
(setq p-aktuell (car frame))
(if dbg-an
(dbgmsg (strcat "GEOMETRIE ERFOLG: GF-Segment gebaut, neue Position="
(dbg-tostring p-aktuell))))
(princ (ssg-text "vfl-ist-kettenende-header"))
(princ (ssg-text "vfl-kettenende-opt-ja-es"))
(princ (ssg-text "vfl-kettenende-opt-ja-ohne-es"))
(princ (ssg-text "vfl-kettenende-opt-nein"))
(setq antwort (vfl-menu (ssg-text "vfl-prompt-wahl-1-3-def3")
(list (ssg-text "vfl-kettenende-opt-ja-es")
(ssg-text "vfl-kettenende-opt-ja-ohne-es")
(ssg-text "vfl-kettenende-opt-nein")) 3
"vfl-ist-kettenende-header"))
(cond
((= antwort "1")
(setq es-seite (vfl-frage-es-seite))
(setq frame (vfl-insert-es-element "GF" frame hz-neu winkel
(caddr (car frame)) es-seite))
(setq fertig t))
((= antwort "2") (setq fertig t))
)
)
)
)
)
@@ -2480,11 +2804,20 @@
(if (< deltaL 1000.0)
(princ (ssg-text "vfl-fehler-vf-kurz"))
(progn
(setq hoehe-vorschlaege (vfl-vf-hoehe-vorschlaege (caddr p-aktuell) deltaL))
(setq hoehe-ab (nth 0 hoehe-vorschlaege) hoehe-auf (nth 1 hoehe-vorschlaege))
(setq hoehe-fallback (if hoehe-ab hoehe-ab (caddr p-aktuell)))
(vfl-hoehe-hinweis-falls-noetig hoehe-ab hoehe-auf)
(if (vfl-wizard-aktiv)
(vl-catch-all-apply 'vflw-gruppe-ziel-hoehe-impl (list (caddr p-aktuell))))
(vl-catch-all-apply 'vflw-gruppe-ziel-hoehe-impl
(list (list hoehe-ab hoehe-auf (caddr p-aktuell)))))
(setq hoehe-neu
(vfl-in-real (ssg-textf "vfl-prompt-hoehe-linienendpunkt" (list (rtos (caddr p-aktuell) 2 1)))))
(if (null hoehe-neu) (setq hoehe-neu (caddr p-aktuell)))
(vfl-in-real
(if (and hoehe-ab hoehe-auf)
(ssg-textf "vfl-prompt-hoehe-linienendpunkt-2"
(list (rtos hoehe-ab 2 1) (rtos hoehe-auf 2 1)))
(ssg-textf "vfl-prompt-hoehe-linienendpunkt" (list (rtos hoehe-fallback 2 1))))))
(if (null hoehe-neu) (setq hoehe-neu hoehe-fallback))
(setq deltaH (- hoehe-neu (caddr p-aktuell)))
(setq richtung (if (>= deltaH 0.0) "Auf" "Ab"))
(setq deltaH (abs deltaH))
@@ -2492,9 +2825,19 @@
(setq typ (nth 0 entscheidung) winkel (nth 1 entscheidung)
L_GF (nth 2 entscheidung) L_VF (nth 3 entscheidung))
(if (null typ)
(alert (ssg-textf "vfl-alert-vf-nicht-baubar"
(list (rtos deltaL 2 0) (rtos deltaH 2 0) richtung)))
(progn
(alert (ssg-textf "vfl-alert-vf-nicht-baubar"
(list (rtos deltaL 2 0) (rtos deltaH 2 0) richtung)))
(if dbg-an
(dbgmsg (strcat "GEOMETRIE FEHLGESCHLAGEN: Linie-VF nicht baubar (deltaL="
(rtos deltaL 2 0) " deltaH=" (rtos deltaH 2 0)
" richtung=" richtung ")"))))
(progn
(if dbg-an
(dbgmsg (strcat "GEOMETRIE: vfl-vf-einheit-abschluss (deltaL=" (rtos deltaL 2 0)
" deltaH=" (rtos deltaH 2 0) " richtung=" richtung
" winkel=" (rtos (float winkel) 2 1)
" L_GF=" (rtos L_GF 2 0) " L_VF=" (rtos L_VF 2 0) ")")))
(setq vf-einheit-res
(vfl-vf-einheit-abschluss frame hz-neu richtung winkel L_GF L_VF nil))
(setq frame (nth 0 vf-einheit-res))
@@ -2503,6 +2846,9 @@
(if (nth 3 vf-einheit-res) (setq es-seite (nth 3 vf-einheit-res)))
(setq letzter-typ "VF")
(setq p-aktuell (car frame))
(if dbg-an
(dbgmsg (strcat "GEOMETRIE ERFOLG: VF-Einheit gebaut, neue Position="
(dbg-tostring p-aktuell))))
)
)
)
@@ -2531,105 +2877,147 @@
(setq frame (nth 0 erg) deltaL (nth 1 erg) p-aktuell (car frame))
)
)
;; Segment-Typ bestimmen. Kurzsegment (deltaL < 1000 mm): KEINE
;; Hoehenabfrage - automatisch 3-Grad-Gefaellestrecke. Grund: ein VF
;; braucht >= 1000 mm deltaL (Umlenk- + Motorstation = 500+500 mm),
;; und eine GF ist mindestens 3 Grad geneigt. Die Endhoehe ergibt
;; sich damit fest aus deltaH = deltaL*tan(3 Grad).
;; Im Kettenende-Modus (Option 4) wird IMMER nach der Zielhoehe
;; gefragt (Kurzsegment-Automatik hier ueberspringen).
(if (and (< deltaL 1000.0) (not linie-ende-modus))
;; Nach dem AS-Einfuegen kann die reale Restlaenge (aus dem
;; tatsaechlichen KS_AUS neu gemessen) kleiner als der urspruenglich
;; gepickte Rohwert sein - bei einem knapp gepickten Punkt sogar
;; NEGATIV. Ohne diese zweite Pruefung wuerde die Kurzsegment-
;; Automatik unten (< 1000mm) mit negativem deltaL trotzdem ein
;; "erfolgreiches" GF-Segment bauen (entartete/unsichtbare Strecke,
;; das naechste Element - z.B. ein GF-Bogen - erscheint dann direkt
;; am AS-Element, obwohl der Nutzer davor noch eine Linie wollte).
(if (< deltaL 1.0)
(princ (ssg-text "vfl-fehler-linie-zu-kurz"))
(progn
(setq typ "GF" winkel 3.0 richtung "Ab" L_GF nil L_VF nil)
(setq deltaH (* deltaL (/ (sin (* 3.0 (/ pi 180.0)))
(cos (* 3.0 (/ pi 180.0))))))
(setq hoehe-neu (- (caddr p-aktuell) deltaH))
(princ (ssg-textf "vfl-info-kurzes-segment"
(list (rtos deltaL 2 0) (rtos deltaH 2 1))))
)
(progn
(if (vfl-wizard-aktiv)
(vl-catch-all-apply 'vflw-gruppe-ziel-hoehe-impl (list (caddr p-aktuell))))
(setq hoehe-neu
(vfl-in-real (ssg-textf "vfl-prompt-hoehe-linienendpunkt" (list (rtos (caddr p-aktuell) 2 1)))))
(if (null hoehe-neu) (setq hoehe-neu (caddr p-aktuell)))
(setq deltaH (- hoehe-neu (caddr p-aktuell)))
(setq richtung (if (>= deltaH 0.0) "Auf" "Ab"))
(setq deltaH (abs deltaH))
;; Kettenende-Modus (Option 4): Der abgefragte Endpunkt (XY+Z)
;; ist das exakte Ende der Kette NACH Separator + ES-Element.
;; Deren Footprint (Separator 300 mm bei ~3 Grad + ES-Element
;; ein-dx/ein-dz) muss vom baubaren GF/VF-Segment reserviert
;; (abgezogen) werden, damit das ES-Element genau am Zielpunkt
;; endet. Naeherung: Separator-Neigung = 3 Grad (Auslauf).
(if linie-ende-modus
;; Segment-Typ bestimmen. Kurzsegment (deltaL < 1000 mm): KEINE
;; Hoehenabfrage - automatisch 3-Grad-Gefaellestrecke. Grund: ein VF
;; braucht >= 1000 mm deltaL (Umlenk- + Motorstation = 500+500 mm),
;; und eine GF ist mindestens 3 Grad geneigt. Die Endhoehe ergibt
;; sich damit fest aus deltaH = deltaL*tan(3 Grad).
;; Im Kettenende-Modus (Option 4) wird IMMER nach der Zielhoehe
;; gefragt (Kurzsegment-Automatik hier ueberspringen).
(if (and (< deltaL 1000.0) (not linie-ende-modus))
(progn
(setq rad3 (* (float (ssg-cfg-or "vario" "gefaelle_winkel" 3))
(/ pi 180.0)))
(setq deltaL (max 1.0 (- deltaL (* 300.0 (cos rad3))
(abs (if ein-dx ein-dx 0.0)))))
(setq deltaH (max 0.0 (- deltaH (* 300.0 (sin rad3))
(abs (if ein-dz ein-dz 0.0)))))
(princ (ssg-textf "vfl-info-kettenende-footprint"
(list (rtos deltaL 2 0) (rtos deltaH 2 0))))
(setq typ "GF" winkel 3.0 richtung "Ab" L_GF nil L_VF nil)
(setq deltaH (* deltaL (/ (sin (* 3.0 (/ pi 180.0)))
(cos (* 3.0 (/ pi 180.0))))))
(setq hoehe-neu (- (caddr p-aktuell) deltaH))
(princ (ssg-textf "vfl-info-kurzes-segment"
(list (rtos deltaL 2 0) (rtos deltaH 2 1))))
)
)
(setq entscheidung (vfl-segment-entscheidung deltaL deltaH richtung))
(setq typ (nth 0 entscheidung) winkel (nth 1 entscheidung)
L_GF (nth 2 entscheidung) L_VF (nth 3 entscheidung))
)
)
(if (null typ)
(alert (ssg-textf "vfl-alert-segment-nicht-baubar"
(list (rtos deltaL 2 0) (rtos deltaH 2 0) richtung)))
(progn
(if (= typ "GF")
(progn
;; --- reine Gefaellestrecke ---
(setq frame (vfl-insert-gf-segment (car frame) hz-neu deltaL winkel))
(setq anzahl-gf (1+ anzahl-gf))
;; GF-Segment erfassen (Schraeglaenge = deltaL/cos(winkel))
(vfl-acc-gf-seg (/ deltaL (cos (* (float winkel) (/ pi 180.0)))) winkel)
(setq letzter-typ "GF")
(setq p-aktuell (car frame))
;; Kettenende-Modus (Option 4): ohne Frage direkt ES setzen.
;; Sonst nachfragen, ob die Kette hier endet.
(setq hoehe-vorschlaege (vfl-segment-hoehe-vorschlaege (caddr p-aktuell) deltaL))
(setq hoehe-ab (nth 0 hoehe-vorschlaege) hoehe-auf (nth 1 hoehe-vorschlaege))
(setq hoehe-fallback (if hoehe-ab hoehe-ab (caddr p-aktuell)))
(vfl-hoehe-hinweis-falls-noetig hoehe-ab hoehe-auf)
(if (vfl-wizard-aktiv)
(vl-catch-all-apply 'vflw-gruppe-ziel-hoehe-impl
(list (list hoehe-ab hoehe-auf (caddr p-aktuell)))))
(setq hoehe-neu
(vfl-in-real
(if (and hoehe-ab hoehe-auf)
(ssg-textf "vfl-prompt-hoehe-linienendpunkt-2"
(list (rtos hoehe-ab 2 1) (rtos hoehe-auf 2 1)))
(ssg-textf "vfl-prompt-hoehe-linienendpunkt" (list (rtos hoehe-fallback 2 1))))))
(if (null hoehe-neu) (setq hoehe-neu hoehe-fallback))
(setq deltaH (- hoehe-neu (caddr p-aktuell)))
(setq richtung (if (>= deltaH 0.0) "Auf" "Ab"))
(setq deltaH (abs deltaH))
;; Kettenende-Modus (Option 4): Der abgefragte Endpunkt (XY+Z)
;; ist das exakte Ende der Kette NACH Separator + ES-Element.
;; Deren Footprint (Separator 300 mm bei ~3 Grad + ES-Element
;; ein-dx/ein-dz) muss vom baubaren GF/VF-Segment reserviert
;; (abgezogen) werden, damit das ES-Element genau am Zielpunkt
;; endet. Naeherung: Separator-Neigung = 3 Grad (Auslauf).
(if linie-ende-modus
(setq antwort "1")
(progn
(princ (ssg-text "vfl-ist-kettenende-header"))
(princ (ssg-text "vfl-kettenende-opt-ja-es"))
(princ (ssg-text "vfl-kettenende-opt-ja-ohne-es"))
(princ (ssg-text "vfl-kettenende-opt-nein"))
(setq antwort (vfl-menu (ssg-text "vfl-prompt-wahl-1-3-def3")
(list (ssg-text "vfl-kettenende-opt-ja-es")
(ssg-text "vfl-kettenende-opt-ja-ohne-es")
(ssg-text "vfl-kettenende-opt-nein")) 3
"vfl-ist-kettenende-header"))
(setq rad3 (* (float (ssg-cfg-or "vario" "gefaelle_winkel" 3))
(/ pi 180.0)))
(setq deltaL (max 1.0 (- deltaL (* 300.0 (cos rad3))
(abs (if ein-dx ein-dx 0.0)))))
(setq deltaH (max 0.0 (- deltaH (* 300.0 (sin rad3))
(abs (if ein-dz ein-dz 0.0)))))
(princ (ssg-textf "vfl-info-kettenende-footprint"
(list (rtos deltaL 2 0) (rtos deltaH 2 0))))
)
)
(cond
((= antwort "1")
(setq es-seite (vfl-frage-es-seite))
(setq frame (vfl-insert-es-element "GF" frame hz-neu winkel
(caddr (car frame)) es-seite))
(setq fertig t))
((= antwort "2") (setq fertig t))
)
(setq entscheidung (vfl-segment-entscheidung deltaL deltaH richtung))
(setq typ (nth 0 entscheidung) winkel (nth 1 entscheidung)
L_GF (nth 2 entscheidung) L_VF (nth 3 entscheidung))
)
)
(if (null typ)
(progn
;; --- VarioFoerderer-Einheit (Umlenk..Motor, mehrsegmentig) ---
;; linie-ende-modus=T -> direkt Kettenende (Separator + ES).
(setq vf-einheit-res
(vfl-vf-einheit-abschluss frame hz-neu richtung winkel L_GF L_VF
linie-ende-modus))
(setq frame (nth 0 vf-einheit-res))
(setq anzahl-vf (+ anzahl-vf (nth 1 vf-einheit-res)))
(if (nth 2 vf-einheit-res) (setq fertig t))
(if (nth 3 vf-einheit-res) (setq es-seite (nth 3 vf-einheit-res)))
(setq letzter-typ "VF")
(setq p-aktuell (car frame))
(alert (ssg-textf "vfl-alert-segment-nicht-baubar"
(list (rtos deltaL 2 0) (rtos deltaH 2 0) richtung)))
(if dbg-an
(dbgmsg (strcat "GEOMETRIE FEHLGESCHLAGEN: Linie (automatisch) nicht baubar"
" (deltaL=" (rtos deltaL 2 0) " deltaH=" (rtos deltaH 2 0)
" richtung=" richtung ")"))))
(progn
(if (= typ "GF")
(progn
;; --- reine Gefaellestrecke ---
(if dbg-an
(dbgmsg (strcat "GEOMETRIE: vfl-insert-gf-segment (deltaL=" (rtos deltaL 2 0)
" hz=" (rtos hz-neu 2 1) " winkel=" (rtos (float winkel) 2 1) ")")))
(setq frame (vfl-insert-gf-segment (car frame) hz-neu deltaL winkel))
(setq anzahl-gf (1+ anzahl-gf))
;; GF-Segment erfassen (Schraeglaenge = deltaL/cos(winkel))
(vfl-acc-gf-seg (/ deltaL (cos (* (float winkel) (/ pi 180.0)))) winkel)
(setq letzter-typ "GF")
(setq p-aktuell (car frame))
(if dbg-an
(dbgmsg (strcat "GEOMETRIE ERFOLG: GF-Segment gebaut, neue Position="
(dbg-tostring p-aktuell))))
;; Kettenende-Modus (Option 4): ohne Frage direkt ES setzen.
;; Sonst nachfragen, ob die Kette hier endet.
(if linie-ende-modus
(setq antwort "1")
(progn
(princ (ssg-text "vfl-ist-kettenende-header"))
(princ (ssg-text "vfl-kettenende-opt-ja-es"))
(princ (ssg-text "vfl-kettenende-opt-ja-ohne-es"))
(princ (ssg-text "vfl-kettenende-opt-nein"))
(setq antwort (vfl-menu (ssg-text "vfl-prompt-wahl-1-3-def3")
(list (ssg-text "vfl-kettenende-opt-ja-es")
(ssg-text "vfl-kettenende-opt-ja-ohne-es")
(ssg-text "vfl-kettenende-opt-nein")) 3
"vfl-ist-kettenende-header"))
)
)
(cond
((= antwort "1")
(setq es-seite (vfl-frage-es-seite))
(setq frame (vfl-insert-es-element "GF" frame hz-neu winkel
(caddr (car frame)) es-seite))
(setq fertig t))
((= antwort "2") (setq fertig t))
)
)
(progn
;; --- VarioFoerderer-Einheit (Umlenk..Motor, mehrsegmentig) ---
;; linie-ende-modus=T -> direkt Kettenende (Separator + ES).
(if dbg-an
(dbgmsg (strcat "GEOMETRIE: vfl-vf-einheit-abschluss (deltaL=" (rtos deltaL 2 0)
" deltaH=" (rtos deltaH 2 0) " richtung=" richtung
" winkel=" (rtos (float winkel) 2 1)
" L_GF=" (rtos L_GF 2 0) " L_VF=" (rtos L_VF 2 0)
" linie-ende-modus=" (if linie-ende-modus "T" "nil") ")")))
(setq vf-einheit-res
(vfl-vf-einheit-abschluss frame hz-neu richtung winkel L_GF L_VF
linie-ende-modus))
(setq frame (nth 0 vf-einheit-res))
(setq anzahl-vf (+ anzahl-vf (nth 1 vf-einheit-res)))
(if (nth 2 vf-einheit-res) (setq fertig t))
(if (nth 3 vf-einheit-res) (setq es-seite (nth 3 vf-einheit-res)))
(setq letzter-typ "VF")
(setq p-aktuell (car frame))
(if dbg-an
(dbgmsg (strcat "GEOMETRIE ERFOLG: VF-Einheit gebaut, neue Position="
(dbg-tostring p-aktuell))))
)
)
)
)
)
+4
View File
@@ -28,6 +28,8 @@
"vfl-prompt-neigungswinkel": "\nNeigungswinkel (Grad, 0 < Winkel <= %1) [%1]: ",
"vfl-alert-winkel-ungueltig": "Neigungswinkel ungueltig: %1 Grad. Erlaubt: 0 < Winkel <= %2 Grad.",
"vfl-prompt-hoehe-linienendpunkt": "\nHoehe (Z) des Linienendpunkts [%1]: ",
"vfl-prompt-hoehe-linienendpunkt-2": "\nHoehe (Z) des Linienendpunkts (Ab: %1 | Auf: %2) [%1]: ",
"vfl-hinweis-hoehe-vorschlag-fehlt": "\n(Hinweis: In diese Richtung ist bei dieser Segmentlaenge kein baubarer Vorschlag gefunden - bitte Wert manuell pruefen.)",
"vfl-alert-gf-kann-nicht-steigen": "Gefaellestrecke (GF) kann nicht steigen - bitte tiefere Zielhoehe waehlen oder Ab/Auf VF benutzen.",
"vfl-alert-gefaelle-zu-steil": "Gefaelle zu steil fuer GF: %1 Grad (erlaubt max %2 Grad).\nBitte kleinere Hoehendifferenz waehlen oder Ab/Auf VF benutzen.",
"vfl-ist-kettenende-header": "\nIst das das Kettenende?",
@@ -284,7 +286,9 @@
"vfl-horizontale-zwischenstrecke": "\n\nHorizontale Zwischenstrecke (0 Grad, L=%1 mm)",
"vfl-kettenende-modus-ziel": "\n>>> Kettenende-Modus: Ziel dL=%1 mm, dH=%2 mm (%3). GF2 variiert mit dem Winkel.",
"vfl-prompt-hoehe-endpunkt": "\nHoehe (Z) des Endpunkts [%1]: ",
"vfl-prompt-hoehe-endpunkt-2": "\nHoehe (Z) des Endpunkts (Ab: %1 | Auf: %2) [%1]: ",
"vfl-prompt-hoehe-kettenende": "\nHoehe (Z) des Kettenendes (ES-Element) [%1]: ",
"vfl-prompt-hoehe-kettenende-2": "\nHoehe (Z) des Kettenendes (ES-Element) (Ab: %1 | Auf: %2) [%1]: ",
"vfl-prompt-wahl-bis-n": "\nIhre Wahl (1-%1) [1]: ",
"vfl-segment-gf-nicht-erlaubt": "\n Segment waere GF (zu steil) oder nicht baubar - innerhalb einer VF-Einheit nicht erlaubt.\n Bitte flacher/steigend zeichnen oder Foerderer beenden.",
"vfl-winkel-option": "\n %1 - %2 Grad (L_GF=%3 mm L_VF=%4 mm)",
+4
View File
@@ -28,6 +28,8 @@
"vfl-prompt-neigungswinkel": "\nIncline angle (degrees, 0 < angle <= %1) [%1]: ",
"vfl-alert-winkel-ungueltig": "Incline angle invalid: %1 degrees. Allowed: 0 < angle <= %2 degrees.",
"vfl-prompt-hoehe-linienendpunkt": "\nHeight (Z) of the line end point [%1]: ",
"vfl-prompt-hoehe-linienendpunkt-2": "\nHeight (Z) of the line end point (down: %1 | up: %2) [%1]: ",
"vfl-hinweis-hoehe-vorschlag-fehlt": "\n(Note: no buildable suggestion found for that direction at this segment length - please check the value manually.)",
"vfl-alert-gf-kann-nicht-steigen": "Gravity section (GF) cannot rise - please pick a lower target height or use down/up VF.",
"vfl-alert-gefaelle-zu-steil": "Slope too steep for GF: %1 degrees (max allowed %2 degrees).\nPlease pick a smaller height difference or use down/up VF.",
"vfl-ist-kettenende-header": "\nIs this the chain end?",
@@ -284,7 +286,9 @@
"vfl-horizontale-zwischenstrecke": "\n\nHorizontal intermediate section (0 deg, L=%1 mm)",
"vfl-kettenende-modus-ziel": "\n>>> Chain-end mode: target dL=%1 mm, dH=%2 mm (%3). GF2 varies with the angle.",
"vfl-prompt-hoehe-endpunkt": "\nHeight (Z) of the end point [%1]: ",
"vfl-prompt-hoehe-endpunkt-2": "\nHeight (Z) of the end point (down: %1 | up: %2) [%1]: ",
"vfl-prompt-hoehe-kettenende": "\nHeight (Z) of the chain end (ES element) [%1]: ",
"vfl-prompt-hoehe-kettenende-2": "\nHeight (Z) of the chain end (ES element) (down: %1 | up: %2) [%1]: ",
"vfl-prompt-wahl-bis-n": "\nYour choice (1-%1) [1]: ",
"vfl-segment-gf-nicht-erlaubt": "\n Segment would be GF (too steep) or not buildable - not allowed within a VF unit.\n Please draw flatter/rising or end the conveyor.",
"vfl-winkel-option": "\n %1 - %2 deg (L_GF=%3 mm L_VF=%4 mm)",