Merge branch 'master' of https://gitea.schoenenberger.de/Schoenenberger_Systeme_GmbH/dxfmakros
This commit is contained in:
File diff suppressed because it is too large
Load Diff
+74
-35
@@ -1004,8 +1004,7 @@
|
||||
;; hoehe = Hoehe in mm als String (wird als HOEHE-Attribut gesetzt)
|
||||
;; drehung = Drehwinkel in Grad als String (Block-Rotation)
|
||||
;; Rueckgabe: Einfuegepunkt oder nil bei Abbruch
|
||||
(defun omni:insert-dxf (sivasnr-str hoehe drehung / dxf-pfad omniflo-pfad angleDeg
|
||||
drehung-anzeige blockEnt attribs layer-name ed pt10 zval zdelta)
|
||||
(defun omni:insert-dxf (sivasnr-str hoehe drehung / dxf-pfad omniflo-pfad)
|
||||
(setq omniflo-pfad (getenv "DXFM_OMNIFLO"))
|
||||
(if (null omniflo-pfad)
|
||||
(progn
|
||||
@@ -1019,7 +1018,19 @@
|
||||
(princ (ssg-textf "omni-fehler-dxf-nicht-gefunden" (list (strcat omniflo-pfad "/" sivasnr-str ".dxf"))))
|
||||
nil
|
||||
)
|
||||
(progn
|
||||
(omni:insert-datei dxf-pfad sivasnr-str hoehe drehung)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; --- Block-Datei (DXF/DWG) interaktiv einfuegen ---
|
||||
;; dxf-pfad = vollstaendiger Pfad der Blockdatei (bereits auf Existenz geprueft)
|
||||
;; name = Anzeigename/Blockname fuer Meldung und Layer-Vorgabe
|
||||
;; hoehe, drehung wie omni:insert-dxf
|
||||
;; Rueckgabe: Einfuegepunkt oder nil bei Abbruch
|
||||
(defun omni:insert-datei (dxf-pfad name hoehe drehung / angleDeg
|
||||
drehung-anzeige blockEnt attribs layer-name ed pt10 zval zdelta)
|
||||
(ssg-start "OMNI DXF Insert" '(("ATTREQ") ("ATTDIA")))
|
||||
(setvar "ATTREQ" 0)
|
||||
(setvar "ATTDIA" 0)
|
||||
@@ -1077,7 +1088,7 @@
|
||||
|
||||
;; Layer aus der Block-Vorgabe (LAYER-Attribut) setzen
|
||||
(setq attribs (ssg-attrib-read blockEnt))
|
||||
(setq layer-name (ssg-block-layer-vorgabe blockEnt sivasnr-str attribs))
|
||||
(setq layer-name (ssg-block-layer-vorgabe blockEnt name attribs))
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1093,7 +1104,7 @@
|
||||
|
||||
(princ (ssg-textf "omni-dxf-eingefuegt"
|
||||
(list
|
||||
sivasnr-str
|
||||
name
|
||||
(if hoehe hoehe (ssg-cfg-or "omniflo" "default_hoehe" "2000"))
|
||||
drehung-anzeige
|
||||
(if layer-name (strcat " Layer=" layer-name) "")
|
||||
@@ -1101,10 +1112,6 @@
|
||||
(ssg-end)
|
||||
;; Rueckgabe: tatsaechlicher Einfuegepunkt
|
||||
(if blockEnt (cdr (assoc 10 (entget blockEnt))))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -1531,10 +1538,12 @@
|
||||
)
|
||||
|
||||
;; --- Omniflo / KettenFoerderer ---
|
||||
(defun c:OMNI_KettenFoerderer ()
|
||||
(princ "\n[DUMMY] KettenFoerderer")
|
||||
(princ)
|
||||
)
|
||||
;; Der Platzhalter c:OMNI_KettenFoerderer (reiner Dummy, gab nur "[DUMMY]
|
||||
;; KettenFoerderer" aus und war im Menue ausgegraut) wurde entfernt: der
|
||||
;; Kettenfoerderer ist seit 2026-10-22 als eigene Baugruppe umgesetzt, der
|
||||
;; Menueeintrag zeigt jetzt auf (ssg-ensure "KettenFoerderer") KETTENFOERDERER
|
||||
;; (Lisp/KettenFoerderer.lsp). Damit war der Dummy toter Code - auf ihn verwies
|
||||
;; nur noch der Menueeintrag selbst.
|
||||
|
||||
|
||||
;; --- Omniflo / Ladeschleifen ---
|
||||
@@ -1650,76 +1659,106 @@
|
||||
)
|
||||
|
||||
;; --- Omniflo / Verbinder ---
|
||||
;; Verbinder-Bloecke liegen dimensionsunabhaengig als DWG in
|
||||
;; data/omniflo/Verbinder (nicht unter DXFM_OMNIFLO = data/omniflo/<DIM>).
|
||||
;; Einfuegen wie die festen TEF-Bauteile ueber omni:insert-datei: Punkt und
|
||||
;; Drehung interaktiv, Layer aus dem LAYER-Attribut, ID per ssg-id-generate.
|
||||
;; Befehl -> DWG-Name steht direkt im jeweiligen c:OMNI_TV_*-Befehl.
|
||||
|
||||
;; Pfad der Verbinder-DWG aus Datenverzeichnis + Dateiname (ohne .dwg)
|
||||
(defun omni:verbinder-pfad (data-pfad datei)
|
||||
(strcat (vl-string-right-trim "/" (vl-string-translate "\\" "/" data-pfad))
|
||||
"/omniflo/Verbinder/" datei ".dwg")
|
||||
)
|
||||
|
||||
;; Verbinder-DWG interaktiv einfuegen. Rueckgabe: Einfuegepunkt oder nil
|
||||
(defun omni:insert-verbinder (datei / data-pfad pfad)
|
||||
(setq data-pfad (getenv "DXFM_DATA"))
|
||||
(cond
|
||||
((null data-pfad)
|
||||
(princ (ssg-text "omni-fehler-dxfm-data"))
|
||||
nil)
|
||||
((not (findfile (setq pfad (omni:verbinder-pfad data-pfad datei))))
|
||||
(princ (ssg-textf "omni-fehler-dxf-nicht-gefunden" (list pfad)))
|
||||
nil)
|
||||
(t (omni:insert-datei pfad datei nil nil))
|
||||
)
|
||||
)
|
||||
|
||||
(defun c:OMNI_TV_W_W ()
|
||||
(princ "\n[DUMMY] TV W-W kpl")
|
||||
(omni:insert-verbinder "TV_W-W_kpl")
|
||||
(princ)
|
||||
)
|
||||
(defun c:OMNI_TV_W_AP110 ()
|
||||
(princ "\n[DUMMY] TV W-AP110 kpl")
|
||||
(omni:insert-verbinder "TV_W-AP110_kpl")
|
||||
(princ)
|
||||
)
|
||||
(defun c:OMNI_TV_W_AP60 ()
|
||||
(princ "\n[DUMMY] TV W-AP60 oben kpl.")
|
||||
(omni:insert-verbinder "TV_W-AP60_oben")
|
||||
(princ)
|
||||
)
|
||||
(defun c:OMNI_TV_W_AP60_KPL ()
|
||||
(omni:insert-verbinder "TV_W-AP60_kpl")
|
||||
(princ)
|
||||
)
|
||||
(defun c:OMNI_TV_W_AP110_W ()
|
||||
(princ "\n[DUMMY] TV W-AP110-W kpl")
|
||||
(princ)
|
||||
)
|
||||
(defun c:OMNI_TV_W_AP ()
|
||||
(princ "\n[DUMMY] TV W-AP oben kpl")
|
||||
(omni:insert-verbinder "TV_W-AP110-W_kpl")
|
||||
(princ)
|
||||
)
|
||||
(defun c:OMNI_TV_80 ()
|
||||
(princ "\n[DUMMY] TV 80")
|
||||
(omni:insert-verbinder "TV_80_kpl")
|
||||
(princ)
|
||||
)
|
||||
(defun c:OMNI_TV_50 ()
|
||||
(princ "\n[DUMMY] TV 50")
|
||||
(omni:insert-verbinder "TV_50_kpl")
|
||||
(princ)
|
||||
)
|
||||
(defun c:OMNI_TV_ENDPLATTE ()
|
||||
(princ "\n[DUMMY] Endplatte Al-Profil AP schraubbar")
|
||||
(omni:insert-verbinder "VB_ENDP_AP")
|
||||
(princ)
|
||||
)
|
||||
(defun c:OMNI_TV_ANSCHLAG ()
|
||||
(princ "\n[DUMMY] Anschlag AP-Ende fuer Spulenzug")
|
||||
(omni:insert-verbinder "VB_ENDP_AP_Spulenzug")
|
||||
(princ)
|
||||
)
|
||||
(defun c:OMNI_TV_A_AP110_AP60 ()
|
||||
(princ "\n[DUMMY] TV-A fuer AP110/AP60 kpl")
|
||||
(omni:insert-verbinder "TV_AP110-AP60_kpl")
|
||||
(princ)
|
||||
)
|
||||
(defun c:OMNI_TV_A_AP60_ST ()
|
||||
(princ "\n[DUMMY] TV-A fuer AP60/ST")
|
||||
(omni:insert-verbinder "TV_AP60-ST_kpl")
|
||||
(princ)
|
||||
)
|
||||
(defun c:OMNI_TV_A_AP110_ST ()
|
||||
(princ "\n[DUMMY] TV-A fuer AP110/ST kpl")
|
||||
(omni:insert-verbinder "TV_AP110-ST_kpl")
|
||||
(princ)
|
||||
)
|
||||
(defun c:OMNI_TV_SW_II_SW_SW ()
|
||||
(princ "\n[DUMMY] TV-SW II fuer SW-SW")
|
||||
(omni:insert-verbinder "TV_SW-SW")
|
||||
(princ)
|
||||
)
|
||||
(defun c:OMNI_TV_SW_III_AP110_SW ()
|
||||
(princ "\n[DUMMY] TV-SW III fuer SW-AP110-SW")
|
||||
(omni:insert-verbinder "TV_SW-AP110-SW")
|
||||
(princ)
|
||||
)
|
||||
(defun c:OMNI_TV_SW_III_AP110 ()
|
||||
(princ "\n[DUMMY] TV-SW III fuer SW-AP110")
|
||||
(defun c:OMNI_TV_W_AP60_KPL ()
|
||||
(omni:insert-verbinder "TV_W-AP60_kpl")
|
||||
(princ)
|
||||
)
|
||||
(defun c:OMNI_TV_SW_I_AP110 ()
|
||||
(omni:insert-verbinder "TV_SW_I_SW-AP110")
|
||||
(princ)
|
||||
)
|
||||
(defun c:OMNI_TV_SW_IV_AP60 ()
|
||||
(princ "\n[DUMMY] TV-SW IV fuer Anschluss SW-AP60")
|
||||
(omni:insert-verbinder "TV_SW_IV_SW-AP60")
|
||||
(princ)
|
||||
)
|
||||
(defun c:OMNI_TV_SW_IV_ST ()
|
||||
(princ "\n[DUMMY] TV-SW IV fuer SW-ST")
|
||||
(omni:insert-verbinder "TV_SW_IV_SW-ST")
|
||||
(princ)
|
||||
)
|
||||
(defun c:OMNI_TV_MUFFE ()
|
||||
(princ "\n[DUMMY] Muffe")
|
||||
(omni:insert-verbinder "VB_Muffe")
|
||||
(princ)
|
||||
)
|
||||
|
||||
|
||||
+90
-34
@@ -38,22 +38,22 @@ am Label-Anfang, bei Submenue-Schliessern hinter dem `<-` (`[<-~Label]`).
|
||||
|
||||
| Menuebereich | Eintraege | Definiert in |
|
||||
| --- | --- | --- |
|
||||
| Omniflo ▸ Anbaugruppen | `OMNI_KettenFoerderer` | `OmniModulInsert.lsp` |
|
||||
| Omniflo ▸ Verbinder | alle `OMNI_TV_*` (18) | `OmniModulInsert.lsp` |
|
||||
| Omniflo ▸ Boegen fuer Weichen | alle `OMNI_APBW_*` (14) | `OmniModulInsert.lsp` |
|
||||
| ILS ▸ Zusatzmodule/Kurven | `ILS_ETF_Etagenfoerderer`, `ILS_K{90,60,30}{L,R}{A,I}` (12), `ILS_Gefaellestrecke` | `SSG_LIB_Commands.lsp` |
|
||||
| Geruest | `GERUEST` (Gattertraeger-Platzhalter, derselbe Befehl wie Saeulen/Rohrabhaenger/Wandbefestigung) | `GeruestInsert.lsp` |
|
||||
|
||||
`OMNI_TEF_*` (UmlenkR/L, AntriebL/R, TEF Gerade) sind entgegen frueherem Stand
|
||||
**implementiert** (echtes `omni:insert-dxf`), nur `OMNI_KettenFoerderer` ist
|
||||
weiterhin Dummy.
|
||||
**implementiert** (echtes `omni:insert-dxf`). Der Menueeintrag KettenFoerderer ist
|
||||
ebenfalls aktiv (Modul `KettenFoerderer.lsp`, Beschreibung in `CLAUDE.md`).
|
||||
|
||||
Aktiv (implementiert) sind u.a.: Kreisel, Eckrad, VarioFoerderer (Standard/Etage/
|
||||
Linienzug), Gefaellestrecke, Geruest (Saeulen/Rohrabhaenger/Wandbefestigung/
|
||||
Rohr-Geruest-Traeger), TRO-Marker, Connections, BTMT Be-/Entladung, Scanner/
|
||||
Separator, Omniflo Boegen (APB)/TEF-Elemente/Aluprofil-Geraden (AP)/alle Weichen
|
||||
(W90/W45/WP/WK/WKomb)/Ladeschleifen, Export (Sivas/CSV), Werkzeuge (Block-/
|
||||
Text-Tools, Planquadrate) und die Tests.
|
||||
(W90/W45/WP/WK/WKomb)/Ladeschleifen/Schwenkschienen/Fahrstrecke, Kettenfoerderer,
|
||||
Export (Sivas/CSV), Werkzeuge (Block-/Text-Tools, Faehnchen + Stueckliste,
|
||||
DIN-Formate, Planquadrate) und die Tests. Die frueheren Dummy-Befehle fuer ILS-Kurven
|
||||
(`ILS_K*`), Etagenfoerderer (`ILS_ETF_*`) und `ILS_Gefaellestrecke` wurden samt
|
||||
Menueeintraegen entfernt.
|
||||
|
||||
---
|
||||
|
||||
@@ -384,6 +384,10 @@ Gefaellestrecke/`vf_core` geladen sein; Kern-Modul.
|
||||
| `extract-ks-from-block[-raw] name` | KS_EIN/KS_AUS-Punkte eines Blocks ermitteln (Cache `*ks-cache*`) |
|
||||
| `insert-block-by-ks name ks-nr pt` | Block anhand KS-Punkt einfuegen (nur Rz-Rotation) |
|
||||
| `insert-inclined-scaled-block` / `insert-rotated-block-with-ks` | Geneigten/rotierten Block mit KS-Offset einfuegen (Rz*Ry) |
|
||||
| `ks-xy-winkel ks-eintrag` | Richtung der X-Achse eines KS in der XY-Ebene (Grad); `nil` bei senkrechter Achse |
|
||||
| `ks-block-messen name` / `ks-versatz ks-data` | KS eines Blocks messen, ohne bleibende Einfuegung / Versatz KS_AUS-KS_EIN |
|
||||
| `insert-block-ks-skaliert name pt hz skala` | Wie `insert-block-by-ks`, zusaetzlich in X skaliert |
|
||||
| `insert-block-ks-matrix name pt R skala` | Einfuegen mit **freier 3x3-Rotationsmatrix** (`ks-rot-x/-y/-z`), z.B. fuer aufgerichtete Baugruppen |
|
||||
|
||||
---
|
||||
|
||||
@@ -579,9 +583,9 @@ umbiegen. Falls das bereits passiert ist, hilft nur ein manuelles
|
||||
|
||||
---
|
||||
|
||||
### `tests.lsp` – Testbefehle
|
||||
### `external_call.lsp` – Python-Aufruf testen
|
||||
|
||||
Testbefehle für die Python-Integration. Export-Funktionen wurden in `export.lsp` ausgelagert.
|
||||
Testbefehl für die Python-Integration (frueher `tests.lsp`). Export-Funktionen liegen in `export.lsp`.
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
| --- | --- |
|
||||
@@ -606,7 +610,7 @@ Verzeichnisstruktur: [`../tests/README.md`](../tests/README.md)):
|
||||
|
||||
Welche JSON-Angaben pro Element-Typ nötig sind (abgeleitet aus den
|
||||
Produktions-Routinen, nicht aus den Test-Wrappern), dokumentiert
|
||||
[`../tests/testdata/object_data.md`](../tests/testdata/object_data.md) –
|
||||
[`../doc/json-input-lisp.md`](../doc/json-input-lisp.md) (Nachfolger des geloeschten `tests/testdata/object_data.md`) –
|
||||
inkl. der Unterscheidung scriptbar vs. nur-interaktiv.
|
||||
|
||||
### LISP-Unit-Tests (`test_unit.lsp`)
|
||||
@@ -702,8 +706,8 @@ AutoLISP-Implementierung fuer alle Omniflo-Komponenten: Boegen, Weichen, Verbind
|
||||
| Geraden | `OMNI_AP60`, `OMNI_AP110`, `OMNI_APG110` | Omniflo-Geradenstuecke |
|
||||
| Ladeschleifen | `OMNI_LADESCHLEIFE_AP110` | Ladeschleife aus `omniflo_ladeschleifen.json` ueber DCL-Dialog (`dcl/omniflo_ladeschleifen.dcl`) einfuegen; Daten per `ssg-json-laden` (Beschreibungen enthalten Kommas). Blockdatei `<Sivasnr>.dwg` unter `DXFM_OMNIFLO` (`omni:insert-dxf` faellt auf `.dwg` zurueck, wenn keine `.dxf` existiert). Per `OMNI_EDIT` editierbar |
|
||||
| TEF Elemente | `OMNI_TEF_UmlenkR/L`, `OMNI_TEF_AntriebL/R`, `OMNI_TEF_Gerade` | Feste TEF-Bauteile ohne Sivas-Auswahl, direkt per `omni:insert-dxf` an gewaehltem Punkt eingefuegt (Dateien unter `DXFM_OMNIFLO`) |
|
||||
| Anbaugruppen ⚠️ | `OMNI_KettenFoerderer` | **Dummy** (noch nicht implementiert, im Menue ausgegraut); `OMNI_STOPPER`/`OMNI_SCANNER`/`OMNI_BUERSTENBREMSE` sind implementiert |
|
||||
| Transferwagen ⚠️ | `OMNI_TV_*` | **Dummy** (noch nicht implementiert, im Menue ausgegraut) |
|
||||
| Anbaugruppen | `OMNI_STOPPER`, `OMNI_SCANNER`, `OMNI_BUERSTENBREMSE` | Implementiert |
|
||||
| Verbinder | `OMNI_TV_*` | Verbinder-DWG aus `data/omniflo/Verbinder` (dimensionsunabhaengig, `omni:insert-verbinder` -> `omni:insert-datei`, Punkt + Drehung interaktiv). Zuordnung Befehl -> DWG nach Dateiname, z.B. `OMNI_TV_W_AP60` -> `TV_W-AP60_oben`, `OMNI_TV_ENDPLATTE` -> `VB_ENDP_AP`, `OMNI_TV_W_AP60_KPL` -> `TV_W-AP60_kpl`, `OMNI_TV_ANSCHLAG` -> `VB_ENDP_AP_Spulenzug`, `OMNI_TV_SW_I_AP110` -> `TV_SW_I_SW-AP110`, `OMNI_TV_MUFFE` -> `VB_Muffe`. Alle 18 Eintraege aktiv |
|
||||
| Bogenweichen ⚠️ | `OMNI_APBW_*` | **Dummy** (noch nicht implementiert, im Menue ausgegraut) |
|
||||
| Bearbeiten | `OMNI_EDIT` | Omniflo-Block selektieren und Attribute bearbeiten |
|
||||
|
||||
@@ -713,13 +717,12 @@ nicht zu verwechseln mit den einzelnen `OMNI_TEF_*`-Befehlen oben.
|
||||
|
||||
---
|
||||
|
||||
### `SSG_LIB_Commands.lsp` – BTMT, Sensoren, Dummy-Befehle, Konfiguration und SSG_BLOCKEDIT
|
||||
### `SSG_LIB_Commands.lsp` – BTMT, Sensoren, Konfiguration und SSG_BLOCKEDIT
|
||||
|
||||
Sammeldatei fuer Menue-Befehle: teils Platzhalter fuer noch nicht implementierte
|
||||
Eintraege, teils bereits **echte** Funktionalitaet (BTMT Be-/Entladung, Sensoren,
|
||||
Konfiguration, Doppelklick-Dispatcher). Alle noch offenen Dummy-Menueintraege sind in
|
||||
`menu/SSG_LIB.mnu` mit `~` ausgegraut (siehe Abschnitt
|
||||
["Status: noch offene Menueintraege"](#status-noch-offene-menueintraege-im-menue-ausgegraut)).
|
||||
Sammeldatei fuer Menue-Befehle: BTMT Be-/Entladung, Sensoren, Eingang/Ausgang,
|
||||
Konfiguration und der Doppelklick-Dispatcher. Die frueheren Dummy-Befehle (ILS-Kurven,
|
||||
Etagenfoerderer) sind entfernt; noch offene Menueintraege anderer Module siehe Abschnitt
|
||||
["Status: noch offene Menueintraege"](#status-noch-offene-menueintraege-im-menue-ausgegraut).
|
||||
|
||||
**Sensoren einfuegen** (real, ueber `ils-insert-sensor` → wiederholtes `_.INSERT`
|
||||
mit interaktivem Einfuegepunkt/Rotation, Blockdatei via `ssg-ils-block-datei`):
|
||||
@@ -761,15 +764,6 @@ Sivas-Export zusaetzlich in den Summenzaehlern "Anzahl aller BTBeladung"/
|
||||
dieselbe `ils-insert-station`-Routine wie BTMT Be-/Entladung (frei platzierbar,
|
||||
Blöcke `Eingang_<DIM>.dwg`/`Ausgang_<DIM>.dwg` in `data/ils`).
|
||||
|
||||
Registrierte Dummy-Befehle:
|
||||
|
||||
| Gruppe | Befehle |
|
||||
| --- | --- |
|
||||
| ILS Zusatzmodule | `ILS_ETF_Etagenfoerderer`|
|
||||
| ILS Kurven angetrieben Aussen | `ILS_K90LA`, `ILS_K90RA`, `ILS_K60LA`, `ILS_K60RA`, `ILS_K30LA`, `ILS_K30RA` |
|
||||
| ILS Kurven angetrieben Innen | `ILS_K90LI`, `ILS_K90RI`, `ILS_K60LI`, `ILS_K60RI`, `ILS_K30LI`, `ILS_K30RI` |
|
||||
| ILS Gefaellestrecken-Kurven | `ILS_Gefaellestrecke` |
|
||||
|
||||
> `FOERDERANLAGE` ist nicht hier definiert – dieser Befehl ist in `VarioFoerderer.lsp` implementiert.
|
||||
|
||||
**Konfigurationsbefehle** (Menue → Konfiguration):
|
||||
@@ -777,11 +771,12 @@ Registrierte Dummy-Befehle:
|
||||
| Befehl | Beschreibung |
|
||||
| --- | --- |
|
||||
| `SSG_DIM_SWITCH` | Schaltet zwischen 2D/3D-Bloecken um (setzt `DXFM_DIM`, `DXFM_BLOCKS`, `DXFM_OMNIFLO`) |
|
||||
| `SSG_DIM_ALL_2D` / `SSG_DIM_ALL_3D` | Alle VF_n-/GF_n-Bloecke der Zeichnung nach 2D bzw. 3D umbauen |
|
||||
| `SSG_SPRACHE` | Oeffnet Dialog `sprache.dcl`, setzt `*ssg-lang*` und persistiert via `DXFM_LANG` (siehe [`ssg_lang.lsp`](#ssg_langlsp--sprachumschaltung-deutschenglisch)) |
|
||||
|
||||
**SSG_BLOCKEDIT** – Doppelklick/Kontextmenue-Dispatcher:
|
||||
|
||||
Erkennt den Blocktyp des selektierten INSERT-Blocks und ruft den passenden Bearbeitungsbefehl auf (Reihenfolge wichtig: `GR_*` **vor** dem Omniflo-Zweig, da Geruest-Bloecke ebenfalls ein TEILEART-Attribut tragen):
|
||||
Erkennt den Blocktyp des selektierten INSERT-Blocks und ruft den passenden Bearbeitungsbefehl auf (Reihenfolge wichtig: `GR_*` und `KF_*` **vor** dem Omniflo-Zweig, da diese Bloecke ebenfalls ein TEILEART-Attribut tragen koennen):
|
||||
|
||||
| Blockmuster | Aktion |
|
||||
| --- | --- |
|
||||
@@ -789,8 +784,11 @@ Erkennt den Blocktyp des selektierten INSERT-Blocks und ruft den passenden Bearb
|
||||
| `ECKRAD_*` | `EckradEdit` |
|
||||
| `GF_*` | `GEFAELLESTRECKE_EDIT` |
|
||||
| `VF_*` | `VARIOFOERDERER_EDIT` |
|
||||
| `GR_*` | Geruest – `BEDIT` (kein eigener Edit-Pfad; siehe `GeruestInsert.lsp`) |
|
||||
| `CONNECTION_*` | `CONNECTION_EDIT` |
|
||||
| `JAM_*` | `JAM_EDIT` |
|
||||
| `TRO_*` | `TRO_EDIT` |
|
||||
| `GR_*` | Geruest – nativer Attribut-Editor `_.EATTEDIT` (kein eigener Edit-Pfad; siehe `GeruestInsert.lsp`) |
|
||||
| `KF_*` | `KF_EDIT` |
|
||||
| Omniflo (TEILEART-Attribut, AP110*, numerisch) | `OMNI_EDIT` |
|
||||
| Sonstige | `BEDIT` (Block-Editor) |
|
||||
|
||||
@@ -801,18 +799,20 @@ Erkennt den Blocktyp des selektierten INSERT-Blocks und ruft den passenden Bearb
|
||||
Rohr-Geruest-Baugruppen (Saeulen, Rohrabhaenger, Wandbefestigung, Rohr-Geruest-Traeger)
|
||||
aus [`data/json/geruest.json`](../data/json/geruest.json) bzw.
|
||||
[`data/json/geruest_traeger.json`](../data/json/geruest_traeger.json) konfigurieren
|
||||
und einfuegen. Die Dialogdefinition wird **zur Laufzeit erzeugt**
|
||||
(`geruest-dcl-schreiben`, temporaere DCL-Datei) – es gibt keine feste
|
||||
`dcl/geruest.dcl`, weil je Anbauteil ein eigenes Mengenfeld gebraucht wird.
|
||||
und einfuegen. Das Dialog-Layout steht als **Vorlage** in `dcl/geruest.dcl` bzw.
|
||||
`dcl/geruest_traeger.dcl`; nur die datenabhaengigen Bloecke (Varianten-Radiobuttons,
|
||||
Mengenfeld je Anbauteil) werden zur Laufzeit an Markerzeilen `//@NAME@` eingesetzt
|
||||
(`ssg-dcl-vorlage-fuellen`, temporaere DCL-Datei).
|
||||
Ausfuehrliche Beschreibung (Konfigurationen, Attribut-Schema, Querstreben/Muffe,
|
||||
Traeger-Beschriftung): siehe `../CLAUDE.md` Abschnitt "AutoLISP-Module".
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
| --- | --- |
|
||||
| `c:GERUEST` | Dialog ohne Vorgabe-Bereich (Dropdown Rohrabhaenger/Saeulen/Wandbefestigung) |
|
||||
| `c:GERUEST_SAEULEN` / `c:GERUEST_ROHRABHAENGER` / `c:GERUEST_WANDBEFESTIGUNG` | Dialog mit vorgewaehltem Bereich (derselbe Dialog wie `GERUEST`) |
|
||||
| `c:GERUEST_SAEULEN` / `c:GERUEST_ROHRABHAENGER` / `c:GERUEST_WANDBEFESTIGUNG` | Je eigener Dialog fuer den Bereich (keine Umschaltung im Dialog) |
|
||||
| `c:GERUEST` | Ohne Bereich nur ein Hinweis (im Menue Platzhalter fuer den Gattertraeger) |
|
||||
| `c:GERUEST_TRAEGER` | Eigener fester Dialog (`dcl/geruest_traeger.dcl`): Rohr-Geruest-Traeger mit Linien-Logik (Start-/Endpunkt oder Laenge, Laengenabzuege, Querstreben/Muffe-Verteilung) |
|
||||
| `c:GERUEST_TRAEGER_BESCHRIFTEN` | Alle Traeger der Zeichnung neu beschriften (eigenes TEXT-Objekt, verknuepft per XDATA `SSG_GR_BESCHR`) |
|
||||
| `c:OMNI_FAHRSTRECKE` / `c:OMNI_FAHRSTRECKE_BESCHRIFTEN` | Omniflo-Fahrstrecke mit derselben Linien-Logik (Daten `omniflo_fahrstrecke.json`, Vorlage `dcl/fahrstrecke.dcl`) bzw. Neubeschriftung |
|
||||
|
||||
Block-Praefix `GR_<id>_<timestamp>` – **nicht kosmetisch**: `SSG_BLOCKEDIT` muss
|
||||
`GR_*` vor dem Omniflo-Zweig abfangen, da Geruest-Bloecke ebenfalls ein
|
||||
@@ -864,3 +864,59 @@ Einfuegepunkt oder den Zeichnungs-Extents. Lazy geladen ueber
|
||||
|
||||
Das fertige Raster (Linien + Zaehl-Texte) wird zu einem einzigen Block
|
||||
`ZZ_PLANQUADRATE` bei (0,0,0) zusammengefasst; Layer aus `cfg/layer.cfg`.
|
||||
|
||||
---
|
||||
|
||||
### `Jam_Edit.lsp` – Staubereiche (SPS)
|
||||
|
||||
Staubereiche zeichnet sps_skel (`tro_annotate.py --anlage`) als Block `JAM_AREA`
|
||||
(Name `Jam<NNNN>_<k>`).
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
| --- | --- |
|
||||
| `c:JAM_EDIT` | Foerderer und laufende Nummer per Dialog (`dcl/jam_edit.dcl`) aendern; Knopf zurueck auf den abgeleiteten Wert, Warnung bei doppeltem Namen. Auch per Doppelklick (`SSG_BLOCKEDIT`, `JAM_*`) |
|
||||
|
||||
---
|
||||
|
||||
### `KettenFoerderer.lsp` – Kettenfoerderer/Schraegfoerderer Stahl
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
| --- | --- |
|
||||
| `c:KETTENFOERDERER` | Baut aus `KF_UM_<winkel>` -> `KF_LAENGE` -> `KF_AN_<winkel>` plus Draufsicht `KF_2D` einen Block `KF_<n>` (Dialog `dcl/kettenfoerderer.dcl`, Daten `data/json/kettenfoerderer.json`) |
|
||||
| `c:KF_EDIT` | `KF_n` bearbeiten und an derselben Stelle neu aufbauen (auch per Doppelklick) |
|
||||
| `c:KF_KS_PRUEFEN` | Diagnose (nicht im Menue) |
|
||||
|
||||
Details (aufgerichtete Geometrie, Attribut-Schema, Sivas-Export): `../CLAUDE.md`.
|
||||
|
||||
---
|
||||
|
||||
### Werkzeuge: `ssg_stueckliste.lsp`, `DinFormate.lsp`
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
| --- | --- |
|
||||
| `c:SSG_FAEHNCHEN_STUECKLISTE` | Positions-Faehnchen je Element und grob gruppierte Stuecklistentabelle, komplett aus der Zeichnung (kein Datei-Import) |
|
||||
| `c:DIN_FORMATE` | DIN-Rahmen A0-A4 und optional Schriftkopf (KOPF11, DE/EN/FR/IT) aus `cfg/rahmen/` einfuegen (Dialog `dcl/dinformate.dcl`) |
|
||||
|
||||
---
|
||||
|
||||
### Export-Hilfen: `count_sep_scan.lsp`, `check_hoehen.lsp`
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
| --- | --- |
|
||||
| `c:ZAEHLE_SEP_SCAN` | Scanner/Separatoren je Kreisel/VF/GF zaehlen und in `ANZAHL_SCANNER`/`ANZAHL_SEPARATOR` schreiben (laeuft auch vor jedem Export) |
|
||||
| `c:HOEHEN_CHECK` | Hoehen von Kreiseln/VF/GF messen, auf 0/negativ pruefen und in die Hoehen-Attribute schreiben |
|
||||
|
||||
---
|
||||
|
||||
### Entwickler-/Pflege-Module
|
||||
|
||||
| Datei | Befehle | Zweck |
|
||||
| --- | --- | --- |
|
||||
| `addattribute.lsp` | `ILS_ATTR_SYNC`, `ILS_ATTR_REPLACE` | ATTDEFs der Block-DWGs mit `data/ils/allocations.json` abgleichen |
|
||||
| `collect_attributes.lsp` | `ILS_ATTR_COLLECT` | ATTDEF-Werte aller DWGs nach `allocations_collected.json` schreiben |
|
||||
| `list_blocks.lsp` | `ILS_BLOCK_LIST` | Sub-Block-Definitionen aller DWGs auflisten (Kollisionen 2D/3D) |
|
||||
| `purge_blocks.lsp` | `ILS_BLOCK_PURGE` | Unbenutzte Bloecke/Layer in allen DWGs entfernen |
|
||||
| `ks_pruefung.lsp` | `KS_PRUEFEN` | KS_EIN/KS_AUS der 2D- gegen die 3D-Variante vergleichen (CSV) |
|
||||
| `menu-inventory.lsp` | `MenuInventory` | BricsCAD-Menuegruppen, Plugins, Startdateien auflisten |
|
||||
| `EtageVarioFoerderer.lsp` | - | Kompatibilitaets-Wrapper, laedt `vf_core.lsp` |
|
||||
| `tro_types.lsp` | - | Von `tro_annotate.py --emit-lisp` erzeugte TRO-Typliste |
|
||||
|
||||
@@ -425,6 +425,24 @@
|
||||
(command "_.EATTEDIT")
|
||||
)
|
||||
|
||||
;; Kettenfoerderer (KF_n, KettenFoerderer.lsp) -> KF_EDIT (DCL-Dialog mit
|
||||
;; Neuaufbau an derselben Stelle). MUSS - aus demselben Grund wie GR_* -
|
||||
;; vor dem Omniflo-Zweig stehen: traegt die Baugruppe ein TEILEART-
|
||||
;; Attribut, wuerde dort sonst der Omniflo-Elementdialog aufgehen.
|
||||
((wcmatch bname "KF_*")
|
||||
(princ (ssg-textf "cmd-kettenfoerderer-bearbeiten" (list bname)))
|
||||
(if (and (null *ssg-KettenFoerderer-loaded*) (atoms-family 1 '("SSG-ENSURE")))
|
||||
(ssg-ensure "KettenFoerderer")
|
||||
)
|
||||
(if (atoms-family 1 '("C:KF_EDIT"))
|
||||
(c:KF_EDIT)
|
||||
(progn
|
||||
(princ (ssg-textf "tro-edit-modul-fehlt" (list "KettenFoerderer.lsp")))
|
||||
(command "_.EATTEDIT")
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; Omniflo-Bloecke -> OMNI_EDIT
|
||||
;; Erkennung: TEILEART-Attribut vorhanden, AP110-Blockname oder rein numerisch
|
||||
((progn
|
||||
|
||||
@@ -2394,6 +2394,14 @@
|
||||
;; GeruestInsert.lsp). Wie BTMT eigenstaendig und von keinem anderen
|
||||
;; Element mitgezaehlt - export_csv.py UND export_sivas.py fuehren sie
|
||||
;; beide als eigene TeileArt-Zeilen.
|
||||
;; VB_*/TV_* = Omniflo-Verbinder (siehe pattern_verbinder in
|
||||
;; cfg/export.cfg, OMNI_TV_* in OmniModulInsert.lsp). export_sivas.py
|
||||
;; fuehrt sie ueber TEILEART/ARTINR im allgemeinen Omniflo-Zweig.
|
||||
;; KF_* = Kettenfoerderer/Schraegfoerderer Stahl (siehe
|
||||
;; pattern_kettenfoerderer in cfg/export.cfg, KettenFoerderer.lsp). Wie
|
||||
;; GR_* eine selbst zusammengebaute Baugruppe mit eigenen Attributen
|
||||
;; (TEILEART/ARTINR), darum eigenstaendig gesammelt - die drei Bausteine
|
||||
;; darin werden NICHT einzeln gezaehlt.
|
||||
;; Bloecke auf GEFRORENEN Layern (und die Hilfsobjekte gefrorener VF_n/GF_n)
|
||||
;; werden ausgelassen, solange *csv-gefrorene-ausschliessen* an ist (Standard,
|
||||
;; Dialog CSV_EXPORT_KONFIG); ausgeschaltete Layer zaehlen nicht als gefroren.
|
||||
@@ -2445,6 +2453,8 @@
|
||||
(wcmatch bname (export:pattern "pattern_eingang" "Eingang*"))
|
||||
(wcmatch bname (export:pattern "pattern_ausgang" "Ausgang*"))
|
||||
(wcmatch bname (export:pattern "pattern_geruest" "GR_*"))
|
||||
(wcmatch bname (export:pattern "pattern_verbinder" "VB_*,TV_*"))
|
||||
(wcmatch bname (export:pattern "pattern_kettenfoerderer" "KF_*"))
|
||||
(wcmatch bname (export:pattern "pattern_unit_marker" "ZZ_UNIT_MARKER*"))
|
||||
;; Rein numerische Namen = Omniflo SivasNr (Boegen/Weichen)
|
||||
;; Rein LISP-intern (Python klassifiziert Omniflo stattdessen
|
||||
|
||||
@@ -1264,6 +1264,13 @@
|
||||
("L_VF_m" "0.000")
|
||||
("ANTRIEBFAHRTRICHTUNG" "Auf")
|
||||
("VF_WINKEL" "0")
|
||||
;; Hoehe je VF-SEGMENT in Metern (3 Nachkommastellen), kommagetrennt und
|
||||
;; Eintrag fuer Eintrag parallel zu L_VF_m/VF_WINKEL: Mittelwert aus KS_EIN
|
||||
;; und KS_AUS des jeweiligen geraden VF-Abschnitts (vf-vfhoehe-segment in
|
||||
;; vf_core.lsp, erfasst in vfs-vf-koerper). Zwischen Umlenk- und
|
||||
;; Motorstation koennen mehrere Abschnitte liegen (auf/ab/horizontal).
|
||||
;; Sivas-Merkmale 4433-4437 (bis zu fuenf Abschnitte je Gruppe).
|
||||
("VF_HOEHE_m" "0.000")
|
||||
("VF_Bogen_A_90" "0")
|
||||
("VF_Bogen_A_60" "0")
|
||||
("VF_Bogen_A_30" "0")
|
||||
|
||||
+5
-1
@@ -86,8 +86,12 @@
|
||||
;; Einheiten-Proxies selbst ab; Separator-/Element-
|
||||
;; Kopien sammeln sich dagegen an - Zeichnung mit
|
||||
;; eingeschaltetem Schalter nicht speichern.
|
||||
;; kf-zeit - Zwischenzeiten beim Aufruf von KETTENFOERDERER
|
||||
;; (Daten lesen / Dialogaufbau), siehe kf-zeit in
|
||||
;; KettenFoerderer.lsp. Standard 0 - nur einschalten,
|
||||
;; wenn der Dialog spuerbar verzoegert erscheint.
|
||||
;; ------------------------------------------------------------
|
||||
(foreach nm '(("vf-sepliste" . 1) ("csv_leave_proxies" . 0))
|
||||
(foreach nm '(("vf-sepliste" . 1) ("csv_leave_proxies" . 0) ("kf-zeit" . 0))
|
||||
(if (not (assoc (car nm) *dbg-schalter*))
|
||||
(setq *dbg-schalter* (cons nm *dbg-schalter*))))
|
||||
|
||||
|
||||
@@ -45,6 +45,11 @@
|
||||
;; Spalte (auch auf Kreiseln) bekommen.
|
||||
;; GR_* (Geruest-Baugruppen, siehe pattern_geruest in cfg/export.cfg) ebenso -
|
||||
;; das ID-ATTDEF steht seit *geruest-attrib-defs* zur Verfuegung.
|
||||
;; VB_*/TV_* (Omniflo-Verbinder, siehe pattern_verbinder in
|
||||
;; cfg/export.cfg) ebenso - fest im Code wie GR_*.
|
||||
;; KF_* (Kettenfoerderer, siehe pattern_kettenfoerderer in cfg/export.cfg,
|
||||
;; KettenFoerderer.lsp) ebenso - das ID-ATTDEF kommt aus kf-attrib-defs, das
|
||||
;; auf dem gemeinsamen Strecken-Schema aufsetzt und darum ID bereits fuehrt.
|
||||
;; Gefaellebogen_* (siehe pattern_nested_bogen in cfg/export.cfg): einer der
|
||||
;; Bausteine einer GF-Kette, verpackt in VF_n/GF_n; wird beim Export ebenso
|
||||
;; als temporaere Kopie ausgepackt wie die uebrigen Vario_*/Staustrecke_*-
|
||||
@@ -81,6 +86,8 @@
|
||||
(wcmatch bname "BTMT-Beladung*,SC_Entladung*")
|
||||
(wcmatch bname "Eingang*,Ausgang*")
|
||||
(wcmatch bname "GR_*")
|
||||
(wcmatch bname "VB_*,TV_*")
|
||||
(wcmatch bname "KF_*")
|
||||
(wcmatch bname "#*")
|
||||
)
|
||||
(ssadd ename ss-out)
|
||||
|
||||
+281
-2
@@ -72,11 +72,31 @@
|
||||
;; Block unter seinem effektiven, dim-suffigierten Namen und GIBT DIESEN ZURUECK,
|
||||
;; damit Aufrufer ihn zum Einfuegen (vla-InsertBlock/tblsearch) verwenden.
|
||||
;; Meldung nur bei Fehlschlag.
|
||||
(defun ensure-block-loaded (blockname / )
|
||||
;; Sonderfall Bloecke OHNE Dimensionssuffix (data/omniflo/<Dim>/, z.B. die
|
||||
;; Kettenfoerderer-Bausteine): ssg-ils-blockname wuerde "KF_UM_26" zu
|
||||
;; "KF_UM_26_2D" machen - das ist die Konvention der FLACHEN Ablage data/ils,
|
||||
;; die Omniflo-Ordner arbeiten stattdessen mit getrennten Verzeichnissen und
|
||||
;; unsuffigierten Namen. Liegt die Definition unter dem Rohnamen bereits in
|
||||
;; der Zeichnung und gibt es KEINE suffigierte Variante, wird der Rohname
|
||||
;; unveraendert verwendet. Die Bedingung ist bewusst eng gefasst (BEIDE Teile
|
||||
;; muessen zutreffen), damit die Dim-Aufloesung fuer alle data/ils-Bloecke
|
||||
;; unberuehrt bleibt: dort existiert die suffigierte Variante, sobald der
|
||||
;; Block geladen ist, und der erste Zweig greift nie.
|
||||
;; Realer Fehler, den das behebt: die KS-Messung eines KF-Bausteins lief ins
|
||||
;; Leere und meldete "KS_EIN/KS_AUS fehlt", obwohl beide KS im Block vorhanden
|
||||
;; waren - gesucht wurde nur ein Blockname, den es nicht gibt.
|
||||
(defun ensure-block-loaded (blockname / eff)
|
||||
(setq eff (ssg-ils-blockname blockname))
|
||||
(if (and (not (tblsearch "BLOCK" eff))
|
||||
(tblsearch "BLOCK" blockname))
|
||||
blockname
|
||||
(progn
|
||||
(if (not (ssg-ils-block-laden blockname))
|
||||
(princ (ssg-textf "vfc-fehler-block-datei-fehlt" (list blockname)))
|
||||
)
|
||||
(ssg-ils-blockname blockname)
|
||||
eff
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
@@ -379,6 +399,265 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; KS-ORIENTIERUNG + SKALIERTE KS-EINFUEGUNG
|
||||
;; ------------------------------------------------------------
|
||||
;; Ergaenzt fuer den Kettenfoerderer (KettenFoerderer.lsp): dort ist die
|
||||
;; Neigung KEIN freier Parameter, sondern steckt fest in der Geometrie der
|
||||
;; Blockvarianten (KF_UM_26 gegen KF_UM_30). Der Einbauwinkel eines
|
||||
;; Folgebausteins ergibt sich darum aus der RICHTUNG des KS_AUS seines
|
||||
;; Vorgaengers. Dafuer reicht der bisher allein ausgewertete KS-URSPRUNG
|
||||
;; nicht - die X-Achse des KS muss mit gelesen werden. extract-ks-from-block
|
||||
;; liefert sie als (origin x-end y-end z-end) bereits mit, sie wurde bislang
|
||||
;; nur von keinem Aufrufer genutzt.
|
||||
|
||||
;; Winkel der X-Achse eines KS-Eintrags in der XY-Ebene, in Grad (-180..180).
|
||||
;; ks-eintrag = (origin x-end y-end z-end), also genau der cadr-Teil eines
|
||||
;; extract-ks-from-block-Ergebnisses. Rueckgabe nil, wenn die X-Achse keine
|
||||
;; XY-Laenge hat (senkrecht stehendes KS) oder der Eintrag unbrauchbar ist.
|
||||
(defun ks-xy-winkel (ks-eintrag / org xend dx dy)
|
||||
(if (and ks-eintrag (listp ks-eintrag) (>= (length ks-eintrag) 2)
|
||||
(listp (car ks-eintrag)) (listp (cadr ks-eintrag)))
|
||||
(progn
|
||||
(setq org (car ks-eintrag) xend (cadr ks-eintrag))
|
||||
(setq dx (- (car xend) (car org))
|
||||
dy (- (cadr xend) (cadr org)))
|
||||
(if (< (+ (* dx dx) (* dy dy)) 1e-12)
|
||||
nil
|
||||
(/ (* 180.0 (atan dy dx)) pi)))
|
||||
nil))
|
||||
|
||||
;; Winkel auf -180..180 Grad normalisieren. Reiner Rechenkern.
|
||||
(defun ks-winkel-normalisieren (w)
|
||||
(if (null w)
|
||||
nil
|
||||
(progn
|
||||
(setq w (float w))
|
||||
(while (> w 180.0) (setq w (- w 360.0)))
|
||||
(while (<= w -180.0) (setq w (+ w 360.0)))
|
||||
w)))
|
||||
|
||||
;; Lokalen KS_AUS-KS_EIN-Versatz eines Blocks als (dx dy dz) liefern.
|
||||
;; ks-data = Ergebnis von extract-ks-from-block/ks-block-messen.
|
||||
;; Rueckgabe nil, wenn eines der beiden KS fehlt.
|
||||
(defun ks-versatz (ks-data / ein aus)
|
||||
(setq ein (cadr (assoc "KS_EIN" ks-data))
|
||||
aus (cadr (assoc "KS_AUS" ks-data)))
|
||||
(if (and ein aus)
|
||||
(list (- (car (car aus)) (car (car ein)))
|
||||
(- (cadr (car aus)) (cadr (car ein)))
|
||||
(- (caddr (car aus)) (caddr (car ein))))
|
||||
nil))
|
||||
|
||||
;; Misst KS_EIN/KS_AUS eines Blocks, ohne eine bleibende Einfuegung zu
|
||||
;; hinterlassen: der Block wird bei Massstab 1 am Ursprung eingefuegt,
|
||||
;; vermessen und wieder geloescht. extract-ks-from-block cached das Ergebnis
|
||||
;; je Blockname, der zweite Aufruf kostet also nichts mehr.
|
||||
;; Rueckgabe wie extract-ks-from-block (Blockkoordinaten), sonst nil.
|
||||
(defun ks-block-messen (blockname / eff temp-obj daten)
|
||||
(setq eff (ensure-block-loaded blockname))
|
||||
(if (tblsearch "BLOCK" eff)
|
||||
(progn
|
||||
(setq temp-obj (vla-InsertBlock modelspace
|
||||
(vlax-3D-point '(0 0 0)) eff 1.0 1.0 1.0 0))
|
||||
(setq daten (extract-ks-from-block temp-obj))
|
||||
(if (not (vlax-erased-p temp-obj)) (vla-Delete temp-obj))
|
||||
daten)
|
||||
nil))
|
||||
|
||||
;; --- Block per KS_EIN/KS_AUS einfuegen, in X SKALIERT (nur Rz-Rotation) ---
|
||||
;; Wie insert-block-by-ks, zusaetzlich mit X-Massstab skala - fuer laengen-
|
||||
;; variable Zwischenstuecke (Kettenfoerderer KF_LAENGE, dieselbe Rolle wie
|
||||
;; die Staustrecke beim VarioFoerderer). Die lokalen KS-Punkte werden VOR der
|
||||
;; Rotation in X mitskaliert; nur so liegt KS_EIN exakt auf einfuegepunkt und
|
||||
;; der zurueckgegebene KS_AUS traegt den skalierten Versatz.
|
||||
;; Rueckgabe: Weltpunkt von KS_AUS (fuer die Verkettung), sonst einfuegepunkt.
|
||||
(defun insert-block-ks-skaliert (blockname einfuegepunkt hz skala /
|
||||
block-obj ks-data ks-ein ks-aus rad-h chv shv
|
||||
ein-x ein-y ein-z aus-x dx-loc dy-loc dz-loc
|
||||
offset ausgang)
|
||||
(if (or (null einfuegepunkt) (not (listp einfuegepunkt)))
|
||||
(progn
|
||||
(princ (ssg-textf "vfc-fehler-ungueltiger-einfuegepunkt" (list blockname)))
|
||||
(exit))
|
||||
)
|
||||
(if (or (null skala) (<= skala 0.0)) (setq skala 1.0))
|
||||
(setq blockname (ensure-block-loaded blockname))
|
||||
(if (not (tblsearch "BLOCK" blockname))
|
||||
(progn
|
||||
(princ (ssg-textf "vfc-fehler-block-nicht-in-bibliothek-abgebrochen" (list blockname)))
|
||||
(exit))
|
||||
)
|
||||
(princ (ssg-textf "vfc-fuege-block-ein-hz" (list blockname (rtos (float hz) 2 1) (chr 176))))
|
||||
(setq rad-h (* (float hz) (/ pi 180.0)))
|
||||
(setq chv (cos rad-h) shv (sin rad-h))
|
||||
;; KS am UNSKALIERTEN Block messen (der Cache arbeitet je Blockname), die
|
||||
;; lokalen Punkte danach selbst in X skalieren.
|
||||
(setq ks-data (ks-block-messen blockname))
|
||||
(setq ks-ein (cadr (assoc "KS_EIN" ks-data)))
|
||||
(setq ks-aus (cadr (assoc "KS_AUS" ks-data)))
|
||||
(setq block-obj (vla-InsertBlock modelspace
|
||||
(vlax-3D-point '(0 0 0))
|
||||
blockname skala 1.0 1.0 0))
|
||||
(ssg-ils-block-auf-ebene block-obj blockname)
|
||||
(if (> (abs hz) 0.0001)
|
||||
(vla-TransformBy block-obj (vlax-tmatrix
|
||||
(list (list chv (- shv) 0 0)
|
||||
(list shv chv 0 0)
|
||||
(list 0 0 1 0)
|
||||
(list 0 0 0 1))))
|
||||
)
|
||||
(if (and ks-ein ks-aus)
|
||||
(progn
|
||||
(setq ein-x (* skala (car (car ks-ein)))
|
||||
ein-y (cadr (car ks-ein))
|
||||
ein-z (caddr (car ks-ein)))
|
||||
(setq aus-x (* skala (car (car ks-aus))))
|
||||
(setq offset (list
|
||||
(- (car einfuegepunkt) (- (* chv ein-x) (* shv ein-y)))
|
||||
(- (cadr einfuegepunkt) (+ (* shv ein-x) (* chv ein-y)))
|
||||
(- (caddr einfuegepunkt) ein-z)))
|
||||
(vla-Move block-obj
|
||||
(vlax-3D-point '(0 0 0))
|
||||
(vlax-3D-point offset))
|
||||
(setq dx-loc (- aus-x ein-x))
|
||||
(setq dy-loc (- (cadr (car ks-aus)) ein-y))
|
||||
(setq dz-loc (- (caddr (car ks-aus)) ein-z))
|
||||
(setq ausgang (list
|
||||
(+ (car einfuegepunkt) (- (* chv dx-loc) (* shv dy-loc)))
|
||||
(+ (cadr einfuegepunkt) (+ (* shv dx-loc) (* chv dy-loc)))
|
||||
(+ (caddr einfuegepunkt) dz-loc)))
|
||||
(ssg-sepliste-dbg
|
||||
(strcat "insert-block-ks-skaliert " blockname
|
||||
" hz=" (rtos (float hz) 2 2) " skala=" (rtos (float skala) 2 4)
|
||||
" einfuegepunkt=" (ssg-sepliste-dbg-pt einfuegepunkt)
|
||||
" offset(=Gruppencode 10)=" (ssg-sepliste-dbg-pt offset)
|
||||
" ausgang=" (ssg-sepliste-dbg-pt ausgang)))
|
||||
(princ (ssg-textf "vfc-ks-aus-xyz"
|
||||
(list (rtos (car ausgang) 2 2) (rtos (cadr ausgang) 2 2) (rtos (caddr ausgang) 2 2))))
|
||||
ausgang
|
||||
)
|
||||
(progn
|
||||
(princ (ssg-text "vfc-warnung-ks-nicht-gefunden"))
|
||||
einfuegepunkt
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; FREI ROTIERTE KS-EINFUEGUNG (beliebige 3x3-Matrix)
|
||||
;; ------------------------------------------------------------
|
||||
;; Verallgemeinerung von insert-block-by-ks/insert-block-ks-skaliert: statt
|
||||
;; einer festen Rz- bzw. Rz*Ry-Drehung nimmt sie eine FERTIGE 3x3-Rotations-
|
||||
;; matrix entgegen. Noetig geworden fuer AUFRECHT eingebaute Baugruppen: der
|
||||
;; Kettenfoerderer ist in der XY-Ebene gezeichnet (X = Fahrtrichtung,
|
||||
;; Y = Hoehe), soll aber im Modell stehen - seine Hoehe muss also nach Z. Das
|
||||
;; ist eine Drehung um X, die weder insert-block-by-ks (nur Rz) noch
|
||||
;; ssg-rot-matrix-zy (Rz*Ry) erzeugen kann.
|
||||
;;
|
||||
;; Bewusst matrixbasiert statt mit einem weiteren Winkelparameter: die
|
||||
;; Aufrichtung ist nur EIN Anwendungsfall, und jeder weitere haette eine
|
||||
;; weitere Spezialfunktion gebraucht. Den Aufrufern bleibt freigestellt,
|
||||
;; welche Drehungen sie kombinieren (beim Kettenfoerderer
|
||||
;; Rz(basis) * Rx(90) * Rz(eigen), siehe kf-matrix-aufrecht).
|
||||
|
||||
;; Elementare Rotationsmatrizen (3x3, Winkel in GRAD).
|
||||
(defun ks-rot-x (grad / r c s)
|
||||
(setq r (* (float grad) (/ pi 180.0)) c (cos r) s (sin r))
|
||||
(list (list 1.0 0.0 0.0)
|
||||
(list 0.0 c (- s))
|
||||
(list 0.0 s c )))
|
||||
|
||||
(defun ks-rot-y (grad / r c s)
|
||||
(setq r (* (float grad) (/ pi 180.0)) c (cos r) s (sin r))
|
||||
(list (list c 0.0 s )
|
||||
(list 0.0 1.0 0.0)
|
||||
(list (- s) 0.0 c )))
|
||||
|
||||
(defun ks-rot-z (grad / r c s)
|
||||
(setq r (* (float grad) (/ pi 180.0)) c (cos r) s (sin r))
|
||||
(list (list c (- s) 0.0)
|
||||
(list s c 0.0)
|
||||
(list 0.0 0.0 1.0)))
|
||||
|
||||
;; 3x3-Rotation in die 4x4-Form bringen, die vla-TransformBy erwartet.
|
||||
(defun ks-mat3->mat4 (R)
|
||||
(list (append (car R) '(0.0))
|
||||
(append (cadr R) '(0.0))
|
||||
(append (caddr R) '(0.0))
|
||||
'(0.0 0.0 0.0 1.0)))
|
||||
|
||||
;; --- Block per KS_EIN/KS_AUS einfuegen, frei rotiert und in X skaliert ---
|
||||
;; blockname Rohname (wird ueber ensure-block-loaded aufgeloest)
|
||||
;; einfuegepunkt Weltpunkt, auf den KS_EIN zu liegen kommt
|
||||
;; R 3x3-Rotationsmatrix (Blockkoordinaten -> Welt)
|
||||
;; skala X-Massstab (1.0 = unskaliert)
|
||||
;; Rueckgabe: Weltpunkt von KS_AUS (fuer die Verkettung), sonst einfuegepunkt.
|
||||
;;
|
||||
;; Reihenfolge wie bei den uebrigen Primitiven: am Ursprung einfuegen,
|
||||
;; skalieren, drehen, dann so verschieben, dass das GEDREHTE KS_EIN exakt auf
|
||||
;; einfuegepunkt liegt. Die lokalen KS-Punkte werden dabei zuerst in X
|
||||
;; mitskaliert - sonst zeigt der zurueckgegebene KS_AUS am skalierten Block
|
||||
;; vorbei.
|
||||
(defun insert-block-ks-matrix (blockname einfuegepunkt R skala /
|
||||
block-obj ks-data ks-ein ks-aus
|
||||
ein-lok aus-lok ein-welt aus-welt offset ausgang)
|
||||
(if (or (null einfuegepunkt) (not (listp einfuegepunkt)))
|
||||
(progn
|
||||
(princ (ssg-textf "vfc-fehler-ungueltiger-einfuegepunkt" (list blockname)))
|
||||
(exit))
|
||||
)
|
||||
(if (or (null skala) (<= skala 0.0)) (setq skala 1.0))
|
||||
(setq blockname (ensure-block-loaded blockname))
|
||||
(if (not (tblsearch "BLOCK" blockname))
|
||||
(progn
|
||||
(princ (ssg-textf "vfc-fehler-block-nicht-in-bibliothek-abgebrochen" (list blockname)))
|
||||
(exit))
|
||||
)
|
||||
(setq ks-data (ks-block-messen blockname))
|
||||
(setq ks-ein (cadr (assoc "KS_EIN" ks-data)))
|
||||
(setq ks-aus (cadr (assoc "KS_AUS" ks-data)))
|
||||
(setq block-obj (vla-InsertBlock modelspace
|
||||
(vlax-3D-point '(0 0 0))
|
||||
blockname skala 1.0 1.0 0))
|
||||
(ssg-ils-block-auf-ebene block-obj blockname)
|
||||
(vla-TransformBy block-obj (vlax-tmatrix (ks-mat3->mat4 R)))
|
||||
(if (and ks-ein ks-aus)
|
||||
(progn
|
||||
;; lokale KS-Punkte, in X mitskaliert
|
||||
(setq ein-lok (list (* skala (car (car ks-ein)))
|
||||
(cadr (car ks-ein))
|
||||
(caddr (car ks-ein))))
|
||||
(setq aus-lok (list (* skala (car (car ks-aus)))
|
||||
(cadr (car ks-aus))
|
||||
(caddr (car ks-aus))))
|
||||
(setq ein-welt (mat3-mul-vec3 R ein-lok))
|
||||
(setq aus-welt (mat3-mul-vec3 R aus-lok))
|
||||
(setq offset (list (- (car einfuegepunkt) (car ein-welt))
|
||||
(- (cadr einfuegepunkt) (cadr ein-welt))
|
||||
(- (caddr einfuegepunkt) (caddr ein-welt))))
|
||||
(vla-Move block-obj
|
||||
(vlax-3D-point '(0 0 0))
|
||||
(vlax-3D-point offset))
|
||||
(setq ausgang (list (+ (car einfuegepunkt) (- (car aus-welt) (car ein-welt)))
|
||||
(+ (cadr einfuegepunkt) (- (cadr aus-welt) (cadr ein-welt)))
|
||||
(+ (caddr einfuegepunkt) (- (caddr aus-welt) (caddr ein-welt)))))
|
||||
(ssg-sepliste-dbg
|
||||
(strcat "insert-block-ks-matrix " blockname
|
||||
" skala=" (rtos (float skala) 2 4)
|
||||
" einfuegepunkt=" (ssg-sepliste-dbg-pt einfuegepunkt)
|
||||
" ks_ein_welt=" (ssg-sepliste-dbg-pt ein-welt)
|
||||
" ks_aus_welt=" (ssg-sepliste-dbg-pt aus-welt)
|
||||
" ausgang=" (ssg-sepliste-dbg-pt ausgang)))
|
||||
ausgang
|
||||
)
|
||||
(progn
|
||||
(princ (ssg-text "vfc-warnung-ks-nicht-gefunden"))
|
||||
einfuegepunkt
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; SEPLISTE: Separator-/AS-/ES-Reihenfolge als XDATA am fertigen Wrapper
|
||||
;; ------------------------------------------------------------
|
||||
|
||||
@@ -218,6 +218,102 @@
|
||||
(defun vf-motorseite-aktuell ( / )
|
||||
(if (member *vf-motorseite* '("links" "rechts")) *vf-motorseite* "rechts"))
|
||||
|
||||
;; ============================================================
|
||||
;; VF-HOEHE JE SEGMENT (Attribut VF_HOEHE_m, Sivas 4433-4437)
|
||||
;; ============================================================
|
||||
;; Sivas erwartet je Streckengruppe bis zu fuenf Variofoerderer-Hoehen. Ein
|
||||
;; Eintrag gehoert zu EINEM VF-Segment (Koerper) - nicht zu einer ganzen
|
||||
;; Foerdereinheit und nicht zur ganzen Kette (Nutzer-Korrektur 2026-10-21):
|
||||
;;
|
||||
;; Hoehe = Mittelwert aus KS_EIN und KS_AUS DIESES Segments.
|
||||
;;
|
||||
;; Eine Kette, die durch Vario-Boegen in drei Abschnitte geteilt ist, bekommt
|
||||
;; dadurch drei Werte - die Liste laeuft Eintrag fuer Eintrag parallel zu
|
||||
;; L_VF_m, VF_WINKEL und ANTRIEBFAHRTRICHTUNG.
|
||||
;;
|
||||
;; Erfasst wird an genau EINER Stelle: vfs-vf-koerper baut ein Segment, kennt
|
||||
;; dessen KS_EIN als Eingangspunkt und liefert dessen KS_AUS zurueck. Alle
|
||||
;; Modi (Standard, Etage, Linienzug) bauen ihre VF-Koerper darueber, deshalb
|
||||
;; muss der verzweigte Bau-Pfad selbst nicht angefasst werden.
|
||||
;;
|
||||
;; Einheit: Meter mit 3 Nachkommastellen (wie L_VF_m), kommagetrennt ueber
|
||||
;; vfl-join-komma - Reihenfolge = Bau-Reihenfolge.
|
||||
(if (not (boundp '*vf-acc-vfhoehe*)) (setq *vf-acc-vfhoehe* '()))
|
||||
|
||||
(defun vf-vfhoehe-reset ()
|
||||
(setq *vf-acc-vfhoehe* '()))
|
||||
|
||||
;; Ein VF-Segment erfassen: z-ein = Z des KS_EIN, z-aus = Z des KS_AUS (mm).
|
||||
;; Fehlt einer der Werte, wird NICHTS angehaengt - sonst verschoebe sich die
|
||||
;; Liste gegen L_VF_m/VF_WINKEL und im Export landete eine Hoehe beim falschen
|
||||
;; Foerderer.
|
||||
(defun vf-vfhoehe-segment (z-ein z-aus)
|
||||
(if (and (numberp z-ein) (numberp z-aus))
|
||||
(setq *vf-acc-vfhoehe*
|
||||
(append *vf-acc-vfhoehe* (list (vf-meter-3 (/ (+ z-ein z-aus) 2.0)))))))
|
||||
|
||||
;; Bequemes Paar fuer die Bau-Pfade: vor dem Einbau den Startpunkt merken,
|
||||
;; danach mit dem Endpunkt abschliessen. Beide geben ihren Punkt zurueck,
|
||||
;; lassen sich also ohne zusaetzliche lokale Variable einsetzen:
|
||||
;;
|
||||
;; (vf-vfhoehe-merke pt)
|
||||
;; (setq pt (insert-inclined-scaled-block ...))
|
||||
;; (vf-vfhoehe-schliesse pt)
|
||||
;;
|
||||
;; Noetig, weil die VF-Segmente NICHT alle ueber vfs-vf-koerper laufen: die
|
||||
;; horizontalen Zwischenstuecke und die Modus-2-Fuellstuecke bauen direkt mit
|
||||
;; insert-inclined-scaled-block. Wurde dort nicht erfasst, fehlten ihre
|
||||
;; Hoehen und VF_HOEHE_m war kuerzer als L_VF_m (realer Befund 2026-10-21:
|
||||
;; L_VF_m hatte drei Eintraege, VF_HOEHE_m nur einen).
|
||||
;;
|
||||
;; REGEL: Jede Stelle, die (vfl-acc-vf-seg ...) aufruft, MUSS auch eine Hoehe
|
||||
;; erfassen - sonst verschiebt sich die Liste gegen L_VF_m/VF_WINKEL und im
|
||||
;; Sivas-Export landet eine Hoehe beim falschen Foerderer.
|
||||
(if (not (boundp '*vf-vfhoehe-merk*)) (setq *vf-vfhoehe-merk* nil))
|
||||
|
||||
(defun vf-vfhoehe-merke (pt)
|
||||
(setq *vf-vfhoehe-merk* (if (listp pt) (caddr pt) nil))
|
||||
pt)
|
||||
|
||||
(defun vf-vfhoehe-schliesse (pt)
|
||||
(vf-vfhoehe-segment *vf-vfhoehe-merk* (if (listp pt) (caddr pt) nil))
|
||||
(setq *vf-vfhoehe-merk* nil)
|
||||
pt)
|
||||
|
||||
;; SONDERFALL Standard/Etage: Hoehe ueber die GANZE Kette.
|
||||
;;
|
||||
;; Diese beiden Typen haben nur EINEN Motor und nur EINEN geraden
|
||||
;; VF-Abschnitt (Nutzer-Vorgabe 2026-10-21). Statt des Segmentwerts gilt dort
|
||||
;; der Mittelwert der ganzen Anlage:
|
||||
;; Anfang = KS_EIN des AS-Elements (Startpunkt der Anlage)
|
||||
;; Ende = KS_AUS des ES-Elements (Rueckgabewert der Einfuegefunktion)
|
||||
;;
|
||||
;; ERSETZT die Liste bewusst, statt anzuhaengen: vfs-vf-koerper hat beim Bau
|
||||
;; bereits den Segmentwert gesammelt, der hier nicht gelten soll. Ergebnis ist
|
||||
;; genau ein Eintrag.
|
||||
;;
|
||||
;; Gerechnet wird aus der GEBAUTEN Geometrie, nicht aus der Soll-Vorgabe
|
||||
;; (anders als MONTAGEHOEHE_m, dessen hoehe-bis aus deltaH abgeleitet ist).
|
||||
;; Beide Hoehen in mm.
|
||||
(defun vf-vfhoehe-kette (z-anfang z-ende)
|
||||
(if (and (numberp z-anfang) (numberp z-ende))
|
||||
(setq *vf-acc-vfhoehe* (list (vf-meter-3 (/ (+ z-anfang z-ende) 2.0))))
|
||||
(setq *vf-acc-vfhoehe* '())))
|
||||
|
||||
;; Millimeter -> Meter als String mit GENAU 3 Nachkommastellen.
|
||||
;;
|
||||
;; (rtos x 2 3) allein genuegt nicht: je nach DIMZIN schneidet es nachfolgende
|
||||
;; Nullen ab und liefert "2.5" statt "2.500" bzw. "-1" statt "-1.000" (real
|
||||
;; beobachtet im Testlauf). Fuer eine Merkmalsliste ist die feste Stellenzahl
|
||||
;; aber gewollt, darum wird hier aufgefuellt - unabhaengig von der
|
||||
;; Zeichnungseinstellung.
|
||||
(defun vf-meter-3 (mm / s pos)
|
||||
(setq s (rtos (/ (float mm) 1000.0) 2 3))
|
||||
(if (not (vl-string-search "." s)) (setq s (strcat s ".")))
|
||||
(setq pos (vl-string-search "." s))
|
||||
(while (< (- (strlen s) pos 1) 3) (setq s (strcat s "0")))
|
||||
s)
|
||||
|
||||
;; ============================================================
|
||||
;; TEIL 5: KS_EIN/KS_AUS EXTRAKTION
|
||||
;; ============================================================
|
||||
@@ -977,6 +1073,9 @@
|
||||
(cons "L_VF_m" (rtos (/ L_VF 1000.0) 2 3))
|
||||
(cons "ANTRIEBFAHRTRICHTUNG" richtung)
|
||||
(cons "VF_WINKEL" (itoa best-winkel))
|
||||
;; Hoehe der (einen) Foerdereinheit - beim Standard-/Etage-Typ
|
||||
;; fuellen vfs-vf-entry/-exit genau einen Listeneintrag.
|
||||
(cons "VF_HOEHE_m" (vfl-join-komma *vf-acc-vfhoehe*))
|
||||
(cons "ANZAHL_SEPARATOR" "2")
|
||||
(cons "ANZAHL_SCANNER" (itoa n-scanner))
|
||||
(cons "GERUEST_EINZELMODUL" geruest-einzelmodul)
|
||||
@@ -1013,6 +1112,10 @@
|
||||
horizontal-info winkelwahl best-winkel L_GF L_VF L_GF1 L_GF2
|
||||
verteilung-modus n-scanner hoehe-von hoehe-bis lastEnt
|
||||
vf-insert vf-endpunkt staustrecke-basis)
|
||||
;; VF-Hoehen-Akkumulator pro Anlage zuruecksetzen - sonst erbte die naechste
|
||||
;; Anlage die Hoehen der vorherigen. (Im Linienzug erledigt das
|
||||
;; vfl-acc-reset; Standard/Etage laufen nicht darueber.)
|
||||
(vf-vfhoehe-reset)
|
||||
(setq berechne-fn (vf-registry-berechne-fn typ))
|
||||
(setq einfuege-fn (vf-registry-einfuege-fn typ))
|
||||
(setq ergebnis (apply berechne-fn (list deltaL deltaH richtung seite)))
|
||||
@@ -1064,6 +1167,15 @@
|
||||
(setq vf-endpunkt
|
||||
(apply einfuege-fn
|
||||
(list deltaL deltaH richtung best-winkel L_GF1 L_GF2 L_VF startpunkt seite hz)))
|
||||
;; VF_HOEHE_m fuer Standard/Etage: Mittelwert ueber die GANZE Kette
|
||||
;; (AS-KS_EIN = startpunkt, ES-KS_AUS = Rueckgabe der Einfuegefunktion),
|
||||
;; weil es hier nur einen Motor und nur einen geraden VF-Abschnitt
|
||||
;; gibt. Ersetzt den beim Bau gesammelten Segmentwert - siehe
|
||||
;; vf-vfhoehe-kette. Der Linienzug laeuft NICHT hier durch und behaelt
|
||||
;; daher seine Segmentliste.
|
||||
(vf-vfhoehe-kette (caddr startpunkt)
|
||||
(if (and vf-endpunkt (listp vf-endpunkt))
|
||||
(caddr vf-endpunkt) nil))
|
||||
(setq vf-insert
|
||||
(vf-block-erstellen typ seite vf-nummer n-scanner
|
||||
hoehe-von hoehe-bis deltaH deltaL L_VF L_GF1 L_GF2
|
||||
|
||||
+11
-4
@@ -101,8 +101,8 @@
|
||||
(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). Aktiv referenziert in
|
||||
;; vf_linienzug.lsp (beide Aufrufstellen von vfl2-pruefe-eckwinkel).
|
||||
;; vf-linienzug-modus3 -> vfl-pfad-eckwinkel-pruefen). Aktiv referenziert in
|
||||
;; vf_linienzug.lsp (beide Aufrufstellen von vfl-pfad-eckwinkel-pruefen).
|
||||
(if (null *vfk-eckwinkel-toleranz*) (setq *vfk-eckwinkel-toleranz* 5.0))
|
||||
|
||||
;; Schwellwert (Grad), ab dem ein Frame noch als "flach" (~0 Grad) gilt.
|
||||
@@ -123,7 +123,7 @@
|
||||
;; (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, ...)
|
||||
;; vf_linienzug.lsp (vfl-body-zerlegung, vfl-zsolve-winkel-waehlen, ...)
|
||||
;; Diese vier NICHT vereinheitlichen ohne sorgfaeltige Pruefung - sie
|
||||
;; entstehen aus unterschiedlicher Bauteil-Zusammensetzung (siehe jeweiliger
|
||||
;; Kommentar im Modul), keine Kopiergleichheit.
|
||||
@@ -166,7 +166,7 @@
|
||||
;; 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. Das fruehere rohe 400.0-
|
||||
;; Duplikat (br-gf1 in vfl3-*) referenziert jetzt *vfl-gf-min-laenge*.
|
||||
;; Duplikat (br-gf1 in vfl-zsolve-*) referenziert jetzt *vfl-gf-min-laenge*.
|
||||
(if (null *vfk-gf-anschluss-mindestlaenge*) (setq *vfk-gf-anschluss-mindestlaenge* 400.0))
|
||||
|
||||
;; ============================================================
|
||||
@@ -303,6 +303,13 @@
|
||||
;; Ueberschreiten, kein Abbruch. Aktiv referenziert.
|
||||
(if (null *vfk-vf-laenge-max*) (setq *vfk-vf-laenge-max* 25000.0))
|
||||
|
||||
;; Hoechstzahl Vario-Kurven INNERHALB einer VF-Einheit (zwischen Umlenk- und
|
||||
;; Motorstation) - Nutzer-Regel 2026-10-22. Zwei Kurven bedeuten hoechstens
|
||||
;; drei VF-Geraden im selben Lauf; danach muss die Einheit mit einer
|
||||
;; Motorstation schliessen und eine neue mit Umlenkstation beginnen.
|
||||
;; Geprueft in vfl-m2-lauf-grenzen (vf_linienzug.lsp, Modus 2).
|
||||
(if (null *vfk-vf-kurven-max*) (setq *vfk-vf-kurven-max* 2))
|
||||
|
||||
(setq *vfk-konstanten-geladen* t)
|
||||
(princ)
|
||||
(princ)
|
||||
|
||||
+1605
-147
File diff suppressed because it is too large
Load Diff
+19
-2
@@ -274,7 +274,18 @@
|
||||
((and (= (type v) 'STR) (= (strcase v) "AUTO")) (vsp-raus "NIL" nil))
|
||||
(T (vsp-zahl "REAL" v "eingang_hoehe"))))
|
||||
|
||||
(defun vsp-praeambel (kopf / punkt)
|
||||
;; Praeambel-Tokens: PT(Startpunkt) REAL(Starthoehe) STR(AS ja/nein)
|
||||
;; [STR(Winkel) STR(Seite) (PT|NIL)(Zufuehrungsachse)].
|
||||
;;
|
||||
;; Das Achsen-Feld "as_achse" ist OPTIONAL (Gegenstueck zu
|
||||
;; vfl-frage-as-winkel-seite-oder-achse und zu praeambel() in
|
||||
;; lib/vf_linienzug_grammatik.py):
|
||||
;; [x, y, z] -> PT (Zufuehrungsachse ueber einen zweiten Punkt)
|
||||
;; "ohne" -> NIL (bewusst ohne Achse gebaut)
|
||||
;; fehlt -> gar kein Token = Journalformat VOR 2026-10-21. Das replayt
|
||||
;; unveraendert; die Kettenrichtung kommt dann wie frueher aus
|
||||
;; dem naechsten Klick.
|
||||
(defun vsp-praeambel (kopf / punkt achse)
|
||||
(setq *vsp-wo* "start")
|
||||
(setq punkt (ssg-val kopf "start_punkt"))
|
||||
(if (and punkt (listp punkt) (>= (length punkt) 3))
|
||||
@@ -287,7 +298,13 @@
|
||||
(if (vsp-ja-p (ssg-val kopf "as"))
|
||||
(progn
|
||||
(vsp-wert-str (ssg-val kopf "as_winkel") "as_winkel")
|
||||
(vsp-code-raus *vsp-tab-seite* (ssg-val kopf "as_seite") "as_seite"))))
|
||||
(vsp-code-raus *vsp-tab-seite* (ssg-val kopf "as_seite") "as_seite")
|
||||
(setq achse (ssg-val kopf "as_achse"))
|
||||
(cond
|
||||
((and achse (listp achse) (>= (length achse) 3))
|
||||
(vsp-raus "PT" (mapcar 'float achse)))
|
||||
((equal achse "ohne") (vsp-raus "NIL" nil))
|
||||
))))
|
||||
|
||||
;; naechste: Felder der NAECHSTEN Top-Level-Sektion (oder nil) - wird nur fuer
|
||||
;; "Linie-GF" gebraucht (siehe dort). *vsp-es-verbraucht* (Ausgabe-Flag, vom
|
||||
|
||||
@@ -612,9 +612,15 @@
|
||||
;; beliebig aneinanderreihen (siehe doc/VarioFoerderer_Linienzug_Prinzipien.md).
|
||||
;; best-winkel=0 => horizontales Sub-Segment (Boegen fest auf_3/ab_3).
|
||||
(defun vfs-vf-koerper (aktueller-punkt richtung best-winkel L_VF hz /
|
||||
bogen-name bogen-mass bogen-dx bogen-dz)
|
||||
bogen-name bogen-mass bogen-dx bogen-dz z-ein)
|
||||
(if (null hz) (setq hz 0.0))
|
||||
(setq hz (float hz))
|
||||
;; Hoehe DIESES VF-Segments (Attribut VF_HOEHE_m, Sivas 4433-4437):
|
||||
;; KS_EIN ist der Punkt beim Eintritt, KS_AUS der Rueckgabewert am Ende -
|
||||
;; der Mittelwert beider wird unten angehaengt. Eine Kette mit drei durch
|
||||
;; Vario-Boegen getrennten Abschnitten bekommt dadurch drei Werte, parallel
|
||||
;; zu L_VF_m und VF_WINKEL (Nutzer-Vorgabe 2026-10-21).
|
||||
(setq z-ein (caddr aktueller-punkt))
|
||||
|
||||
;; 5. 1. Vertikalbogen
|
||||
;; Sonderfall best-winkel=0 (horizontale Zwischenstrecke, siehe
|
||||
@@ -717,6 +723,8 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; Segment-Hoehe anhaengen: Mittelwert aus KS_EIN (z-ein) und KS_AUS.
|
||||
(vf-vfhoehe-segment z-ein (caddr aktueller-punkt))
|
||||
aktueller-punkt
|
||||
)
|
||||
|
||||
|
||||
@@ -2,62 +2,77 @@
|
||||
|
||||
AutoLISP-Makros (SSG_LIB) fuer BricsCAD Pro zur automatisierten Erstellung von Foerderanlagen-Layouts (ILS Kreisel, Omniflo, VarioFoerderer, Gefaellestrecke, Geruest).
|
||||
|
||||
**Einstieg:**
|
||||
|
||||
- [doc/faq.md](doc/faq.md) - haeufige Fragen und erste Schritte mit dem Programm
|
||||
- [doc/cad-datenaufbereitung.md](doc/cad-datenaufbereitung.md) - neue CAD-Bausteine anlegen: Koordinatensysteme, Platzierung, Datenablage
|
||||
|
||||
## Menustruktur (SSG_LIB)
|
||||
|
||||
```
|
||||
SSG_LIB
|
||||
├── ILS
|
||||
│ ├── Kreisel-Module
|
||||
│ │ ├── Einfuegen → KreiselInsert
|
||||
│ │ ├── Verbinden → KreiselConnect
|
||||
│ │ ├── Bearbeiten → KreiselEdit
|
||||
│ │ └── Eckrad → ILS_Eckrad
|
||||
│ │ ├── Einfuegen / Verbinden / Bearbeiten → KreiselInsert / KreiselConnect / KreiselEdit
|
||||
│ │ ├── Eckrad / Eckrad bearbeiten → ILS_Eckrad / EckradEdit
|
||||
│ │ └── Weichenpunkte ermitteln → KREISEL_WEICHEN
|
||||
│ ├── Zusatzmodul
|
||||
│ │ ├── BTMT-Beladung → ILS_BTMT_Beladung
|
||||
│ │ ├── BTMT-Entladung → ILS_BTMT_Entladung
|
||||
│ │ ├── Scanner einfuegen → ILS_SCANNER_INSERT
|
||||
│ │ └── Separator einfuegen → ILS_SEPARATOR_INSERT
|
||||
│ │ ├── BTMT-Beladung / -Entladung → ILS_BTMT_Beladung / ILS_BTMT_Entladung
|
||||
│ │ └── Scanner / Separator einfuegen → ILS_SCANNER_INSERT / ILS_SEPARATOR_INSERT
|
||||
│ ├── Foerderer
|
||||
│ │ ├── Standard → StandardVarioFoerderer / StandardVarioFoerderer3D
|
||||
│ │ ├── Etage → EtageVarioFoerderer / EtageVarioFoerderer3D
|
||||
│ │ ├── Standard (Werte manuell / aus 3D-Linie) → StandardVarioFoerderer / StandardVarioFoerderer3D
|
||||
│ │ ├── Etage (Werte manuell / aus 3D-Linie) → EtageVarioFoerderer / EtageVarioFoerderer3D
|
||||
│ │ ├── Streckengruppe (Linienzug) → LinienzugVarioFoerdererManuell / -Zielhoehe / -Stueckweise
|
||||
│ │ └── Vario_Kette_Merge / VARIOFOERDERER_NACHRUESTEN
|
||||
│ │ └── Vario_Kette_Merge / VarioFoerderer nachruesten → Vario_Kette_Merge / VARIOFOERDERER_NACHRUESTEN
|
||||
│ └── Gefaellestrecke
|
||||
│ ├── einfach → GEFAELLESTRECKE_EINFACH
|
||||
│ ├── aus 3D-Linie → GEFAELLESTRECKE_3DLINIE
|
||||
│ └── aus Linienzug → GEFAELLESTRECKE_LINIENZUG
|
||||
│ ├── einfach / aus 3D-Linie / aus Linienzug → GEFAELLESTRECKE_EINFACH / _3DLINIE / _LINIENZUG
|
||||
│ └── QC Linie mit GF (auch U-Form) → QcLinieMitGf / QcLinieMitGfUForm
|
||||
├── Omniflo
|
||||
│ ├── Boegen APB110/APB60
|
||||
│ ├── Aluprofil Gerade (AP60/AP110/APG110)
|
||||
│ ├── Weichen (90/45/Parallel/Weichenkoerper/Weichenkombinationen)
|
||||
│ ├── TEF Elemente, Anbaugruppen, Verbinder, Boegen fuer Weichen
|
||||
│ ├── Element bearbeiten → OMNI_EDIT
|
||||
│ └── Ladeschleifen (AP110) → OMNI_LADESCHLEIFE_AP110
|
||||
│ ├── Fahrstrecke / Fahrstrecken beschriften → OMNI_FAHRSTRECKE / OMNI_FAHRSTRECKE_BESCHRIFTEN
|
||||
│ ├── Boegen APB110 / APB60, Aluprofil Gerade (AP60/AP110/APG110)
|
||||
│ ├── Weichen (90/45/Parallel/22.5, Delta, Star)
|
||||
│ ├── TEF Elemente (inkl. TEF Gerade auf Linie → TEF_FOERDERER_LINIE)
|
||||
│ ├── Anbaugruppen (Stopper, Scanner, Buerstenbremse)
|
||||
│ ├── Spez. Streckenelemente ▸ Tuerloesungen ▸ Schwenkschienen → OMNI_SCHW_400_*
|
||||
│ ├── KettenFoerderer → KETTENFOERDERER
|
||||
│ ├── Ladeschleifen → OMNI_LADESCHLEIFE_AP110
|
||||
│ ├── Verbinder → OMNI_TV_*
|
||||
│ ├── Boegen fuer Weichen (ausgegraut, Dummy) → OMNI_APBW_*
|
||||
│ └── Element bearbeiten → OMNI_EDIT
|
||||
├── Geruest
|
||||
│ ├── Rohr-Geruest-Traeger → GERUEST_TRAEGER
|
||||
│ ├── Saeulen / Rohrabhaenger / Wandbefestigung → GERUEST
|
||||
│ ├── Saeulen / Rohrabhaenger / Wandbefestigung → GERUEST_SAEULEN / GERUEST_ROHRABHAENGER / GERUEST_WANDBEFESTIGUNG
|
||||
│ ├── Gattertraeger (Platzhalter) → GERUEST
|
||||
│ └── Funktionen ▸ Traeger beschriften → GERUEST_TRAEGER_BESCHRIFTEN
|
||||
├── SPS
|
||||
│ ├── TRO (Marker einfuegen/bearbeiten) → TRO_INSERT / TRO_EDIT
|
||||
│ └── Connections (einfuegen/bearbeiten, Eingang/Ausgang) → CONNECTION_INSERT / CONNECTION_EDIT / ILS_EINGANG_INSERT / ILS_AUSGANG_INSERT
|
||||
│ ├── Connections (einfuegen/bearbeiten) → CONNECTION_INSERT / CONNECTION_EDIT
|
||||
│ └── Eingang / Ausgang → ILS_EINGANG_INSERT / ILS_AUSGANG_INSERT
|
||||
├── Export
|
||||
│ ├── Export Sivas → EXPORTSIVAS
|
||||
│ └── Export CSV → EXPORTCSV
|
||||
├── Konfiguration
|
||||
│ ├── Umschalten 2D und 3D → SSG_DIM_SWITCH
|
||||
│ ├── Alle Bloecke auf 2D / 3D → SSG_DIM_ALL_2D / SSG_DIM_ALL_3D
|
||||
│ ├── Sprache → SSG_SPRACHE
|
||||
│ └── Planquadrate an/aus → PLANQUADRATE_TOGGLE
|
||||
│ ├── Planquadrate an/aus → PLANQUADRATE_TOGGLE
|
||||
│ └── CSV-Export → CSV_EXPORT_KONFIG
|
||||
├── Werkzeuge
|
||||
│ ├── Bloecke zaehlen/loeschen, Attribute ersetzen → ssg_blocktools
|
||||
│ └── Text ersetzen/parallel/Hoehe/Stil → ssg_texttools
|
||||
└── Tests (Testsuiten ausfuehren und exportieren)
|
||||
│ ├── Bloecke zaehlen / loeschen, Attribute ersetzen → SSG_BLOCK_COUNT / SSG_BLOCK_DELETE / SSG_ATTR_ERSETZEN
|
||||
│ ├── Text ersetzen / parallel / Hoehe / Stil → SSG_TEXT_ERSETZEN / _PARALLEL / _HOEHE / _STIL
|
||||
│ ├── Faehnchen + Stueckliste aus Zeichnung → SSG_FAEHNCHEN_STUECKLISTE
|
||||
│ └── Din Formate → DIN_FORMATE
|
||||
└── Tests (alle Testsuiten, einzelne Szenarien, Export CSV/Sivas ALL, KS 2D/3D pruefen)
|
||||
```
|
||||
|
||||
Doppelklick auf einen Block ruft `SSG_BLOCKEDIT` auf und verzweigt nach Blockname
|
||||
(Kreisel, Eckrad, VF_/GF_, KF_, Omniflo, GR_, TRO_, CONNECTION_, JAM_ → passender Edit-Befehl).
|
||||
|
||||
Vollstaendige, laufend aktualisierte Befehls-/Modulzuordnung: siehe `CLAUDE.md` (Abschnitt "Modulzuordnung im Menue") und `menu/SSG_LIB.mnu`.
|
||||
|
||||
## Lademechanismus
|
||||
|
||||
Module werden per Lazy-Loading ueber das Menuesystem geladen (`ssg-ensure` in `SSG_LIB.mnl`). Einmalige Einrichtung pro BricsCAD-Installation:
|
||||
Die Module werden beim Laden des Menues ueber `SSG_LIB.mnl` initialisiert (`ssg-ensure`, ueberspringt bereits geladene Module; einzelne Module wie `DrawPlanquadrate`, `DinFormate`, `Tro_Edit`, `Jam_Edit` werden erst beim ersten Aufruf nachgeladen). Einmalige Einrichtung pro BricsCAD-Installation:
|
||||
|
||||
1. `bin/setenv.bat` ausfuehren (setzt `DXFM_LISP` u.a.)
|
||||
2. BricsCAD starten
|
||||
@@ -70,16 +85,18 @@ Details und die Core-Ladereihenfolge: siehe `CLAUDE.md` Abschnitt "Lademechanism
|
||||
```text
|
||||
dxfmakros/
|
||||
├── Lisp/ # AutoLISP-Makros und Kernbibliotheken (Details: Lisp/README.md)
|
||||
├── bin/ # Hilfs-Skripte (setenv.bat, start_briscad.bat)
|
||||
├── bin/ # Hilfs-Skripte (setenv, start_briscad, run_tests, Python-Wrapper)
|
||||
├── cfg/ # Konfigurationsdateien
|
||||
├── data/ # JSON-Daten, DXF-Quellen, Block-Libraries - nicht im Git
|
||||
├── data/ # JSON-Komponentendaten, DWG-/DXF-Bloecke, Block-Libraries
|
||||
├── dcl/ # DCL-Dialogdefinitionen
|
||||
├── doc/ # Dokumentation (doc/plan Architektur/Analysen, doc/todo offene Fahrplaene)
|
||||
├── lang/ # Benutzertexte de_DE.json / en_GB.json (ssg-text)
|
||||
├── lib/ # Python-Skripte (DXF-Bearbeitung, Export)
|
||||
├── log/ # Logdateien - nicht im Git
|
||||
├── logs/ # Logdateien und .dbg-Ausgaben (DXFM_LOG) - nicht im Git
|
||||
├── menu/ # BricsCAD-Menudefinition (SSG_LIB.mnu, SSG_LIB.mnl)
|
||||
├── results/ # Ergebnisse / Exporte - nicht im Git
|
||||
├── tests/ # Testskripte und Referenzdaten
|
||||
├── tools/ # Einmal-Werkzeuge (z.B. Migration der Sprachtexte)
|
||||
├── LICENSE
|
||||
├── README.md
|
||||
└── requirements.txt
|
||||
@@ -110,11 +127,18 @@ Headless-Unit-Tests (file- und zeichnungsfrei):
|
||||
bin\run_tests.bat --lisp
|
||||
```
|
||||
|
||||
Python-Tests (in der `.venv`):
|
||||
|
||||
```bat
|
||||
pytest tests/
|
||||
bin\run_tests.bat --check
|
||||
```
|
||||
|
||||
Zeichnungs-/Szenario-Tests laufen interaktiv in BricsCAD ueber das Menue `Tests` bzw. `SSG_RUN_ALL_TESTS`. Details: `doc/LispTests.md`, `tests/README.md`.
|
||||
|
||||
## Dokumentation
|
||||
|
||||
Ausfuehrliche Modul- und Befehlsdokumentation: `CLAUDE.md` (Projektanweisungen) und `Lisp/README.md`. Weitere Anwender-/Entwickler-Themen direkt in `doc/` (u.a. `variofoerderer.md`, `csv-export.md`, `faq.md`, `kommandos.md`). Architektur-Analysen und Planungsdokumente in `doc/plan/` (u.a. `translate.md`, `Entwicklungsplan.md`), offene Fahrplaene/TODOs in `doc/todo/`.
|
||||
Ausfuehrliche Modul- und Befehlsdokumentation: `CLAUDE.md` (Projektanweisungen) und `Lisp/README.md`. Weitere Anwender-/Entwickler-Themen direkt in `doc/` (u.a. `kommandos.md` - Uebersicht aller Befehle und Skripte, `variofoerderer.md`, `vf_linienzug_modus1_anleitung.md`, `csv-export.md`, `json-input-lisp.md`, `faq.md`). Architektur-Analysen und Planungsdokumente in `doc/plan/` (u.a. `translate.md`, `Entwicklungsplan.md`), alle offenen TODOs gesammelt in `doc/todo.md` (Detail-Fahrplaene in `doc/todo/`).
|
||||
|
||||
## Lizenz
|
||||
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
@echo off
|
||||
REM ================================================================
|
||||
REM create_tests.bat - ILS Testlauf
|
||||
REM
|
||||
REM Ablauf:
|
||||
REM 1. Umgebung setzen
|
||||
REM 2. Python: ILStest.dxf mit Linien erzeugen
|
||||
REM 3. BricsCAD: Kreisel einfuegen, exportieren, speichern
|
||||
REM 4. Python: Ergebnisse gegen Referenzen validieren
|
||||
REM ================================================================
|
||||
|
||||
call "%~dp0setenv.bat"
|
||||
|
||||
echo.
|
||||
echo ================================================================
|
||||
echo ILS TEST - Schritt 1: Basis-DXF erzeugen
|
||||
echo ================================================================
|
||||
python "%DXFM_TESTS%\create_ILStest_dxf.py" "%DXFM_TESTS%\ILStest.dxf"
|
||||
if errorlevel 1 (
|
||||
echo FEHLER: DXF-Erzeugung fehlgeschlagen!
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo.
|
||||
echo ================================================================
|
||||
echo ILS TEST - Schritt 2: BricsCAD starten und Kreisel erzeugen
|
||||
echo ================================================================
|
||||
echo BricsCAD wird gestartet mit dem Testskript...
|
||||
echo Nach Abschluss des Tests BricsCAD schliessen.
|
||||
echo.
|
||||
REM /b = Skript ausfuehren (NICHT /s - das ist der Support-Ordner-Schalter).
|
||||
start /wait "" "%BRICSCAD%" /b "%DXFM_TESTS%\ILS_test.scr"
|
||||
|
||||
echo.
|
||||
echo ================================================================
|
||||
echo ILS TEST - Schritt 3: Ergebnisse validieren
|
||||
echo ================================================================
|
||||
python "%DXFM_TESTS%\validate_tests.py" "%DXFM_RESULTS%" "%DXFM_TESTS%\references"
|
||||
|
||||
echo.
|
||||
pause
|
||||
Binary file not shown.
@@ -71,6 +71,20 @@
|
||||
# Eigenstaendig wie BTMT, kein ANZAHL_*-Attribut an einem Carrier - export_csv.py
|
||||
# UND export_sivas.py fuehren sie als eigene TeileArt-Zeilen.
|
||||
#
|
||||
# pattern_verbinder: Omniflo-Verbinder (OMNI_TV_*, DWGs in data/omniflo/
|
||||
# Verbinder). Nur fuer Lisp's Block-SAMMLUNG und ID-Vergabe - export_sivas.py
|
||||
# erkennt sie wie alle Omniflo-Teile ueber TEILEART "Omniflo ..." und schreibt
|
||||
# je Nummer aus ARTINR eine Omniflo-Zeile.
|
||||
#
|
||||
# pattern_kettenfoerderer: Kettenfoerderer/Schraegfoerderer Stahl
|
||||
# (KettenFoerderer.lsp, KF_<n>). Eine selbst zusammengebaute Baugruppe wie
|
||||
# GR_*, mit eigenen Attributen TEILEART ("Omniflo Kettenfoerderer ...") und
|
||||
# ARTINR - erkannt wird sie darum im allgemeinen Omniflo-Zweig von
|
||||
# export_sivas.py. Die drei Bausteine darin (Umlenkstation, skaliertes
|
||||
# Zwischenstueck, Antriebsstation) werden NICHT einzeln gezaehlt. Die im
|
||||
# Dialog gewaehlten Verbindungselemente stehen als Attribut
|
||||
# VERBINDUNGSELEMENTE am Block und landen im Merkmale-/details-JSON.
|
||||
#
|
||||
# pattern_nested_bogen/_streckenelement/_umlenkstation/_motorstation: die
|
||||
# uebrigen Bausteine einer VF_n/GF_n-Kette (Boegen, gerade Foerderer-/
|
||||
# Gefaellestrecken-Segmente, Umlenk-/Motorstation). Wie pattern_schleuselement
|
||||
@@ -130,6 +144,8 @@ pattern_ks_subblocks= KS_EIN, KS_AUS, K1, K2, K3, K4
|
||||
pattern_gerade= AP110*, AP_110*, AP60*
|
||||
# Gerüst
|
||||
pattern_geruest= GR_*
|
||||
pattern_verbinder= VB_*, TV_*
|
||||
pattern_kettenfoerderer= KF_*
|
||||
|
||||
[python]
|
||||
# Interpreter fuer die Export-Skripte (lib/export_csv.py, lib/export_sivas.py).
|
||||
|
||||
@@ -168,6 +168,13 @@ gf_beschriftung = GF_Beschriftung, 7
|
||||
# Lisp/DrawPlanquadrate.lsp (DRAW_PLANQUADRATE).
|
||||
planquadrate = ZZ_Planquadrate, 8
|
||||
|
||||
# Kettenfoerderer (Schraegfoerderer Stahl), aus Umlenkstation + skaliertem
|
||||
# Zwischenstueck + Antriebsstation zusammengebauter Block KF_n - siehe
|
||||
# Lisp/KettenFoerderer.lsp (KETTENFOERDERER). Wie VF_n/GF_n eine
|
||||
# ZUSAMMENGEBAUTE Baugruppe ohne eigene Blockdatei, der Layer muss darum hier
|
||||
# stehen. Die drei Bausteine darin behalten ihre eigenen Layer.
|
||||
kettenfoerderer = Omni_Kettenfoerderer, 4
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Farben fuer Layer OHNE Baugruppen-Key
|
||||
|
||||
+97
-4
@@ -28,19 +28,45 @@
|
||||
# (TRANSFORMS-Dict), die den ermittelten Rohwert
|
||||
# (Attribut- oder Default-Wert) in die Sivas-Anzeige
|
||||
# umwandelt (z.B. "0"/"1" -> "Ja"/"Nein"). Bekannte Namen:
|
||||
# ja_nein, geruest_typ_anzeige. Ein unbekannter Name
|
||||
# ja_nein, geruest_typ_anzeige, mm_zu_m, as_es_vorhanden,
|
||||
# as_es_winkel, as_seite, es_seite. Ein unbekannter Name
|
||||
# bricht NICHT ab, der Rohwert wird unveraendert
|
||||
# uebernommen (siehe sivas_mapping.anwenden).
|
||||
# Soll ein Merkmal ohne eigenes Attribut nur per Transform
|
||||
# entstehen, braucht die Zeile trotzdem den ":" vor dem
|
||||
# "|" ("WINKEL_AS : | as_es_vorhanden") - sonst gilt der
|
||||
# Transform-Name als Fallback-Attributname.
|
||||
# Transforms, die mit @braucht_attribs markiert sind
|
||||
# (as_seite/es_seite), sehen zusaetzlich alle uebrigen
|
||||
# Attribute des Blocks - noetig, wenn ein Merkmal von
|
||||
# einem ZWEITEN Attribut abhaengt (Seite nur, wenn der
|
||||
# zugehoerige Winkel ueberhaupt ein Element ausweist).
|
||||
#
|
||||
# Abschnittsnamen entsprechen den bisherigen build_*_details-Funktionen in
|
||||
# export_sivas.py: [gefaellestrecke], [kreisel], [eckrad], [geruest]. Die
|
||||
# geruest-typ-Anzeige-Tabelle (ASCII-Attributwert -> Sivas-Klartext mit
|
||||
# Umlauten) UND SEPARATOR_BEARBEITUNG_ANZEIGE bleiben eigene, kleine
|
||||
# Abschnitte weiter unten.
|
||||
# Anzeige-Tabellen (ASCII-Attributwert -> Sivas-Klartext/Optionswert:
|
||||
# [geruest_typ_anzeige], [as_es_winkel_anzeige]) UND
|
||||
# SEPARATOR_BEARBEITUNG_ANZEIGE bleiben eigene, kleine Abschnitte weiter
|
||||
# unten.
|
||||
#
|
||||
# [gefaellestrecke] und [variofoerderer] fuehren die AS-/ES-Merkmale
|
||||
# (4427-4432) absichtlich DOPPELT: GF_N- und VF_N-Bloecke tragen dieselben
|
||||
# Attribute des gemeinsamen Strecken-Schemas, und jeder Abschnitt soll fuer
|
||||
# sich lesbar bleiben. Aenderungen dort bitte in beiden nachziehen (der Test
|
||||
# tests/test_export_sivas_as_es.py::test_zuordnung_steht_in_der_config wacht
|
||||
# darueber).
|
||||
# ============================================================
|
||||
|
||||
[gefaellestrecke]
|
||||
2950= MONTAGEHOEHE_m : 0
|
||||
# AS-/ES-Element, Reihenfolge wie die Sivas-Hierarchie (identisch in
|
||||
# [variofoerderer]): 4431/4432 Ja/Nein schalten Winkel und Seite frei.
|
||||
4431= WINKEL_AS : | as_es_vorhanden
|
||||
4427= WINKEL_AS : | as_es_winkel
|
||||
4428= SEITE_AS : | as_seite
|
||||
4432= WINKEL_ES : | as_es_vorhanden
|
||||
4429= WINKEL_ES : | as_es_winkel
|
||||
4430= SEITE_ES : | es_seite
|
||||
4384= : Gefällestrecke
|
||||
4318= L_GF_m
|
||||
4391= GF_WINKEL
|
||||
@@ -79,12 +105,55 @@
|
||||
[geruest]
|
||||
Farbe= FARBE
|
||||
|
||||
[kettenfoerderer]
|
||||
# Kettenfoerderer / Schraegfoerderer Stahl (KF_n, Lisp/KettenFoerderer.lsp).
|
||||
# Merkmalnummern laut Merkmalstamm des Schraegfoerderers.
|
||||
#
|
||||
# 350 kommt aus FOERDERERTYP (Bauart im Klartext). Der Default greift nur
|
||||
# bei Altbestands-Bloecken ohne das Attribut.
|
||||
# 359 kommt aus WINKEL, das den Neigungswinkel als nackte Zahl fuehrt
|
||||
# ("26"/"30"); die Anzeige-Tabelle [kf_typ_anzeige] weiter unten macht
|
||||
# daraus den Sivas-Optionstext mit Gradzeichen. Grund fuer die
|
||||
# Zweiteilung: Block-Attribute bleiben laut Projektkonvention ASCII.
|
||||
# 353 (Anzahl der gleichen KF) steht ABSICHTLICH NICHT hier: der Wert
|
||||
# entsteht erst aus der Gruppierung baugleicher Bloecke
|
||||
# (kettenfoerderer_signature in export_sivas.py) und ist damit kein
|
||||
# flaches Attribut-Mapping - gleiche Bauart wie 3510/3512 beim Kreisel.
|
||||
# 356 und 361 nutzen den vorhandenen Transform ja_nein, die Attribute
|
||||
# fuehren "1"/"0".
|
||||
# 357 "Antriebsart" ist beim Kettenfoerderer FEST (1.1 kW): im Dialog ein
|
||||
# Dropdown mit genau einer, zwingend gewaehlten Option - das Attribut gibt es trotzdem, damit der Wert am
|
||||
# Block steht und nicht nur im Export auftaucht.
|
||||
# 354 "Farbe Foerderer" und 355 "Antriebsmotor Foerderer" sind ZWEI getrennte
|
||||
# Merkmale (nicht ein kombinierter Text) - im Dialog darum auch zwei
|
||||
# Felder, Attribute FARBE und ANTRIEBSMOTOR.
|
||||
# 354/355/391 tragen bereits den vollen Sivas-Optionstext im Attribut (die
|
||||
# Auswahllisten in data/json/kettenfoerderer.json liefern ihn so) -
|
||||
# darum kein Transform.
|
||||
350= FOERDERERTYP : Schrägförderer Stahl
|
||||
359= WINKEL : 26 | kf_typ_anzeige
|
||||
361= STANDARD_STEUERUNG : 0 | ja_nein
|
||||
354= FARBE : RAL 7035
|
||||
355= ANTRIEBSMOTOR : Europa 50 Hz
|
||||
357= ANTRIEBSART : 1.1 kW
|
||||
356= MOVIMOT : 0 | ja_nein
|
||||
360= H_EINBAUHOEHE_mm : 0
|
||||
391= VERBINDUNGSELEMENTE : Nein
|
||||
|
||||
[variofoerderer]
|
||||
# Nur die von der Segmentanzahl UNABHAENGIGEN Top-Level-Felder einer VF_N-
|
||||
# Streckengruppe (siehe build_variofoerderer_details in export_sivas.py).
|
||||
# Die Gefaelle-/Vario-Segmentpaare (4312-4392, 4353/4354/4386) haengen an der
|
||||
# Listenlaenge von L_GF_m/L_VF_m und bleiben Code.
|
||||
2950= MONTAGEHOEHE_m : 0
|
||||
# AS-/ES-Element, Reihenfolge wie die Sivas-Hierarchie (identisch in
|
||||
# [gefaellestrecke]): 4431/4432 Ja/Nein schalten Winkel und Seite frei.
|
||||
4431= WINKEL_AS : | as_es_vorhanden
|
||||
4427= WINKEL_AS : | as_es_winkel
|
||||
4428= SEITE_AS : | as_seite
|
||||
4432= WINKEL_ES : | as_es_vorhanden
|
||||
4429= WINKEL_ES : | as_es_winkel
|
||||
4430= SEITE_ES : | es_seite
|
||||
4329= GF_Bogen_L_90 : 0
|
||||
4330= GF_Bogen_L_60 : 0
|
||||
4331= GF_Bogen_L_30 : 0
|
||||
@@ -103,11 +172,35 @@ Farbe= FARBE
|
||||
3992= GERUEST_EINZELMODUL : 0 | ja_nein
|
||||
3993= GERUEST_TYP : Schoenenberger Geruest | geruest_typ_anzeige
|
||||
|
||||
[as_es_winkel_anzeige]
|
||||
# Attributwert WINKEL_AS/WINKEL_ES -> Optionswert der Sivas-Auswahlliste zu
|
||||
# Merkmal 4427/4429. Im Merkmalstamm heissen die Optionen "30 °"/"90 °" (mit
|
||||
# Leerzeichen vor dem Gradzeichen) - das Attribut in der Zeichnung bleibt die
|
||||
# nackte Zahl. Gleiche Bauart wie [geruest_typ_anzeige]: steht ein Winkel
|
||||
# hier NICHT drin, wird er unveraendert uebernommen.
|
||||
#
|
||||
# >>> Falls Sivas den Import mit "30 °" ablehnt, ist DIESE Tabelle die
|
||||
# >>> einzige Stelle zum Nachziehen (z.B. auf "30°" ohne Leerzeichen oder
|
||||
# >>> auf die nackte Zahl) - der Code bleibt unberuehrt.
|
||||
30= 30 °
|
||||
90= 90 °
|
||||
|
||||
[geruest_typ_anzeige]
|
||||
# ASCII-Attributwert (GERUEST_TYP) -> Sivas-Klartext mit Umlauten/Sonder-
|
||||
# zeichen (Attribute selbst bleiben ASCII, siehe CLAUDE.md-Konvention).
|
||||
Schoenenberger Geruest= Schönenberger-Gerüst
|
||||
|
||||
[kf_typ_anzeige]
|
||||
# Attributwert WINKEL (Neigungswinkel als nackte Zahl) -> Optionswert der
|
||||
# Sivas-Auswahlliste zu Merkmal 359. Gleiche Bauart wie
|
||||
# [geruest_typ_anzeige]/[as_es_winkel_anzeige]: steht ein Wert hier NICHT
|
||||
# drin, wird er unveraendert uebernommen.
|
||||
#
|
||||
# >>> Lehnt Sivas den Import ab, ist DIESE Tabelle die einzige Stelle zum
|
||||
# >>> Nachziehen (z.B. "26 °" mit Leerzeichen) - der Code bleibt unberuehrt.
|
||||
26= Schrägförderer Stahl 26°
|
||||
30= Schrägförderer Stahl 30°
|
||||
|
||||
[weichen]
|
||||
# ILS 2.0 Weiche (6216): eine Summenzeile, Werte aus den Kreisel-Beruehr-
|
||||
# punkten des LISP-Exports (kreisel_weichen.json). Ein Beruehrpunkt ist eine
|
||||
|
||||
@@ -8,7 +8,8 @@ der Wahrheit ist der Code in `lib/export_sivas.py` - diese Datei ist ein
|
||||
Backup/Nachschlagewerk, bei Aenderungen am Code bitte hier nachziehen.
|
||||
|
||||
Stand: abgeglichen mit `lib/export_sivas.py` nach der Umstellung von
|
||||
beschreibenden JSON-Keys auf reine Merkmalnummern (Sept. 2026).
|
||||
beschreibenden JSON-Keys auf reine Merkmalnummern (Sept. 2026), ergaenzt um
|
||||
die AS-/ES-Element-Merkmale 4427-4432 (Okt. 2026).
|
||||
|
||||
## ILS 2.0 Kreisel (SivasNr 6200, Dispogruppe 20)
|
||||
|
||||
@@ -59,6 +60,7 @@ immer 1. Sivas kennt je Streckengruppe nur EIN Gefaelle-Segment-Paar
|
||||
| 4381 | Streckengruppe - Anzahl der Separatoren - Variofoerderer | `ANZAHL_SEPARATOR` | **voller Blockwert** (Aufteilung noch offen, siehe 4337) |
|
||||
| 4382 | (dieselbe Bezeichnung wie 4338 im Merkmalstamm) | - | fest `SEPARATOR_BEARBEITUNG_ANZEIGE` |
|
||||
| 4383 | Streckengruppe - Anzahl der Scanner (Vario-Anteil) | `ANZAHL_SCANNER` | **voller Blockwert** |
|
||||
| 4427-4432 | AS-/ES-Element (vorhanden/Winkel/Seite) | `WINKEL_AS`/`SEITE_AS`/`WINKEL_ES`/`SEITE_ES` | siehe eigener Abschnitt unten |
|
||||
| 3992 | Geruest fuer Einzelmodul | `GERUEST_EINZELMODUL` | wie Kreisel |
|
||||
| 3993 | Geruestoption fuer Einzelmodul | `GERUEST_TYP` | wie Kreisel |
|
||||
|
||||
@@ -86,9 +88,56 @@ Stueckzahl der Gruppe steht im Merkmal 4311.
|
||||
| 4337 | Streckengruppe - Anzahl der Separatoren - Gefaellestrecke | `ANZAHL_SEPARATOR` | direkt (kein Split noetig, kein Vario-Anteil vorhanden) |
|
||||
| 4338 | Streckengruppe - Bearbeitung Gefaellestreckenteilstueck fuer Separator (829516050) | - | fest `SEPARATOR_BEARBEITUNG_ANZEIGE` |
|
||||
| 4339 | Streckengruppe - Anzahl der Scanner | `ANZAHL_SCANNER` | direkt |
|
||||
| 4427-4432 | AS-/ES-Element (vorhanden/Winkel/Seite) | `WINKEL_AS`/`SEITE_AS`/`WINKEL_ES`/`SEITE_ES` | siehe eigener Abschnitt unten |
|
||||
| 3992 | Geruest fuer Einzelmodul | `GERUEST_EINZELMODUL` | wie Kreisel |
|
||||
| 3993 | Geruestoption fuer Einzelmodul | `GERUEST_TYP` | wie Kreisel |
|
||||
|
||||
Die Gruppierung (`gefaellestrecke_signature`) beruecksichtigt AS-/ES-Element
|
||||
mit: zwei sonst baugleiche Gefaellestrecken mit AS links bzw. AS rechts
|
||||
bleiben getrennte Zeilen, sonst zeigte die gemeinsame Zeile nur die Seite des
|
||||
ersten Blocks.
|
||||
|
||||
## AS-/ES-Element (4427-4432) - gilt fuer VF_N UND GF_N
|
||||
|
||||
Die Zuordnung steht vollstaendig in `cfg/sivas.cfg` - mit denselben sechs
|
||||
Zeilen in `[gefaellestrecke]` UND `[variofoerderer]`, weil beide Blockarten
|
||||
dieselben Attribute des gemeinsamen Strecken-Schemas tragen
|
||||
(`*strecke-attr-front*` in `ssg_core.lsp`). In `export_sivas.py` stehen nur
|
||||
die Transform-Funktionen.
|
||||
|
||||
Sivas-Hierarchie (Merkmalstamm): 4431/4432 (`"Ja"`/`"Nein"`) sind die
|
||||
Oberknoten, Winkel und Seite haengen als Unterknoten darunter - darum auch
|
||||
diese Reihenfolge in der Config.
|
||||
|
||||
| Merkmalnr | Bezeichnung (Merkmalstamm) | Block-Attribut | Transform | Berechnung |
|
||||
|---|---|---|---|---|
|
||||
| 4431 | AS-Element | `WINKEL_AS` | `as_es_vorhanden` | `"Ja"`, wenn ein Winkel gesetzt ist, sonst `"Nein"` |
|
||||
| 4427 | AS-Element - Winkel | `WINKEL_AS` | `as_es_winkel` | Optionswert der Auswahlliste (`"30"` -> `"30 °"`, Tabelle `[as_es_winkel_anzeige]`); leer, wenn kein AS-Element |
|
||||
| 4428 | AS-Element - Seite | `SEITE_AS` | `as_seite` | kleingeschrieben (`"links"`/`"rechts"`); leer, wenn kein AS-Element |
|
||||
| 4432 | ES-Element | `WINKEL_ES` | `as_es_vorhanden` | wie 4431 |
|
||||
| 4429 | ES-Element - Winkel | `WINKEL_ES` | `as_es_winkel` | wie 4427 |
|
||||
| 4430 | ES-Element - Seite | `SEITE_ES` | `es_seite` | wie 4428 |
|
||||
|
||||
**Warum der Winkel ueber das Vorhandensein entscheidet und nicht die Seite:**
|
||||
das Schema laesst `WINKEL_AS`/`WINKEL_ES` leer, wenn kein Element gewaehlt
|
||||
wurde, waehrend `SEITE_AS`/`SEITE_ES` mit `"rechts"` immer einen Vorgabewert
|
||||
tragen. Ohne Element bleiben darum Winkel UND Seite leer - sonst stuende in
|
||||
Sivas eine Seite unter einem `"Nein"`-Knoten.
|
||||
|
||||
**Winkel-Schreibweise:** die Sivas-Auswahlliste fuehrt `"30 °"`/`"90 °"` (mit
|
||||
Leerzeichen vor dem Gradzeichen), das Block-Attribut dagegen die nackte Zahl.
|
||||
Die Uebersetzung steht als Tabelle `[as_es_winkel_anzeige]` in `sivas.cfg`
|
||||
(gleiche Bauart wie `[geruest_typ_anzeige]`) - weicht Sivas davon ab, ist das
|
||||
die einzige Stelle zum Nachziehen. Ein Winkel ohne Eintrag dort wird
|
||||
unveraendert uebernommen.
|
||||
|
||||
**Neu im Mapping-Mechanismus:** `4428`/`4430` brauchen ein ZWEITES Attribut
|
||||
(die Seite haengt am Winkel). Dafuer gibt es in `sivas_mapping.py` den
|
||||
Dekorator `@braucht_attribs` - ein so markierter Transform wird als
|
||||
`fn(wert, attribs)` statt `fn(wert)` aufgerufen und sieht damit die uebrigen
|
||||
Attribute des Blocks. Ohne diese Klammer muessten bedingte Merkmale wieder
|
||||
als Python-Code aus der Config herauswandern.
|
||||
|
||||
## ILS 2.0 Zusatzmodul (SivasNr 6215, Dispogruppe 20)
|
||||
|
||||
BTMT-Beladestationen UND Abwurfstationen (Klammerbuegel-Entladung) in EINER
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"kettenfoerderer": {
|
||||
"id": "Kettenfoerderer",
|
||||
"titel": "Kettenfoerderer (Schraegfoerderer Stahl)",
|
||||
"layer": "kettenfoerderer",
|
||||
"teileart": "Schraegfoerderer Stahl",
|
||||
"foerderertyp": "Schrägförderer Stahl",
|
||||
|
||||
"einbauhoehe": { "vorgabe": 1500, "min": 300, "max": 8000 },
|
||||
"laenge": { "min": 100, "max": 20000 },
|
||||
|
||||
"_hinweis_ansicht": "KF_2D liegt DECKUNGSGLEICH mit der Kette (KS_EIN auf KS_EIN der Umlenkung, KS_AUS auf KS_AUS des Antriebs) - die Baugruppe ist EIN Koerper. Den frueheren Versatz (versatz_y) gibt es nicht mehr, seit die Kette aufgerichtet eingebaut wird.",
|
||||
"ansicht_2d": { "block": "KF_2D" },
|
||||
|
||||
"_hinweis_antriebsart": "Merkmal 357 ist beim Kettenfoerderer FEST: die Liste hat genau EINEN Eintrag, der im Dialog als Dropdown erscheint und zwingend gewaehlt ist. Weitere Antriebsarten (z.B. 0.55 kW) waeren einfach eine weitere Zeile.",
|
||||
"antriebsart": [
|
||||
{ "name": "1.1 kW", "wert": "1.1 kW" }
|
||||
],
|
||||
|
||||
"farbe": [
|
||||
{ "name": "RAL 7035", "wert": "RAL 7035" },
|
||||
{ "name": "RAL 2000", "wert": "RAL 2000" },
|
||||
{ "name": "RAL 5018", "wert": "RAL 5018" },
|
||||
{ "name": "Sonderfarbe", "wert": "Sonderfarbe" }
|
||||
],
|
||||
|
||||
"antriebsmotor": [
|
||||
{ "name": "Europa 50 Hz", "wert": "Europa 50 Hz" }
|
||||
],
|
||||
|
||||
"movimot": [
|
||||
{ "name": "Nein", "wert": "0" },
|
||||
{ "name": "Ja", "wert": "1" }
|
||||
],
|
||||
|
||||
"standard_steuerung": [
|
||||
{ "name": "Nein", "wert": "0" },
|
||||
{ "name": "Ja", "wert": "1" }
|
||||
],
|
||||
|
||||
"verbindungselemente": [
|
||||
{ "name": "Verbindungselemente an AP", "wert": "Verbindungselemente an AP" },
|
||||
{ "name": "Verbindungselemente an ST", "wert": "Verbindungselemente an ST" },
|
||||
{ "name": "Nein", "wert": "Nein" }
|
||||
],
|
||||
|
||||
"varianten": [
|
||||
{
|
||||
"name": "Schraegfoerderer Stahl 26 Grad",
|
||||
"winkel": 26,
|
||||
"standard": true,
|
||||
"block_umlenkung": "KF_UM_26",
|
||||
"block_laenge": "KF_LAENGE",
|
||||
"block_antrieb": "KF_AN_26",
|
||||
"sivas_id": "6120"
|
||||
},
|
||||
{
|
||||
"name": "Schraegfoerderer Stahl 30 Grad",
|
||||
"winkel": 30,
|
||||
"block_umlenkung": "KF_UM_30",
|
||||
"block_laenge": "KF_LAENGE",
|
||||
"block_antrieb": "KF_AN_30",
|
||||
"sivas_id": "6120"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,104 @@
|
||||
// ============================================================
|
||||
// kettenfoerderer.dcl - Kettenfoerderer (Schraegfoerderer Stahl)
|
||||
// Verwendet von KettenFoerderer.lsp (kf-dialog, Befehl KETTENFOERDERER).
|
||||
//
|
||||
// VORLAGE mit Markerzeilen: nur der Varianten-Block ist datenabhaengig und
|
||||
// wird zur Laufzeit an //@VARIANTEN@ eingesetzt (kf-dcl-ersetzungen ->
|
||||
// ssg-dcl-vorlage-fuellen in ssg_core, Temp-Datei). Grund: DCL kann
|
||||
// radio_button-Tiles weder zur Laufzeit erzeugen noch ihre Labels per
|
||||
// set_tile aendern - gleiches Vorgehen wie geruest_traeger.dcl.
|
||||
//
|
||||
// Varianten bewusst als Radiobuttons statt popup_list: es sind nur zwei
|
||||
// Werte (26/30 Grad), beide sollen ohne Aufklappen sichtbar sein.
|
||||
// Die Gruppenbeschriftung steht am boxed_row - ein zusaetzliches Label am
|
||||
// Tile waere doppelt gemoppelt.
|
||||
//
|
||||
// Die Beschriftungen folgen dem Sivas-Merkmalstamm, damit Dialog und
|
||||
// Stueckliste dieselbe Sprache sprechen (Merkmalnummer in Klammern):
|
||||
// Schraegfoerderer Stahl Typ (359) H - Einbauhoehe Schraegfoerderer (360)
|
||||
// Farbe Foerderer (354) Antriebsmotor Foerderer (355)
|
||||
// Antrieb mit Movimot (356) Verbindungselemente (391)
|
||||
// Farbe und Antriebsmotor sind dabei ZWEI eigenstaendige Merkmale
|
||||
// (Attribute FARBE und ANTRIEBSMOTOR), nicht ein kombinierter Text.
|
||||
//
|
||||
// Kein Geruest-Bereich: der Kettenfoerderer traegt sich selbst.
|
||||
// ============================================================
|
||||
|
||||
kettenfoerderer : dialog {
|
||||
label = "Kettenfoerderer";
|
||||
width = 62;
|
||||
|
||||
: boxed_radio_row {
|
||||
key = "variante";
|
||||
label = "Schraegfoerderer Stahl Typ";
|
||||
//@VARIANTEN@
|
||||
}
|
||||
|
||||
: boxed_column {
|
||||
label = "Geometrie";
|
||||
|
||||
: row {
|
||||
: edit_box {
|
||||
key = "hoehe";
|
||||
label = "H - Einbauhoehe Schraegfoerderer [ mm ]:";
|
||||
edit_width = 12;
|
||||
}
|
||||
// Zweite Eingabeart: Hoehe aus zwei gewaehlten Punkten messen.
|
||||
// Der Knopf schliesst den Dialog (done_dialog 2), der Aufrufer pickt
|
||||
// die Punkte und zeigt ihn mit dem Ergebnis erneut - aus einem
|
||||
// action_tile heraus laesst sich kein getpoint aufrufen.
|
||||
: button {
|
||||
key = "hoehe_messen";
|
||||
label = "aus 2 Punkten messen";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
: boxed_column {
|
||||
label = "Ausfuehrung";
|
||||
|
||||
// Reihenfolge wie im Sivas-Merkmalstamm: 361 vor 354 - Dialog,
|
||||
// Attributschema und Merkmalstamm bleiben damit in derselben Folge.
|
||||
: popup_list {
|
||||
key = "standard_steuerung";
|
||||
label = "mit Standard Steuerung:";
|
||||
width = 40;
|
||||
}
|
||||
|
||||
: popup_list {
|
||||
key = "farbe";
|
||||
label = "Farbe Foerderer:";
|
||||
width = 40;
|
||||
}
|
||||
|
||||
: popup_list {
|
||||
key = "antriebsmotor";
|
||||
label = "Antriebsmotor Foerderer:";
|
||||
width = 40;
|
||||
}
|
||||
|
||||
// Antriebsart (Merkmal 357): Dropdown mit genau EINER Option, die immer
|
||||
// gewaehlt ist - beim Kettenfoerderer ist sie fest 1.1 kW. Als Dropdown
|
||||
// statt als Textzeile, damit alle Merkmale gleich aussehen; kommt spaeter
|
||||
// eine zweite Antriebsart dazu, ist es nur eine weitere Zeile in der JSON.
|
||||
: popup_list {
|
||||
key = "antriebsart";
|
||||
label = "Antriebsart 0,55 / 1,1 kW:";
|
||||
width = 40;
|
||||
}
|
||||
|
||||
: popup_list {
|
||||
key = "movimot";
|
||||
label = "Antrieb mit Movimot:";
|
||||
width = 40;
|
||||
}
|
||||
|
||||
: popup_list {
|
||||
key = "verbindung";
|
||||
label = "Verbindungselemente:";
|
||||
width = 40;
|
||||
}
|
||||
}
|
||||
|
||||
ok_cancel;
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
// ============================================================
|
||||
// stueckliste.dcl - Optionen fuer Positionen + Stueckliste
|
||||
// Aufruf ueber c:SSG_FAEHNCHEN_STUECKLISTE (Lisp/ssg_stueckliste.lsp,
|
||||
// ssg-sl-dialog). Vorbelegung aus cfg/stueckliste.json bzw. dem letzten Lauf.
|
||||
// ============================================================
|
||||
|
||||
stueckliste : dialog {
|
||||
label = "Positionen + Stueckliste";
|
||||
|
||||
: boxed_column {
|
||||
label = "Layer der Positionen";
|
||||
: radio_column {
|
||||
key = "modus";
|
||||
: radio_button { key = "m_suffix"; label = "Bauteil-Layer + Suffix"; }
|
||||
: radio_button { key = "m_fest"; label = "Fester Layer"; }
|
||||
}
|
||||
: edit_box { key = "suffix"; label = "Suffix:"; edit_width = 20; }
|
||||
: edit_box { key = "fest"; label = "Fester Layer:"; edit_width = 20; }
|
||||
: text { label = "Regeln je Bauteiltyp: cfg/stueckliste.json"; }
|
||||
}
|
||||
|
||||
: boxed_column {
|
||||
label = "Stueckliste";
|
||||
: edit_box { key = "tab_layer"; label = "Tabellen-Layer:"; edit_width = 20; }
|
||||
: edit_box { key = "titel"; label = "Titel:"; edit_width = 30; }
|
||||
}
|
||||
|
||||
: boxed_column {
|
||||
label = "Nummerierung / Darstellung";
|
||||
: edit_box { key = "startnr"; label = "Erste Positionsnummer:"; edit_width = 10; }
|
||||
: edit_box { key = "faktor"; label = "Massstabsfaktor:"; edit_width = 10; }
|
||||
: toggle { key = "alle_pos";
|
||||
label = "Alle Positionen in der Fahne (100|101|...), jede Art.-Nr. nummeriert"; }
|
||||
}
|
||||
|
||||
: errtile { key = "error"; }
|
||||
ok_cancel;
|
||||
}
|
||||
+114
-3
@@ -181,6 +181,84 @@ vflw_as : dialog {
|
||||
}
|
||||
}
|
||||
|
||||
// Wie vflw_as, aber ZUSAETZLICH mit der Zufuehrungsachse (2. Punkt) in
|
||||
// DEMSELBEN Bildschirm - nur fuer das AS-Element am Kettenanfang von Modus 1
|
||||
// (Nutzer-Vorgabe 2026-10-21: "Achse und links/rechts gehoeren in ein
|
||||
// Fenster", beide zusammen legen AS-Lage UND Kettenrichtung fest: der 2.
|
||||
// Punkt gibt die KS_EIN-Achse, links/rechts die AS-Variante und damit die
|
||||
// KS_AUS-Richtung). Eigener Dialog statt einer dauerhaft ausgegrauten
|
||||
// Punkt-Zeile in vflw_as - denselben Dialog nutzt auch das ES-Element am
|
||||
// Kettenende, wo es gar keine Zufuehrungsachse gibt (gleiche Begruendung wie
|
||||
// bei vflw_winkel_seite vs. vflw_winkel_seite_30_90).
|
||||
// Punktwahl-Zeile nach dem Muster von vflw_punkt_zahl: der Button schliesst
|
||||
// den Dialog (done_dialog 2), danach laeuft (getpoint) auf der
|
||||
// Kommandozeile, danach wird der Dialog neu gezeigt - darum nutzt "back"
|
||||
// hier Code 3.
|
||||
vflw_as_achse : dialog {
|
||||
label = "VarioFoerderer Assistent";
|
||||
|
||||
: column {
|
||||
: text {
|
||||
key = "kopf";
|
||||
label = "";
|
||||
width = 60;
|
||||
}
|
||||
: toggle {
|
||||
key = "setzen";
|
||||
label = "Ja, setzen";
|
||||
}
|
||||
: boxed_radio_column {
|
||||
label = "Winkel:";
|
||||
key = "winkel";
|
||||
: radio_button { key = "winkel_90"; label = "90 Grad"; value = "1"; }
|
||||
: radio_button { key = "winkel_30"; label = "30 Grad"; }
|
||||
}
|
||||
// Beschriftungen bewusst NEUTRAL: derselbe Dialog dient dem AS-Element
|
||||
// am Kettenanfang (vorwaerts) UND dem ES-Element am Kettenende
|
||||
// (rueckwaerts bauen, 2026-10-22). Welches Element gemeint ist, sagt die
|
||||
// Kopfzeile ("kopf").
|
||||
: boxed_radio_column {
|
||||
label = "Seite (Element schleust nach):";
|
||||
key = "seite";
|
||||
: radio_button { key = "seite_links"; label = "Links"; value = "1"; }
|
||||
: radio_button { key = "seite_rechts"; label = "Rechts"; }
|
||||
}
|
||||
: boxed_column {
|
||||
label = "Fahrtrichtung (2. Punkt):";
|
||||
// Startpunkt der Kette - er ist der Sitz des AS-Elements UND der
|
||||
// Ausgangspunkt der Achse; waehrend der Punktwahl haengt das
|
||||
// Gummiband an ihm (vfl-getpoint mit Basispunkt).
|
||||
: text {
|
||||
key = "start_anzeige";
|
||||
label = "";
|
||||
width = 46;
|
||||
}
|
||||
: row {
|
||||
: button {
|
||||
key = "pick";
|
||||
label = "2. Punkt waehlen...";
|
||||
fixed_width = true;
|
||||
width = 20;
|
||||
}
|
||||
: text {
|
||||
key = "pt_anzeige";
|
||||
label = "(ohne Achse: Richtung aus dem naechsten Klick)";
|
||||
width = 46;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
: row {
|
||||
alignment = centered;
|
||||
: button { key = "back"; label = "Zurueck"; fixed_width = true; width = 12; }
|
||||
spacer;
|
||||
: button { key = "accept"; label = "Ok Weiter"; is_default = true; fixed_width = true; width = 12; }
|
||||
spacer;
|
||||
: button { key = "cancel"; label = "Abbrechen"; is_cancel = true; fixed_width = true; width = 12; }
|
||||
}
|
||||
}
|
||||
|
||||
// Winkel (30/60/90) + Seite - fuer GF-Bogen, wo alle drei Winkel geometrisch
|
||||
// gueltig sind. Fuer AS-/ES-Element (wo 60 Grad NIE gueltig ist) stattdessen
|
||||
// vflw_winkel_seite_30_90 verwenden (siehe vflw-gruppe-winkel-seite-impl/
|
||||
@@ -402,6 +480,12 @@ vflw_gf_laenge_modus : dialog {
|
||||
: radio_button { key = "modus_hoehe"; label = "Zielhoehe festlegen (Laenge wird berechnet)"; }
|
||||
: radio_button { key = "modus_steigend"; label = "Steigende GF (Sonderfall, bis 3 Grad)"; }
|
||||
: radio_button { key = "modus_qc"; label = "QC Linie mit GF (automatische Auf-Ab-Berechnung)"; }
|
||||
// Nur am Kettenanfang mit AS-Element UND festgelegter Zufuehrungsachse
|
||||
// waehlbar - sonst fehlt die Bezugsachse fuer den Abstand. Wird in
|
||||
// vflw-gruppe-gf-laenge-modus-impl per mode_tile deaktiviert (anders
|
||||
// als eine NIE waehlbare Kachel ist diese kontextabhaengig, siehe
|
||||
// "sepnach" in vflw_sep_gf).
|
||||
: radio_button { key = "modus_parallel"; label = "Parallel zum Kreisel weiterbauen (Abstand)"; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,10 +547,20 @@ vflw_sep_gf : dialog {
|
||||
key = "sepvor";
|
||||
label = "Separator VOR dieser Gefaellestrecke";
|
||||
}
|
||||
// Steht am Kettenende ein ES-Element, ist "Separator NACH" gesperrt -
|
||||
// der Hinweis dahinter sagt warum, in EINER Zeile mit dem Ankreuzfeld
|
||||
// (gleiche Anordnung wie in vflw_seg_linie_m2). Sonst leer (set_tile "").
|
||||
: row {
|
||||
: toggle {
|
||||
key = "sepnach";
|
||||
label = "Separator NACH dieser Gefaellestrecke";
|
||||
}
|
||||
: text {
|
||||
key = "sephinweis";
|
||||
label = "";
|
||||
width = 62;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
: row {
|
||||
@@ -1006,7 +1100,13 @@ vflw_seg_linie_m2 : dialog {
|
||||
: boxed_column {
|
||||
label = "Separator (nur bei GF):";
|
||||
: toggle { key = "sep_vor"; label = "Separator VOR diesem GF-Stueck"; }
|
||||
// Begruendung, wenn "NACH" gesperrt ist (ES folgt direkt), in EINER
|
||||
// Zeile hinter dem Ankreuzfeld - sonst liest sie sich wie eine eigene
|
||||
// Aussage statt wie die Erklaerung zu genau diesem Feld. Sonst leer.
|
||||
: row {
|
||||
: toggle { key = "sep_nach"; label = "Separator NACH diesem GF-Stueck"; }
|
||||
: text { key = "sephinweis"; label = ""; width = 62; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1116,13 +1216,24 @@ vflw_m2_lauf_anfang : dialog {
|
||||
label = "";
|
||||
width = 60;
|
||||
}
|
||||
// Reihenfolge nach Haeufigkeit (Nutzer-Wunsch 2026-10-23): der
|
||||
// Regelfall zuerst, der Sonderfall "offener Anfang" zuletzt. Die
|
||||
// radio_button-KEYS bleiben dabei unveraendert; journalisiert wird der
|
||||
// am Key haengende WERT ("mit-gf1"/"direkt"/"ohne", siehe
|
||||
// vfl-m2-anfang-norm), nicht die Position - Umsortieren und Umnummerieren
|
||||
// sind damit folgenlos fuer bestehende Ketten.
|
||||
: boxed_radio_column {
|
||||
label = "Lauf beginnen mit:";
|
||||
key = "anfang";
|
||||
: radio_button { key = "anfang_offen"; label = "Ohne Umlenkstation (offener Anfang, spaeter fortsetzen)"; }
|
||||
: radio_button { key = "anfang_umlenk"; label = "Umlenkstation direkt (kein GF1/Separator)"; }
|
||||
: radio_button { key = "anfang_umlenk_gf1"; label = "Umlenkstation mit GF1 + Separator"; value = "1"; }
|
||||
// Nummern wie in der Konsolenausgabe, damit Dialog und Protokoll
|
||||
// dieselbe Option gleich benennen.
|
||||
: radio_button { key = "anfang_umlenk_gf1"; label = "1 - Umlenkstation mit GF1 + Separator"; value = "1"; }
|
||||
: radio_button { key = "anfang_umlenk"; label = "2 - Umlenkstation direkt (kein GF1/Separator)"; }
|
||||
: radio_button { key = "anfang_offen"; label = "3 - Ohne Umlenkstation (offener Anfang, spaeter fortsetzen/verschmelzen)"; }
|
||||
}
|
||||
// Begruendung, wenn "Ohne Umlenkstation" gesperrt ist (AS gesetzt).
|
||||
// Breit genug fuer den vollen Satz - bei width = 60 wurde er abgeschnitten.
|
||||
: text { key = "anfanghinweis"; label = ""; width = 76; }
|
||||
}
|
||||
|
||||
ok_cancel;
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
# Datenaufbereitung der CAD-Bausteine
|
||||
|
||||
Kurzanleitung fuer alle, die neue CAD-Modelle (DWG/DXF-Bausteine) fuer die
|
||||
SSG_LIB-Makros anlegen oder bestehende ersetzen.
|
||||
|
||||
Hier finden Sie Antworten auf folgende Fragen:
|
||||
|
||||
1. [Wo sind Koordinatensysteme anzusetzen?](#1-wo-sind-koordinatensysteme-anzusetzen)
|
||||
2. [Wie muessen sie heissen?](#2-wie-muessen-die-koordinatensysteme-heissen)
|
||||
3. [Wie werden 3D-Modelle anhand der 2.5D-Skelette platziert?](#3-grundidee-platzierung-ueber-das-25d-skelett)
|
||||
4. [Wo und wie werden die Dateien abgelegt?](#4-datenablage-und-benennung)
|
||||
|
||||
Am Ende steht eine [Checkliste](#5-checkliste-fuer-ein-neues-modell).
|
||||
|
||||
---
|
||||
|
||||
## 1. Wo sind Koordinatensysteme anzusetzen?
|
||||
|
||||
Ein Koordinatensystem (KS) markiert einen **Anschlusspunkt**: die Stelle, an
|
||||
der ein Baustein an seinen Vorgaenger bzw. Nachfolger andockt. Es sitzt
|
||||
immer **auf der Mittellinie der Foerderstrecke** (dem Skelett, siehe
|
||||
Abschnitt 3), genau am Uebergang zum Nachbarteil.
|
||||
|
||||
**Aufbau eines KS** - ein kleiner Block mit drei LINEs, alle ab demselben
|
||||
Ursprung:
|
||||
|
||||
| Achse | Farbe | Laenge | Richtung |
|
||||
|---|---|---|---|
|
||||
| X | rot (1) | 1 | Foerderrichtung (bzw. Anschlussrichtung, siehe unten) |
|
||||
| Y | gruen (3) | 2 | quer dazu, nach links |
|
||||
| Z | blau (5) | 3 | nach oben, aus der Zeichenebene |
|
||||
|
||||
Die Makros erkennen die Achsen **nur an der Linienlaenge** (1 = X, 2 = Y,
|
||||
3 = Z; X darf auch 100 lang sein). Farben dienen nur der Lesbarkeit. Der
|
||||
KS-Block liegt auf Layer `_KOORDINATENSYSTEME` und muss **direkt** (eine
|
||||
Ebene tief) im Baustein eingefuegt sein, nicht in einem weiteren Unterblock.
|
||||
|
||||
### ILS-Kettenbausteine (Vario, Gefaelle, AS/ES, Staustrecke, Separator ...)
|
||||
|
||||
- **`KS_EIN`** am Einlauf, **`KS_AUS`** am Auslauf.
|
||||
- Bei **beiden** zeigt die X-Achse **in Foerderrichtung**. Beim Verketten
|
||||
kommt das `KS_EIN` des Nachfolgers auf das `KS_AUS` des Vorgaengers; die
|
||||
Richtung des Folgebausteins wird aus der X-Achse von `KS_AUS` gemessen
|
||||
(z.B. beim Kettenfoerderer).
|
||||
- Laengenvariable Teile (Staustrecke, `KF_LAENGE`) liegen entlang **+X** und
|
||||
werden in X skaliert - `KS_EIN` bei X=0, `KS_AUS` am Ende der
|
||||
Referenzlaenge (z.B. 1000 mm).
|
||||
|
||||
### Omniflo-Boegen und -Weichen
|
||||
|
||||
- Anschluss-KS heissen **`K1` bis `K4`**. Die X-Achse zeigt jeweils **in
|
||||
das Element hinein** (tangential zur Linie).
|
||||
- Zuordnung:
|
||||
|
||||
| KS | Boegen | Weichen |
|
||||
|---|---|---|
|
||||
| K1 | Beginn der obersten waagerechten Linie, X nach rechts | Beginn der untersten senkrechten Linie, X nach oben |
|
||||
| K2 | anderes Kettenende | Ende des linken Bogenzweigs |
|
||||
| K3 | - | Ende des rechten Bogenzweigs (nur bei 2+ Boegen) |
|
||||
| K4 | - | oberes Ende der K1-Linie (nicht bei Doppel-/Dreifach-/Deltaweiche) |
|
||||
|
||||
- K1-K4 muessen nicht von Hand gezeichnet werden: `lib/set_koords.py --set-all`
|
||||
setzt sie geometrisch, vorher setzt `bin\set_einfuegepunkt.bat`
|
||||
(`lib/set_einfuegepkt.py`) den Einfuegepunkt. Details: [tools.md](tools.md).
|
||||
|
||||
### Bausteine ohne KS
|
||||
|
||||
Einzeln frei platzierte Teile (Kreisel-Raeder `AN8`/`SP8`, BTMT-Stationen,
|
||||
Scanner, Eingang/Ausgang, Geruestteile) brauchen kein KS. Hier zaehlt nur
|
||||
der **Einfuegepunkt** (Basispunkt der DWG), siehe Abschnitt 3.
|
||||
|
||||
---
|
||||
|
||||
## 2. Wie muessen die Koordinatensysteme heissen?
|
||||
|
||||
| Name | Verwendung |
|
||||
|---|---|
|
||||
| `KS_EIN` | Einlauf eines ILS-Kettenbausteins |
|
||||
| `KS_AUS` | Auslauf eines ILS-Kettenbausteins |
|
||||
| `K1` ... `K4` | Anschluesse von Omniflo-Boegen/-Weichen |
|
||||
|
||||
- Genau diese Schreibweise, **ohne** `_2D`/`_3D`-Suffix (die KS-Bloecke sind
|
||||
dimensionsunabhaengig und in 2D- und 3D-Variante identisch).
|
||||
- Je Baustein jedes KS **nur einmal**.
|
||||
- `KSYS_EIN`/`KSYS_AUS` werden aus Altbestaenden noch gelesen, fuer neue
|
||||
Modelle aber nicht mehr verwenden.
|
||||
|
||||
---
|
||||
|
||||
## 3. Grundidee: Platzierung ueber das 2.5D-Skelett
|
||||
|
||||
**Skelett** = die Mittellinie der Foerderstrecke als einfache Linien/Boegen.
|
||||
"2.5D", weil es eine flache Grundriss-Geometrie ist, deren Punkte zusaetzlich
|
||||
eine Hoehe (Z) tragen - keine echte 3D-Konstruktion.
|
||||
|
||||
Das Prinzip hat zwei Seiten:
|
||||
|
||||
**a) Im Baustein selbst** ist das Skelett die Bezugsgeometrie:
|
||||
|
||||
- Die 2D-Variante *ist* das Skelett (plus Symbolik).
|
||||
- Das 3D-Modell enthaelt **dieselben 2D-Skelettlinien** in seiner
|
||||
Grundebene. Einfuegepunkt und KS liegen auf diesem Skelett - deshalb
|
||||
sind sie in 2D- und 3D-Variante **deckungsgleich** und die Varianten
|
||||
beliebig austauschbar. Die Omniflo-Werkzeuge (`set_einfuegepkt.py`,
|
||||
`set_koords.py`) werten genau diese Skelettlinien aus; ohne sie
|
||||
funktionieren sie bei 3D-Dateien nicht.
|
||||
- Gezeichnet wird in der Lage "Foerderrichtung = +X, Z nach oben". Einzige
|
||||
Ausnahme: aufrecht eingebaute Teile wie der Kettenfoerderer (`KF_*`)
|
||||
sind in XY gezeichnet (Y = Hoehe) und werden vom Makro aufgerichtet.
|
||||
|
||||
**b) In der Anlage** liefert der Anwender bzw. das Makro das Skelett
|
||||
(geklickte Punkte, gezeichneter Linienzug, Hoehen). Die Makros setzen die
|
||||
Bausteine darauf nacheinander:
|
||||
|
||||
1. `KS_EIN` des Bausteins auf den aktuellen Skelettpunkt legen.
|
||||
2. Drehen: um Z nach der Grundriss-Richtung des Segments, um Y nach dessen
|
||||
Neigung (Rz * Ry).
|
||||
3. Laengenteile in X auf die Segmentlaenge skalieren.
|
||||
4. Weltlage von `KS_AUS` lesen = Startpunkt des naechsten Bausteins.
|
||||
|
||||
Freistehende Teile ohne KS werden nur mit Einfuegepunkt + Drehung gesetzt
|
||||
(z.B. `AN8` mit dem Basispunkt in der Radmitte).
|
||||
|
||||
Weil 3D-Modell und 2D-Symbol am selben Skelett haengen, kann jede Anlage
|
||||
wahlweise in 2D oder 3D aufgebaut und spaeter umgeschaltet werden.
|
||||
|
||||
---
|
||||
|
||||
## 4. Datenablage und Benennung
|
||||
|
||||
Grundregeln:
|
||||
|
||||
- **Eine Datei je Baustein**, Dateiname = Blockname.
|
||||
- Namen nur **ASCII, ohne Umlaute und Leerzeichen** (`ae`/`oe`/`ue`, `_`
|
||||
als Trenner).
|
||||
- Der Basispunkt der DWG ist der Einfuegepunkt (s. Abschnitt 3).
|
||||
|
||||
| Bereich | Ablage | Benennung |
|
||||
|---|---|---|
|
||||
| ILS (Kreisel, Vario, Gefaelle, AS/ES, Stationen, Sensoren) | `data/ils/` **flach** | `<Name>_2D.dwg` und `<Name>_3D.dwg`, z.B. `AS_Element_30_links_3D.dwg`. Fehlt die 2D-Datei, wird automatisch die 3D-Datei genommen |
|
||||
| Omniflo-Boegen/-Weichen | `data/omniflo/2D/` bzw. `data/omniflo/3D/` | Sivas-Nummer, `.dxf`, z.B. `821104024.dxf`; Kombinationen mit `+`, z.B. `821104024+0_B10081.dxf` |
|
||||
| Omniflo-Verbinder | `data/omniflo/Verbinder/` | dimensionsunabhaengig, z.B. `TV_AP60-ST_kpl.dwg` |
|
||||
| Kettenfoerderer | `data/omniflo/2D/` | ohne Suffix: `KF_UM_26`, `KF_AN_30`, `KF_LAENGE`, `KF_2D` |
|
||||
| Geruest | `data/geruest/` | Artikelnummer, z.B. `821006031.dwg`; Platzhalter `dummy_*.dwg` |
|
||||
| DIN-Rahmen/Schriftkoepfe | `cfg/rahmen/` | `A0.DWG` ... `Kopf11.dwg` |
|
||||
|
||||
**Zugehoerige Daten** (Masse, Sivas-/Artikelnummern, Auswahllisten) liegen
|
||||
nicht in der DWG, sondern in `data/json/` - z.B. `omniflo_boegen.json`,
|
||||
`omniflo_weichen.json`, `geruest.json`, `kettenfoerderer.json`. Ein neues
|
||||
Omniflo- oder Geruestteil ist erst auswaehlbar, wenn es dort eingetragen ist.
|
||||
|
||||
**Attribute und Layer:**
|
||||
|
||||
- Bloecke, die nur eingefuegt werden, tragen ihren Ziel-Layer als Attribut
|
||||
**`LAYER`** (Vorgaben je Block in `data/ils/allocations.json`, z.B.
|
||||
`AN8_2D` -> `ILS_ANTR`, `AN8_3D` -> `_3D_ILS_ANTR`).
|
||||
- Ein leeres **`ID`**-Attribut mit anlegen - nur dann kann die automatische
|
||||
ID-Vergabe fuer den Export es befuellen.
|
||||
- Omniflo-Teile brauchen fuer den Export `TEILEART` (`Omniflo ...`) und
|
||||
`ARTINR`.
|
||||
- Layer/Farbe zusammengebauter Baugruppen (`KREISEL_n`, `VF_n`, `GF_n`)
|
||||
stehen nicht im Modell, sondern in `cfg/layer.cfg`.
|
||||
|
||||
---
|
||||
|
||||
## 5. Checkliste fuer ein neues Modell
|
||||
|
||||
- [ ] Dateiname nach Tabelle in Abschnitt 4, ASCII, im richtigen Ordner
|
||||
- [ ] ILS: 2D- **und** 3D-Variante, Basispunkt und KS deckungsgleich
|
||||
- [ ] 3D-Modell enthaelt die 2D-Skelettlinien
|
||||
- [ ] Foerderrichtung entlang +X, Z nach oben
|
||||
- [ ] Kettenbaustein: `KS_EIN`/`KS_AUS` direkt im Block, X in Foerderrichtung,
|
||||
Achslaengen 1/2/3
|
||||
- [ ] Omniflo: `set_einfuegepkt.py` und `set_koords.py --set-all` gelaufen,
|
||||
Kontrolle per `--show-omniflo`
|
||||
- [ ] Attribute `LAYER` und leeres `ID` vorhanden (Omniflo zusaetzlich
|
||||
`TEILEART`, `ARTINR`)
|
||||
- [ ] Eintrag in der passenden JSON unter `data/json/` bzw. `allocations.json`
|
||||
- [ ] In BricsCAD einmal ueber das Menue einfuegen/verketten und pruefen,
|
||||
dass der Anschluss sauber sitzt
|
||||
@@ -7,8 +7,7 @@ und die Treiber in `tests/test_*.lsp`, die sie lesen.
|
||||
|
||||
Die zugehoerigen LISP-Routinen mit Signaturen stehen in
|
||||
[lisp_methods.md](lisp_methods.md). Diese Seite ersetzt das fruehere
|
||||
`tests/testdata/object_data.md` (geloescht in Commit `e147b89`, auf das Code-
|
||||
Kommentare teilweise noch verweisen).
|
||||
`tests/testdata/object_data.md` (geloescht in Commit `e147b89`).
|
||||
|
||||
**Feldnamen als Python-Konstanten**: `lib/testdata_schema.py` buendelt die
|
||||
Feldnamen/festen Werte der Abschnitte 1 (Kreisel), 2 (Einzelbloecke), 3 (VF
|
||||
|
||||
+34
-7
@@ -37,7 +37,9 @@ Gross-/Kleinschreibung spielt an der Kommandozeile keine Rolle.
|
||||
| `KreiselLabelSetup` | Beschriftung einstellen (Hoehe, Farbe, Abstand, Schriftart) |
|
||||
| `KreiselLabelPos` | Versatz der Beschriftung (dx/dy) einstellen |
|
||||
| `KreiselLabelHoehe` | Texthoehe der Beschriftung einstellen |
|
||||
| `ILS_Eckrad` | Eckrad an einem Tangentenpunkt mit Richtung einfuegen |
|
||||
| `ILS_Eckrad` | Eckrad einfuegen (Dialog `eckrad_edit.dcl`, ohne GUI Konsolen-Rueckfall) |
|
||||
| `EckradEdit` | Bestehendes Eckrad per Dialog bearbeiten (auch per Doppelklick) |
|
||||
| `KREISEL_WEICHEN` | Beruehrpunkte/Weichen und Kollisionen aller Kreisel/Eckraeder gleicher Hoehe ermitteln, Marker setzen |
|
||||
|
||||
### VarioFoerderer (`VarioFoerderer.lsp` -> `vf_core`/`vf_standard`/`vf_etage`/`vf_linienzug`/`vf_spec`)
|
||||
|
||||
@@ -97,18 +99,28 @@ Gross-/Kleinschreibung spielt an der Kommandozeile keine Rolle.
|
||||
| `OMNI_WKomb_Delta_1400`, `OMNI_WKomb_Delta_1600`, `OMNI_WKomb_Star` | Weichenkombinationen (Delta, Stern) |
|
||||
| `OMNI_APBW_R400_45_140`, `OMNI_APBW_R400_675_260`, `OMNI_APBW_R550_45_77`, `OMNI_APBW_R550_45_194`, `OMNI_APBW_R550_225_360`, `OMNI_APBW_R550_225_410A`/`B`/`C`, `OMNI_APBW_R550_675_58`/`_125`/`_208`/`_360`, `OMNI_APBW_R650_90_300`, `OMNI_APBW_R750_90_200` | Boegen fuer Weichen (fest, ohne Dialog) |
|
||||
| `OMNI_TEF_UmlenkL`/`R`, `OMNI_TEF_AntriebL`/`R`, `OMNI_TEF_Gerade` | TEF-Elemente (fest, ohne Drehung) |
|
||||
| `OMNI_SCHW_400_L`/`_R`, `OMNI_SCHW_400_L_SENSORIK`/`_R_SENSORIK` | Schwenkschienen fuer Schiebetueren (Menue Spez. Streckenelemente -> Tuerloesungen) |
|
||||
| `OMNI_STOPPER`, `OMNI_SCANNER`, `OMNI_BUERSTENBREMSE` | Anbaugruppen |
|
||||
| `OMNI_TV_W_W`, `OMNI_TV_W_AP`, `OMNI_TV_W_AP60`, `OMNI_TV_W_AP110`, `OMNI_TV_W_AP110_W`, `OMNI_TV_50`, `OMNI_TV_80`, `OMNI_TV_ENDPLATTE`, `OMNI_TV_ANSCHLAG`, `OMNI_TV_MUFFE`, `OMNI_TV_A_AP110_AP60`, `OMNI_TV_A_AP60_ST`, `OMNI_TV_A_AP110_ST`, `OMNI_TV_SW_II_SW_SW`, `OMNI_TV_SW_III_AP110`, `OMNI_TV_SW_III_AP110_SW`, `OMNI_TV_SW_IV_AP60`, `OMNI_TV_SW_IV_ST` | Verbinder |
|
||||
| `OMNI_TV_W_W`, `OMNI_TV_W_AP60`, `OMNI_TV_W_AP60_KPL`, `OMNI_TV_W_AP110`, `OMNI_TV_W_AP110_W`, `OMNI_TV_50`, `OMNI_TV_80`, `OMNI_TV_ENDPLATTE`, `OMNI_TV_ANSCHLAG`, `OMNI_TV_MUFFE`, `OMNI_TV_A_AP110_AP60`, `OMNI_TV_A_AP60_ST`, `OMNI_TV_A_AP110_ST`, `OMNI_TV_SW_II_SW_SW`, `OMNI_TV_SW_I_AP110`, `OMNI_TV_SW_III_AP110_SW`, `OMNI_TV_SW_IV_AP60`, `OMNI_TV_SW_IV_ST` | Verbinder |
|
||||
| `OMNI_LADESCHLEIFE_AP110` | Ladeschleife (Dialog `omniflo_ladeschleifen.dcl`) |
|
||||
| `OMNI_KettenFoerderer` | Platzhalter (noch ohne Funktion) |
|
||||
| `OMNI_EDIT` | Omniflo-Element per Dialog bearbeiten; auch per Doppelklick |
|
||||
| `OMNI_FAHRSTRECKE` (`GeruestInsert.lsp`) | Omniflo-Fahrstrecke mit Linien-Logik wie `GERUEST_TRAEGER` (Dialog `fahrstrecke.dcl`) |
|
||||
| `OMNI_FAHRSTRECKE_BESCHRIFTEN` | Alle Fahrstrecken der Zeichnung neu beschriften |
|
||||
|
||||
### Kettenfoerderer (`KettenFoerderer.lsp`)
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
|---|---|
|
||||
| `KETTENFOERDERER` | Kettenfoerderer/Schraegfoerderer Stahl per Dialog (`kettenfoerderer.dcl`) als Block `KF_<n>` bauen; Menue Omniflo -> KettenFoerderer |
|
||||
| `KF_EDIT` | `KF_n`-Block bearbeiten und neu aufbauen; auch per Doppelklick |
|
||||
| `KF_KS_PRUEFEN` | Diagnose (nicht im Menue): KS-Lage der Kettenfoerderer-Bausteine pruefen |
|
||||
|
||||
### Geruest (`GeruestInsert.lsp`)
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
|---|---|
|
||||
| `GERUEST` | Geruest-Dialog (Bereich frei waehlbar) |
|
||||
| `GERUEST_SAEULEN` / `GERUEST_ROHRABHAENGER` / `GERUEST_WANDBEFESTIGUNG` | Derselbe Dialog, im jeweiligen Bereich geoeffnet |
|
||||
| `GERUEST_SAEULEN` / `GERUEST_ROHRABHAENGER` / `GERUEST_WANDBEFESTIGUNG` | Je eigener Dialog aus der Vorlage `geruest.dcl` (keine Umschaltung zwischen den Bereichen) |
|
||||
| `GERUEST` | Ohne Bereich nur ein Hinweis; im Menue Platzhalter fuer den Gattertraeger |
|
||||
| `GERUEST_TRAEGER` | Rohr-Geruest-Traeger: Dialog (`geruest_traeger.dcl`), danach Start-/Endpunkt oder Laenge bis ESC/Enter |
|
||||
| `GERUEST_TRAEGER_BESCHRIFTEN` | Alle Traeger der Zeichnung neu beschriften, verwaiste Beschriftungen entfernen |
|
||||
|
||||
@@ -120,6 +132,7 @@ Gross-/Kleinschreibung spielt an der Kommandozeile keine Rolle.
|
||||
| `TRO_EDIT` | ID/TYPE eines TRO-Markers per Dialog aendern |
|
||||
| `CONNECTION_INSERT` | Verbindungspfeil (Fluss) zwischen zwei Elementen zeichnen |
|
||||
| `CONNECTION_EDIT` | Quelle/Ziel einer Verbindung aendern |
|
||||
| `JAM_EDIT` (`Jam_Edit.lsp`) | Staubereich (`JAM_AREA` aus sps_skel) bearbeiten: Foerderer und laufende Nummer; auch per Doppelklick |
|
||||
|
||||
### Export und IDs (`export.lsp`, `ssg_id.lsp`, `count_sep_scan.lsp`, `check_hoehen.lsp`)
|
||||
|
||||
@@ -145,9 +158,22 @@ Gross-/Kleinschreibung spielt an der Kommandozeile keine Rolle.
|
||||
| `DRAW_PLANQUADRATE` | Planquadrat-Raster (Block `ZZ_PLANQUADRATE`) zeichnen bzw. neu aufbauen |
|
||||
| `DELETE_PLANQUADRATE` | Planquadrat-Raster entfernen |
|
||||
| `PLANQUADRATE_TOGGLE` | Raster an/aus (zeichnen, falls keins existiert, sonst entfernen) |
|
||||
| `SSG_BLOCKEDIT` | Doppelklick-/Kontextmenue-Dispatcher: Kreisel, Omniflo, GF_*, VF_*, GR_*, TRO_* auf den passenden Edit-Befehl |
|
||||
| `SSG_BLOCKEDIT` | Doppelklick-/Kontextmenue-Dispatcher: Kreisel, Eckrad, Omniflo, GF_*, VF_*, KF_*, GR_*, TRO_*, JAM_* auf den passenden Edit-Befehl |
|
||||
| `EATTEDIT` | Ueberschreibt den nativen Befehl, leitet an `SSG_BLOCKEDIT` weiter (Fallback `_.EATTEDIT`) |
|
||||
|
||||
### Werkzeuge (`ssg_blocktools.lsp`, `ssg_texttools.lsp`, `ssg_stueckliste.lsp`, `DinFormate.lsp`)
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
|---|---|
|
||||
| `SSG_BLOCK_COUNT` | Blockeinfuegungen im aktuellen Layout zaehlen (Pick, Muster oder Statistik) |
|
||||
| `SSG_BLOCK_DELETE` | Alle Einfuegungen eines Blocks loeschen (mit Rueckfrage) |
|
||||
| `SSG_ATTR_ERSETZEN` | Attributwerte zeichnungsweit oder in einer Auswahl suchen und ersetzen |
|
||||
| `SSG_TEXT_ERSETZEN` | Suchen/Ersetzen in TEXT, MTEXT und Attributen |
|
||||
| `SSG_TEXT_PARALLEL` | Text parallel zu Linie/Polylinie/Bogen setzen |
|
||||
| `SSG_TEXT_HOEHE` / `SSG_TEXT_STIL` | Texthoehe bzw. Textstil aendern |
|
||||
| `SSG_FAEHNCHEN_STUECKLISTE` | Positions-Faehnchen und Stuecklistentabelle aus den gewaehlten Elementen der Zeichnung |
|
||||
| `DIN_FORMATE` | DIN-Rahmen (A0-A4) und optional Schriftkopf einfuegen |
|
||||
|
||||
### Layer-Werkzeuge (`ssg_layer.lsp`)
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
@@ -202,6 +228,8 @@ Aus dem Menue "Tests" bzw. der Kommandozeile; Details in `doc/LispTests.md`.
|
||||
| `TEST_MUBEA` | Mubea-Nachbau aus `tests/testdata/mubea.json` |
|
||||
| `TEST_DEMATIC_ARVATO` | Dematic/Arvato-Nachbau (Flowpuffer/Kreisel) |
|
||||
| `TEST_SHOWROOM_ILS` | ILS-3.0-Showroom-Nachbau (Kreisel, Gefaellestrecken; Hoehen noch Platzhalter) |
|
||||
| `TEST_LASTENT` | `ssg-lastent-ohne-attribute` (kopierter Attribut-Block verliert keine Attribute) |
|
||||
| `TEST_STUECKLISTE` | Faehnchen + Stueckliste aus der Zeichnung |
|
||||
| `TEST_TEST_SYSTEM` | Testanlage `test_system` nachbauen (9 Kreisel, Separatoren, BTMT) - Vorlage fuer sps_skel |
|
||||
|
||||
---
|
||||
@@ -218,7 +246,6 @@ Alle Skripte rufen zuerst `setenv.bat` (bzw. `setenv.sh`) auf.
|
||||
| `install_py.bat` / `install_py.sh` | `.venv` anlegen und `requirements.txt` installieren (nur wenn noch nicht vorhanden) |
|
||||
| `activate_venv.bat` / `activate_venv.sh` | `.venv` aktivieren, Python-Version und Pakete anzeigen |
|
||||
| `run_tests.bat` | Testausfuehrung, siehe unten |
|
||||
| `create_tests.bat` | Kompletter ILS-Testlauf: Basis-DXF erzeugen, BricsCAD mit `ILS_test.scr`, Ergebnisse validieren |
|
||||
| `set_einfuegepunkt.bat [schalter]` | Wrapper fuer `lib/set_einfuegepkt.py` (siehe `doc/tools.md`) |
|
||||
| `set_coords.bat [schalter]` | Wrapper fuer `lib/set_koords.py` (siehe `doc/tools.md`) |
|
||||
| `dbg2lsp.bat [argumente]` | Wrapper fuer `lib/dbg2lsp.py` (siehe `doc/dbg2lsp.md`) |
|
||||
|
||||
@@ -1,33 +1,38 @@
|
||||
# Kapitel 1: Meilensteinplanung
|
||||
|
||||
Status-Stand: 2026-10-26 (DONE = im Menue nutzbar und im Sivas-/CSV-Export erfasst).
|
||||
|
||||
## Meilenstein 1: ILS für die Projektierung
|
||||
- ILS Kreisel DONE
|
||||
- ILS Eckrad DONE
|
||||
- ILS Varioförder DONE
|
||||
- ILS Gefällestrecke
|
||||
- ILS Weichen
|
||||
- ILS Horizontalvariobögen (30,60,90 r und l, innen und aussen angetrieben)
|
||||
- ILS Gefällebögen (30,60,90 r und l)
|
||||
- ILS Varioförder DONE (Standard, Etage, Streckengruppe/Linienzug Modus 1-3, QC-Linie mit GF)
|
||||
- ILS Gefällestrecke DONE (einfach, aus 3D-Linie, aus Linienzug; Doppelklick-Edit)
|
||||
- ILS Weichen TEILWEISE (Weichenpunkte zwischen Kreiseln ermitteln: KREISEL_WEICHEN, Export Merkmal 4403 + Weichenzeile; keine eigene Weichen-Geometrie)
|
||||
- ILS Horizontalvariobögen (30,60,90 r und l, innen und aussen angetrieben) TEILWEISE (als Vario-Kurve innerhalb der Streckengruppe; die frueheren Einzelbefehle ILS_K* wurden entfernt)
|
||||
- ILS Gefällebögen (30,60,90 r und l) TEILWEISE (als GF-Bogen innerhalb von Streckengruppe/Gefaellestrecke-Linienzug)
|
||||
- BTMT Beladung und Entladung DONE (Einfuegen + Sivas-/CSV-Export)
|
||||
- CSV Export aller ILS Elemente
|
||||
- CSV Export aller ILS Elemente DONE (EXPORTCSV / EXPORTSIVAS)
|
||||
|
||||
## Meilenstein 2: Ersatz von Bihler Gerüst
|
||||
- Gerüst
|
||||
+ Abhänger (3 Quetschung, 6 Abhängung oben, 4 Abhängung unten, 4 Befestiung oben, 3 Farben, Variable Länge)
|
||||
+ T-Abhänger mit Flansch-Rohr (3 Spannpratze, 3 Farben, Variable Länge)
|
||||
+ Säulen (2 Arten, 3 Farben, 2 Einbauwinkel Platte, 5 Haltearm, 4 Einbauwinkel Arm, 8 Klemmring, Länge Bodensäule)
|
||||
+ Wandbefestigung (4 Varianten, 3 Befestigungen)
|
||||
+ Träger (RT/DRT) - (4 Varianten, 3 Farben, Muffe, Längenabzug Anfang/Ende)
|
||||
- CSV Export aller Gerüst Komponenten
|
||||
+ Abhänger (3 Quetschung, 6 Abhängung oben, 4 Abhängung unten, 4 Befestiung oben, 3 Farben, Variable Länge) DONE (GERUEST_ROHRABHAENGER)
|
||||
+ T-Abhänger mit Flansch-Rohr (3 Spannpratze, 3 Farben, Variable Länge) DONE (Variante der Rohrabhaenger)
|
||||
+ Säulen (2 Arten, 3 Farben, 2 Einbauwinkel Platte, 5 Haltearm, 4 Einbauwinkel Arm, 8 Klemmring, Länge Bodensäule) DONE (GERUEST_SAEULEN)
|
||||
+ Wandbefestigung (4 Varianten, 3 Befestigungen) DONE (GERUEST_WANDBEFESTIGUNG)
|
||||
+ Träger (RT/DRT) - (4 Varianten, 3 Farben, Muffe, Längenabzug Anfang/Ende) DONE (GERUEST_TRAEGER inkl. Beschriftung)
|
||||
+ Gatterträger OFFEN (Menue-Platzhalter)
|
||||
- CSV Export aller Gerüst Komponenten DONE (`pattern_geruest = GR_*`)
|
||||
- TOS von Gerüst-Import ins Sivas
|
||||
|
||||
## Meilenstein 3: Ersatz von Bihler Omniflo
|
||||
- Omniflo Bögen (27) DONE
|
||||
- Omniflo Weichen (80) DONE
|
||||
- Omniflo Verbinder (18 Varianten)
|
||||
- Kettenförderer (3 Teile: Ein/Auslauf und Verbindung)
|
||||
- TEF Geraden aus Omniflo Geraden (Umwandlungsmakro)
|
||||
- CSV Export aller Omniflo Elemente
|
||||
- Omniflo Verbinder (18 Varianten) DONE (OMNI_TV_*)
|
||||
- Kettenförderer (3 Teile: Ein/Auslauf und Verbindung) DONE (KETTENFOERDERER / KF_EDIT)
|
||||
- TEF Geraden aus Omniflo Geraden (Umwandlungsmakro) TEILWEISE (TEF_FOERDERER_LINIE belegt eine Linie mit TEF-Geraden; Umwandlung bestehender Omniflo-Geraden fehlt)
|
||||
- Omniflo Fahrstrecke, Ladeschleifen, Schwenkschienen DONE
|
||||
- Bögen für Weichen (OMNI_APBW_*) OFFEN (Dummy, im Menue ausgegraut)
|
||||
- CSV Export aller Omniflo Elemente DONE
|
||||
|
||||
## Meilenstein 4: Flex
|
||||
- Erstellung der .dwg Dateien von Bögen, Geraden, Förderer
|
||||
@@ -46,7 +51,7 @@
|
||||
- Erzeugung eines Puffers aus einer Flächenangabe/Recheck
|
||||
- Positionierung von Separatoren und Scannern aus dem Streckenverlauf/Fördereranbindung
|
||||
- Makro zur Erzeugung eines Arbeitsplatzes (Varioförderer ab, 180 Grad Bogen, Varoförderer auf)
|
||||
- Varioförder als Etagenförderer (anderer ES und AS Elemente)
|
||||
- Varioförder als Etagenförderer (anderer ES und AS Elemente) DONE (VF-Typ Etage)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ Erweiterung (AutoLISP-Konvention: Alist statt echtem Struct):
|
||||
| `vfl-modus-abbruch-sichern` | vf_linienzug.lsp | 9 |
|
||||
| `vf-winkel-solve` | vf_core.lsp | 8 |
|
||||
| `vfs-mitte-teil`, `vfl-vf-einheit`, `vfl-vf-einheit-abschluss` | standard/linienzug | je 7 |
|
||||
| `vfs-vf-koerper`, `vfl-insert-es-element`, `vfl3-es-fueller` | standard/linienzug | je 5-6 |
|
||||
| `vfs-vf-koerper`, `vfl-insert-es-element`, `vfl-zsolve-es-fueller` | standard/linienzug | je 5-6 |
|
||||
| die vier `insert-hz-*`-Funktionen | vf_etage.lsp | je 4-6 |
|
||||
|
||||
## Struct-Kandidaten
|
||||
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
# Offene TODOs
|
||||
|
||||
Zentrale Sammlung aller offenen Punkte. Wo ein eigener Fahrplan in `doc/todo/`
|
||||
existiert, steht hier nur die Kurzfassung mit Verweis. Erledigtes wird
|
||||
entfernt (Historie steht in git), nicht abgehakt stehen gelassen.
|
||||
|
||||
Stand: 2026-10-26. Wird woechentlich (freitags) mit der Doku geprueft, siehe
|
||||
`CLAUDE.md` -> Konventionen.
|
||||
|
||||
---
|
||||
|
||||
## 1. VarioFoerderer / Linienzug
|
||||
|
||||
- **Modus-2-Solver: achsenweise Laengen-Bilanz.** Gefaltete VF-Laeufe (U-Form)
|
||||
werden falsch gebaut (erste GF zu lang, Kletterstrecke zu kurz, Motor/ES
|
||||
falsch), weil der Solver die festen Fussabdruecke skalar von EINER Spanne
|
||||
abzieht. Als Zwischenloesung zumindest gefaltete Laeufe mit Meldung
|
||||
abweisen. -> `doc/todo/modus2-achsenweise-bilanz.md`
|
||||
- **VF-Linienzug ohne GUI/Konsole, Stufe 2** (Funktionstrennung):
|
||||
Schritte 5c, 6, 8, 9, 10 offen (u.a. `vfl-spec-ausfuehren`, Daten-Pfad ohne
|
||||
Replay-Umweg), Schritt 11 (Modus 2) zurueckgestellt. Bringt Architektur,
|
||||
keine neue Funktion. -> `doc/todo/plan-vf-interactive.md`
|
||||
- **Spec-Uebersetzer fuer Modus 2/3** (Stufe 1 Rest): `vsp-journal` kann nur
|
||||
Modus-1-Ketten. Braucht erst 2-3 echte `linienzug2`/`linienzug3`-Journale
|
||||
als Referenz; Abschnitt 4.4 des Plans auf das `SEGS`-Journalformat
|
||||
anpassen. -> `doc/todo/plan-vf-interactive.md`
|
||||
- **`vfl-konvertiere-ent` headless?** Die Batch-2D/3D-Konvertierung laeuft
|
||||
ohne `*vfl-headless*` (Live-Rueckfrage bisher gewollt). Entscheiden, ob sie
|
||||
auf den Ergebnis-Record umgestellt wird.
|
||||
- **Stufe 3 Winkelwahl: "Ab"-Zweig** (`vf_standard.lsp`, Kommentar bei der
|
||||
Fuellstueck-Berechnung): nur "Auf" implementiert, "Ab" bleibt bewusst offen,
|
||||
bis ein konkreter Bedarfsfall vorliegt. Ebenso `schon-flach` in Stufe 3.
|
||||
- **Modus 2: Separatoren vor GF-Boegen** werden noch nicht gesetzt; GF-Bogen
|
||||
mit fester Eigen-Neigung erzeugt bei unterschiedlichen Nachbar-Neigungen
|
||||
einen (akzeptierten) Knick (`vf_linienzug.lsp`, Kopfkommentar "MODUS 2:
|
||||
3D-OBJEKTE WAEHLEN").
|
||||
- **Veralteter Kommentar** im selben Kopf: "VF-Zweige als TODO (Meilenstein 2)
|
||||
... uebersprungen" - die VF-Laeufe sind inzwischen gebaut (Bau-Schleife
|
||||
"Meilenstein 2: GF + VF-Laeufe"). Kommentar nachziehen.
|
||||
|
||||
## 2. Export / Sivas
|
||||
|
||||
- **Separator-/Scanner-Aufteilung GF/VF** in Streckengruppen: Merkmale
|
||||
4337/4339 (Gefaelle-Anteil) stehen fest auf `"0"`, 4381/4383 (Vario-Anteil)
|
||||
tragen den kompletten Blockwert. Haengt an einer Ueberarbeitung der
|
||||
Separator-/Scanner-Zuordnung im Zeichnungsmodell.
|
||||
-> `cfg/sivas_merkmal_zuordnung.md` ("Offener Punkt")
|
||||
- **TOS von Geruest-Import ins Sivas** (Entwicklungsplan Meilenstein 2).
|
||||
|
||||
## 3. Geruest
|
||||
|
||||
- **Gattertraeger**: nur Menue-Platzhalter auf `GERUEST` (zeigt einen Hinweis).
|
||||
Daten sollen spaeter in `data/json/geruest_traeger.json`.
|
||||
- **Edit-Pfad `GERUEST_EDIT`** fehlt: Doppelklick auf `GR_*` oeffnet nur
|
||||
`EATTEDIT`, kein Neuaufbau ueber den Dialog.
|
||||
|
||||
## 4. Omniflo
|
||||
|
||||
- **Boegen fuer Weichen `OMNI_APBW_*`** (14 Befehle): Dummy, im Menue
|
||||
ausgegraut.
|
||||
- **TEF-Geraden aus Omniflo-Geraden** (Umwandlungsmakro): bisher nur
|
||||
`TEF_FOERDERER_LINIE` (Linie mit TEF-Geraden belegen), keine Umwandlung
|
||||
bestehender Omniflo-Geraden.
|
||||
|
||||
## 5. ILS
|
||||
|
||||
- **ILS-Weichen als Geometrie**: Weichenpunkte werden ermittelt und exportiert
|
||||
(`KREISEL_WEICHEN`), eine eigene Weichen-Geometrie gibt es nicht.
|
||||
- **Horizontal-Variobogen / Gefaellebogen als eigenstaendige Befehle**: nur
|
||||
innerhalb der Streckengruppe (Vario-Kurve, GF-Bogen); die frueheren
|
||||
Dummy-Befehle `ILS_K*` sind entfernt.
|
||||
|
||||
## 6. Tests
|
||||
|
||||
- **Statisches Inventar veraltet**: `tests/test_vf_headless_statisch.py`
|
||||
(`test_alert_nur_in_interaktiv_pfaden`, `test_eingabe_fundstellen_unveraendert`)
|
||||
- das eingecheckte Soll-Inventar `ALERT_ERLAUBT`/`EINGABE_ERLAUBT` kennt die
|
||||
neueren Funktionen (`vfl-body-abschluss`, `vflw-gruppe-*-impl` ...) nicht.
|
||||
Inventar nach Pruefung aktualisieren.
|
||||
- **`tests/test_vf_geometrie.py`** braucht BricsCAD-erzeugte DXF-Referenzdaten,
|
||||
die headless fehlen -> schlaegt ohne vorherigen CAD-Lauf fehl.
|
||||
- CAD-Laeufe `TEST_VF_SPEC` und `VF_SPEC_BAU` + `tests/test_vf_spec.py`
|
||||
gegen `tests/output/hundm05_results.json` (Beweis "Spec-Pfad ==
|
||||
Journal-Pfad" auf Geometrie-Ebene). -> `doc/todo/plan-vf-interactive.md`
|
||||
|
||||
## 7. Spaetere Meilensteine (Entwicklungsplan)
|
||||
|
||||
Nur Ueberschriften, Details in `doc/plan/Entwicklungsplan.md`:
|
||||
|
||||
- Meilenstein 4: Flex (DWGs, Produktprogramm, CSV-Export, TOS)
|
||||
- Meilenstein 5: 3D-Modelle (Omniflo Bogen/Weiche, Geruest-Modelle)
|
||||
- Meilenstein 6: Metafunktionen (Geruest ueber Bereich, Strecke aus Polylinie,
|
||||
Kreisel-Verbindung auf unterschiedlicher Hoehe, Puffer aus Flaeche,
|
||||
Separator-/Scanner-Positionierung, Arbeitsplatz-Makro)
|
||||
@@ -3,6 +3,12 @@
|
||||
Status: **Vorschlag / noch nicht umgesetzt** (2026-09-18). Mit dem Entwickler zu
|
||||
besprechen, bevor der Solver angefasst wird. Reiner Plan - kein Code geaendert.
|
||||
|
||||
**Pruefung 2026-10-26:** weiterhin OFFEN - der Solver bilanziert noch skalar
|
||||
(`climber-span`, `hor-pairs` 0/1), auch die Zwischenloesung (gefaltete Laeufe
|
||||
abweisen) ist nicht eingebaut. Die Zeilennummern unten sind veraltet: Phase B
|
||||
von `vf-linienzug-modus2` liegt inzwischen bei ca. `vf_linienzug.lsp:11880-12100`
|
||||
(per Suche nach `climber-span` finden).
|
||||
|
||||
## Kurzfassung
|
||||
|
||||
Der Modus-2-Solver (`vf-linienzug-modus2`, Phase B, `Lisp/vf_linienzug.lsp`
|
||||
@@ -44,7 +50,7 @@ ganze Hoehe traegt, und rechnet die geneigte Laenge skalar:
|
||||
|
||||
```lisp
|
||||
;; vf_linienzug.lsp:9990 - Solver bekommt die SKALARE Spanne
|
||||
(setq wahl3 (vfl3-waehle-winkel climber-span dH-adj feste-vf))
|
||||
(setq wahl3 (vfl-zsolve-winkel-waehlen climber-span dH-adj feste-vf))
|
||||
;; feste-vf = Umlenk + Separator (+ Motor) -- ein fester Fussabdruck
|
||||
|
||||
;; vf_linienzug.lsp:10070 - Kletterer bekommt br-lvf proportional
|
||||
|
||||
@@ -5,6 +5,11 @@
|
||||
verifiziert, `TEST_HUNDM05` aktiv in `tests/alltests.json`; Stufe 2
|
||||
Schritte 0-4 + 7-Assertion fertig, 5/6/8/9/10 offen, 11 zurueckgestellt.
|
||||
**Herkunft:** Planungslauf (Plan-Modus) vom 2026-09-02, hier eingecheckt zur Nachverfolgung.
|
||||
**Pruefung 2026-10-26:** Stand unveraendert - Stufe 2 Schritte 5c/6/8/9/10
|
||||
(u.a. `vfl-spec-ausfuehren`) und die Spec-Uebersetzer fuer Modus 2/3 sind
|
||||
weiterhin nicht gebaut. Hinweis: Modus 2/3 journalisieren inzwischen
|
||||
Segment-Essenz (`SEGS`) statt Objekt-Handles (`OBJS`), Abschnitt 4.4 ist
|
||||
darauf noch nicht angepasst.
|
||||
|
||||
## Fortschritt
|
||||
|
||||
@@ -149,8 +154,11 @@ Modus-uebergreifende Blocker:
|
||||
- **`ATTREQ`/`ATTDIA`**: ohne `0` fragt das `(command "_.INSERT" ...)` in den
|
||||
Einfuegeprimitiven nach Attributwerten - der wahrscheinlichste Haenger.
|
||||
|
||||
Namensfalle: die `vfl3-*`-Helfer (:5093-5276) gehoeren zu **Modus 2**, die
|
||||
`vfl2-*`-Helfer (:4703-4804) zu **Modus 3**.
|
||||
Namensschema (seit 2026-10-22 rollenbasiert statt nach Modus-Nummer, die
|
||||
frueheren Praefixe `vfl3-`/`vfl2-` waren zur Menue-Nummerierung vertauscht):
|
||||
die `vfl-zsolve-*`-Helfer rechnen die Hoehen durch und gehoeren zu **Modus 2**;
|
||||
die `vfl-pfad-*`-Helfer arbeiten auf dem gezeichneten Pfad und werden von
|
||||
**Modus 2 UND Modus 3** genutzt.
|
||||
|
||||
---
|
||||
|
||||
@@ -695,7 +703,7 @@ Architektur, nicht Funktion.
|
||||
|
||||
### Ausdruecklich nicht anfassen
|
||||
|
||||
`vf-linienzug-modus3` + alle `vfl2-*`; die `vfl-in-*`-Wrapper und `vfl-menu*`;
|
||||
`vf-linienzug-modus3` + alle `vfl-pfad-*`; die `vfl-in-*`-Wrapper und `vfl-menu*`;
|
||||
`vfl-entry->string` und das XDATA-Layout/die Marker; **alle Journal-Konsumenten**
|
||||
(brauchen sie Aenderungen, ist die Invariante gebrochen - das ist der
|
||||
Lackmustest); die reinen `vfs-*`/`berechne-*` in `vf_standard.lsp` (via
|
||||
|
||||
+20
-7
@@ -387,7 +387,7 @@ arbeiten auf bereits in der Zeichnung vorhandener Geometrie statt auf freier
|
||||
Klick-Eingabe — fuer eine GUI eher Import/Solver-Werkzeuge als klassische
|
||||
Formulare.
|
||||
|
||||
### Modus 2 — Pfad + Zielhoehe (Solver)
|
||||
### Modus 2 — aus 3D Linie MIT Zielhoehe (Solver)
|
||||
|
||||
| Feld | Steuerelement | Werte |
|
||||
|---|---|---|
|
||||
@@ -400,15 +400,28 @@ Formulare.
|
||||
| -> Vario-Kurve-Variante | Dropdown | Aussen / Innen |
|
||||
| GF-Verteilung | Dropdown | alles am Einlauf (GF1) / 1/2 GF1 + 1/2 GF2 |
|
||||
|
||||
### Modus 3 — Vorwaerts-Nachbau (Legacy, wird umgebaut)
|
||||
### Modus 3 — aus 3D Linie OHNE Zielhoehe (Vorwaerts-Bau)
|
||||
|
||||
Baut dieselbe gezeichnete Geometrie wie Modus 2, aber VORWAERTS mit
|
||||
vorgegebenen Winkeln: die Endhoehe ist hier ein Ergebnis, kein Ziel. Genau
|
||||
das ist sein Anwendungsfall — wenn es keine feste Zielhoehe gibt.
|
||||
|
||||
| Feld | Steuerelement | Werte |
|
||||
|---|---|---|
|
||||
| Startpunkt (3D) | Punktwahl | KS_EIN AUS-Element / Kettenanfang |
|
||||
| Gefaellewinkel | Zahl (Grad) | wird auch aus 2 gewaehlten 3D-Punkten vorgeschlagen |
|
||||
| AUS-Element Seite | Dropdown | links / rechts |
|
||||
| Separator vor EIN? | Dropdown | Ja/Nein |
|
||||
| Einfuegen bestaetigen | Dropdown | Ja/Nein |
|
||||
| Startpunkt (3D) + Starthoehe | Punktwahl + Zahl | Kettenanfang |
|
||||
| AS-Element bauen? | Ja/Nein | bei Nein beginnt die Kette direkt am Startpunkt |
|
||||
| -> AS Winkel + Seite | Dropdown | 30/90 Grad · links/rechts (ein Dialog zusammen mit "bauen?") |
|
||||
| ES-Element bauen? | Ja/Nein | **vor** dem Bau gefragt, damit der ES-Fussabdruck von der letzten Geraden abgezogen werden kann |
|
||||
| -> ES Winkel + Seite | Dropdown | 30/90 Grad · links/rechts |
|
||||
| Pfad-Objekte | Objektauswahl | Linien + Boegen der Trasse |
|
||||
| Je gerades Segment: Typ | Dropdown | GF / VF-Ab / VF-Auf / VF-Horizontal |
|
||||
| -> GF-Neigung bzw. Vario-Winkel | Zahl (Grad) | kontextabhaengig |
|
||||
| Je Bogen-Segment: Typ | Dropdown | GF-Bogen / Vario-Kurve (+ Variante) |
|
||||
|
||||
Ketten, die vor dem 2026-10-22 gebaut wurden, kennen die beiden
|
||||
"bauen?"-Fragen noch nicht; sie werden beim Doppelklick automatisch erkannt
|
||||
und in der alten Reihenfolge nachgebaut (siehe `alt-journal` in
|
||||
`vf-linienzug-modus3`).
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -105,6 +105,63 @@ Zwischen-Etappe, es geht in derselben VF-Einheit weiter (Vario-Kurve,
|
||||
weiteres gerades Stueck, Auf/Ab). "Ja" beendet die VF-Einheit mit einer
|
||||
Motorstation - optional zusaetzlich mit ES-Element (echtes Kettenende).
|
||||
|
||||
### 3a. Neu seit 2026-10-21: Zufuehrungsachse und "Parallel zum Kreisel"
|
||||
|
||||
Die Tabelle oben zitiert eine aeltere Aufzeichnung. Zwei Dinge sind seitdem
|
||||
dazugekommen (aeltere Ketten bleiben unveraendert editierbar - das Journal
|
||||
erkennt am Eintragstyp, welche Fragen damals gestellt wurden):
|
||||
|
||||
**Zufuehrungsachse (2. Punkt) - jetzt bei BEIDEN AS-Winkeln.** Nach Winkel
|
||||
und Seite (Eintrag 4/5) fragt der AS-Dialog zusaetzlich einen zweiten Punkt
|
||||
ab; im Assistenten stehen alle drei Angaben in EINEM Fenster
|
||||
(`vflw_as_achse`). Die beiden Angaben beschreiben verschiedene Dinge und
|
||||
legen das AS erst zusammen vollstaendig fest:
|
||||
|
||||
| Angabe | legt fest |
|
||||
|---|---|
|
||||
| 2. Punkt | Richtung der KS_EIN-Achse = die Zufuehrung, z.B. die Kreisel-Laufrichtung. Der Startpunkt bleibt der Sitz des AS-Elements, der zweite Punkt gibt nur die Richtung. |
|
||||
| links/rechts | AS-Variante und damit die KS_AUS-Richtung, also wohin die Kette nach dem Ausschleusen laeuft. |
|
||||
|
||||
Der Dialog zeigt den Startpunkt mit an (er ist der Sitz des AS-Elements UND
|
||||
der Ausgangspunkt der Achse); waehrend der Punktwahl haengt das Gummiband an
|
||||
ihm. Mit dem gesetzten Punkt ist der Dialog fertig und schliesst direkt - die
|
||||
ermittelte Achsrichtung meldet die Konsole. Nur ein mit ESC abgebrochener
|
||||
Pick zeigt den Dialog noch einmal (mit den vorher gewaehlten Werten), damit
|
||||
nach einem Fehlklick nichts verloren geht.
|
||||
|
||||
Die Achse ist **optional**: ohne Punkt laeuft alles wie frueher ueber die
|
||||
Richtung des naechsten Klicks. Frueher ersetzte die Achse beim 30-Grad-
|
||||
Element die Seitenfrage (die Seite wurde aus der Lage des naechsten Punkts
|
||||
erraten); das gilt nur noch beim Nachbau alter Ketten.
|
||||
|
||||
**"Parallel zum Kreisel weiterbauen"** - 5. Option der Frage "Wie soll die
|
||||
Laenge dieser Gefaellestrecke bestimmt werden?" (Eintrag 30). Sie erscheint
|
||||
nur am Kettenanfang mit AS-Element UND festgelegter Zufuehrungsachse, weil
|
||||
sie beides als Bezug braucht. Gebaut wird AS -> kurzes GF-Stueck -> GF-Bogen,
|
||||
sodass die Kette danach parallel zur Zufuehrungsachse weiterlaeuft. Einzige
|
||||
Eingabe ist der **Abstand**, gemessen senkrecht zur Zufuehrungsachse von
|
||||
KS_EIN des AS bis KS_AUS des Bogens; die Laenge des GF-Stuecks dazwischen
|
||||
wird daraus berechnet. Ein Separator zwischen GF-Stueck und Bogen wird
|
||||
bewusst NICHT gesetzt, damit der Abstand exakt getroffen wird. Der Bogen wird
|
||||
nicht geraten, sondern so gewaehlt, dass er den gemessenen Grundriss-Schwenk
|
||||
des AS-Blocks genau aufhebt - immer zur Gegenseite der AS-Seite:
|
||||
|
||||
| AS | Bogen |
|
||||
|---|---|
|
||||
| 30 Grad links | 30 Grad rechts |
|
||||
| 30 Grad rechts | 30 Grad links |
|
||||
| 90 Grad links | 90 Grad rechts |
|
||||
| 90 Grad rechts | 90 Grad links |
|
||||
|
||||
Diese Tabelle ist das ERGEBNIS der Messung, keine gepflegte Zuordnung im
|
||||
Code - sie bleibt auch dann richtig, wenn ein Element anders vermessen ist
|
||||
als hier erwartet.
|
||||
|
||||
Direkt nach dem Bogen kommt die gewohnte Frage "Ist das das Kettenende?"
|
||||
(Ja mit ES / Ja ohne ES / Nein, weiterbauen) - hier ausnahmsweise NACH dem
|
||||
Bau, weil es keine gepickte Laenge gibt, von der ein ES-Fussabdruck
|
||||
abzuziehen waere.
|
||||
|
||||
## 4. Stufe 1 / Stufe 2 - wie die letzte Strecke berechnet wird
|
||||
|
||||
Am Kettenende (Eintrag 61/62) ist die Aufgabe: von der aktuellen Position/
|
||||
|
||||
+91
-8
@@ -9,6 +9,7 @@
|
||||
"vfl-as-auto-erkannt": "\n>>> Startpunkt liegt auf KS_AUS einer bestehenden %1-Kette - kein AS-Element noetig.",
|
||||
"vfl-familie-neutral": "GF/VF",
|
||||
"vfl-sep-nach-durch-es-ueberschrieben": "\n>>> Separator NACH ignoriert - das ES-Element bringt beim Kettenende bereits seinen eigenen Separator mit (sonst zwei Separatoren hintereinander).",
|
||||
"vfl-sep-gf-es-automatisch": "(Ein Separator zwischen GF und ES wird automatisch gesetzt.)",
|
||||
"vfl-echo-position": "\n>>> Position: X=%1 Y=%2 Z=%3",
|
||||
"vfl-echo-wahl": "\n>>> Gewaehlt: %1",
|
||||
"vfl-aus-seite-header": "\n\nAUS-Element (AS_Element_*) - Seite waehlen:",
|
||||
@@ -55,6 +56,27 @@
|
||||
"vfl-gf-laenge-modus-opt-hoehe": "\n 2 - Zielhoehe festlegen (Laenge wird berechnet)",
|
||||
"vfl-gf-laenge-modus-opt-steigend": "\n 3 - Steigende GF (Sonderfall, bis 3 Grad)",
|
||||
"vfl-gf-laenge-modus-opt-qc": "\n 4 - QC Linie mit GF (automatische Auf-Ab-Berechnung)",
|
||||
"vfl-gf-laenge-modus-opt-parallel": "\n 5 - Parallel zum Kreisel weiterbauen (nur Abstand eingeben)",
|
||||
"vfl-richtung-header": "\n\nIn welche Richtung soll gebaut werden?",
|
||||
"vfl-richtung-opt-vor": "\n 1 - Vorwaerts bauen (der gewaehlte Punkt ist der Kettenanfang)",
|
||||
"vfl-richtung-opt-rueck": "\n 2 - Rueckwaerts bauen (der gewaehlte Punkt ist das Kettenende, ES-Austritt)",
|
||||
"vfl-prompt-es-achse-p2": "\n\nFahrtrichtung - 2. Punkt (gibt nur die Richtung, der Endpunkt bleibt): ",
|
||||
"vfl-es-basislinie-info": "\n Abfuehrungsachse (Fahrtrichtung): %1 Grad.",
|
||||
"vfl-rueck-menu-linie-gf": "\n 1 - Neue Linie: GF (Gefaellestrecke)",
|
||||
"vfl-rueck-laenge-opt-anfangspunkt": "\n 1 - Kettenanfang waehlen (Laenge ergibt sich, Anfangshoehe wird gerechnet)",
|
||||
"vfl-rueck-laenge-opt-anfangshoehe": "\n 2 - Anfangshoehe festlegen (Laenge wird berechnet)",
|
||||
"vfl-rueck-prompt-anfangspunkt": "\n\nKettenanfang waehlen (Richtung steht ueber die Abfuehrungsachse fest): ",
|
||||
"vfl-rueck-prompt-anfangshoehe": "\nGewuenschte Hoehe am Kettenanfang (mm) <%1>: ",
|
||||
"vfl-rueck-alert-hoehe-zu-klein": "Der Kettenanfang muss HOEHER liegen als das Kettenende - eine Gefaellestrecke faellt in Fahrtrichtung.",
|
||||
"vfl-rueck-erfolg-punkt": "\n>>> Rueckwaerts gebaut: GF-Stueck %1 mm (horizontal), Anfangshoehe %2 mm.",
|
||||
"vfl-rueck-erfolg-hoehe": "\n>>> Rueckwaerts gebaut: GF-Stueck %1 mm (horizontal), Anfangshoehe %2 mm.",
|
||||
"vfl-rueck-erfolg-parallel": "\n>>> Rueckwaerts, parallel zum Kreisel: GF-Stueck %1 mm (horizontal), Bogen %2 Grad %3.",
|
||||
"vfl-par-prompt-abstand": "\n\nAbstand zum Kreisel (mm, senkrecht zur Zufuehrungsachse, von AS-KS_EIN bis Bogen-KS_AUS): ",
|
||||
"vfl-par-nur-kettenanfang": "'Parallel zum Kreisel' geht nur am Kettenanfang mit AS-Element UND festgelegter Zufuehrungsachse (2. Punkt im AS-Dialog).",
|
||||
"vfl-par-kein-bogen": "Kein GF-Bogen hebt den AS-Schwenk von %1 Grad auf (Seite %2) - parallel zum Kreisel nicht schliessbar.",
|
||||
"vfl-par-kein-versatz": "Das AS-Element schwenkt nicht aus der Zufuehrungsachse heraus - so laesst sich kein Abstand erreichen.",
|
||||
"vfl-par-zu-klein": "Abstand %1 mm zu klein: AS und Bogen allein brauchen schon %2 mm. Bitte groesseren Abstand waehlen.",
|
||||
"vfl-par-erfolg": "\n>>> Parallel zum Kreisel: GF-Stueck %1 mm (horizontal), Bogen %2 Grad %3, erreichter Abstand %4 mm.",
|
||||
"vfl-qc-nur-kettenanfang": "\nFEHLER: 'QC Linie mit GF' ist nur am Kettenanfang moeglich (braucht eine eigene AS-Seite) - bitte anderen Modus waehlen.",
|
||||
"vfl-qc-prompt-richtung": "\n\nRichtung waehlen (Gerade, auf der AS-Eintritt und ES-Austritt liegen sollen) - Punkt in Fahrtrichtung anklicken: ",
|
||||
"vfl-qc-ks-ein-gemessen": "\n>>> AS KS_EIN (Referenzgerade) gemessen: X=%1 Y=%2 Z=%3",
|
||||
@@ -99,6 +121,11 @@
|
||||
"vfl-es-setzen-frage": "\n\nES-Element setzen?",
|
||||
"vfl-es-nein-zielpunkt": "\n 2 - Nein (Kette endet direkt am Zielpunkt)",
|
||||
"vfl-prompt-endpunkt-fahrtrichtung": "\n\nEndpunkt entlang Fahrtrichtung waehlen (bestimmt die Laenge): ",
|
||||
"vfl-prompt-as-achse-p2": "\n\nZufuehrungsachse - 2. Punkt (gibt nur die Richtung, der Startpunkt bleibt): ",
|
||||
"vfl-basislinie-punkte-gleich": "\n Die beiden Punkte sind identisch - keine Richtung bestimmbar. Abbruch.",
|
||||
"vfl-basislinie-info": "\n Zufuehrungsachse (Fahrtrichtung): %1 Grad.",
|
||||
"vfl-basislinie-ohne": "\n Keine Zufuehrungsachse festgelegt - die Richtung ergibt sich aus dem naechsten Klick.",
|
||||
"vfl-as-seite-ermittelt": "\n AS-Seite aus der Lage des naechsten Punkts: %1",
|
||||
"vfl-endpunkt-modus-header": "\n\nWie soll der Endpunkt bestimmt werden?",
|
||||
"vfl-endpunkt-modus-opt-linie": "\n 1 - Ziellinie zeichnen (2 Punkte) - der Schnittpunkt bestimmt die Laenge",
|
||||
"vfl-prompt-ziellinie-p1": "\n\nZiellinie - 1. Punkt (beliebige Richtung, Z wird ignoriert): ",
|
||||
@@ -169,7 +196,7 @@
|
||||
"vfl-soll-xyz": "\n Soll: X=%1 Y=%2 Z=%3",
|
||||
"vfl-ist-xyz": "\n Ist : X=%1 Y=%2 Z=%3",
|
||||
"vfl-abweichung-xyz": "\n Abweichung: dX=%1 dY=%2 dZ=%3 mm",
|
||||
"vfl-m3-titel": "\n VF-LINIENZUG - Modus 2: Pfad + Ziel-Hoehe (fertig; Anker + Solver + Bau)",
|
||||
"vfl-m3-titel": "\n VF-LINIENZUG - Modus 2: aus 3D Linie MIT Zielhoehe (Anker + Solver + Bau)",
|
||||
"vfl-m3-alert-gf-modul": "Gefaellestrecke-Modul nicht geladen!",
|
||||
"vfl-m3-pfad-waehlen": "\n\nPfad-Objekte waehlen (Linien/Boegen):",
|
||||
"vfl-m3-keine-objekte": "\nKeine Objekte gewaehlt - Abbruch.",
|
||||
@@ -224,13 +251,18 @@
|
||||
"vfl-m3-kletter-zu-kurz-flach": "\n Kein Kletter-Winkel passt (Segment zu kurz) -> Lauf wird komplett flach gebaut, Hoehe wandert in GF1.",
|
||||
"vfl-m3-kletter-flach-gf": "\n Flache Zone: GF-Kompensation (GF1) = %1 mm",
|
||||
"vfl-m3-alert-vf-zu-lang": "VF-Lauf ist %1 m lang (Grenze %2 m) - bitte neu planen (z.B. Zwischen-Motorstation einfuegen).",
|
||||
"vfl-m2-einheit-grenze": "Diese VF-Einheit ist so nicht baubar.\n\nGemessen: %1 m Laenge, %2 Vario-Kurven.\nErlaubt je Einheit (zwischen Umlenk- und Motorstation): hoechstens %3 m und %4 Vario-Kurven.\n\nBitte den Bogen in Segment %5 als GF-Bogen klassifizieren - dann endet die erste Einheit davor mit einer Motorstation und die zweite beginnt danach mit einer Umlenkstation.",
|
||||
"vfl-m2-einheit-grenze-unteilbar": "Diese VF-Einheit ist so nicht baubar.\n\nGemessen: %1 m Laenge, %2 Vario-Kurven.\nErlaubt je Einheit (zwischen Umlenk- und Motorstation): hoechstens %3 m und %4 Vario-Kurven.\n\nEs gibt keinen Bogen, an dem sich der Lauf teilen liesse - bitte den Pfad kuerzer fassen oder eine Ecke einplanen, an der die Einheit enden kann.",
|
||||
"vfl-m3-warnung-fueller-eingang-zu-kurz": "\n WARNUNG: Fueller direkt nach der Umlenkstation zu kurz (%1 mm < Minimum %2 mm) - nur Minimalabstand gebaut, Zielposition nicht exakt erreicht.",
|
||||
"vfl-m3-warnung-fueller-ausgang-zu-kurz": "\n WARNUNG: Fueller direkt vor der Motorstation zu kurz (%1 mm < Minimum %2 mm) - nur Minimalabstand gebaut, Zielposition nicht exakt erreicht.",
|
||||
"vfl-m3-lauf-anfang-header": "\n\nDer VF-Lauf ist der Anfang des gewaehlten Pfads. Lauf beginnen mit:",
|
||||
"vfl-m3-lauf-anfang-opt-offen": "\n 1 - Ohne Umlenkstation (offener Anfang, spaeter fortsetzen/verschmelzen)",
|
||||
"vfl-m3-lauf-anfang-opt-offen": "\n 3 - Ohne Umlenkstation (offener Anfang, spaeter fortsetzen/verschmelzen)",
|
||||
"vfl-m3-lauf-anfang-opt-umlenk": "\n 2 - Umlenkstation direkt (kein GF1/Separator)",
|
||||
"vfl-m3-lauf-anfang-opt-umlenk-gf1": "\n 3 - Umlenkstation mit GF1 + Separator",
|
||||
"vfl-m3-lauf-anfang-opt-umlenk-gf1": "\n 1 - Umlenkstation mit GF1 + Separator",
|
||||
"vfl-m2-anfang-wert-unbekannt": "Lauf-Anfang nicht lesbar: Kette %1 enthaelt den unbekannten Wert %2. Aufbau abgebrochen - eine geratene Anfangsvariante wuerde die Kette falsch neu bauen.",
|
||||
"vfl-m3-lauf-anfang-offen-hinweis": "\n Anfang bleibt bewusst offen - keine Umlenkstation/GF1/Separator gebaut, spaeter fortsetzen oder per Vario_Kette_Merge verbinden.",
|
||||
"vfl-m2-anfang-offen-gesperrt-zeile": "\n (nicht waehlbar - mit AS-Element braucht der Lauf eine Umlenkstation)",
|
||||
"vfl-m2-anfang-offen-gesperrt": "Mit AS-Element ist ein offener Anfang nicht moeglich - der Lauf braucht dann eine Umlenkstation.",
|
||||
"vfl-m3-lauf-abschluss-header": "\n\nDer VF-Lauf ist das Ende des gewaehlten Pfads. Lauf beenden mit:",
|
||||
"vfl-m3-lauf-abschluss-opt-offen": "\n 1 - Ohne Motorstation (offenes Ende, spaeter fortsetzen/verschmelzen)",
|
||||
"vfl-m3-lauf-abschluss-opt-motor": "\n 2 - Motorstation setzen (kein ES-Element)",
|
||||
@@ -246,6 +278,7 @@
|
||||
"vfl-m3-gf2-ausgleich": "\n GF2 (gemessener Ausgleich): L=%1 mm",
|
||||
"vfl-m3-kurve-back-uebersprungen": "\n >>> [M3a] Vario-Kurve im Back-Lauf - uebersprungen.",
|
||||
"vfl-m3-nichts-gebaut": "\nNichts gebaut - Abbruch.",
|
||||
"vfl-m3-alt-journal": "\n Hinweis: Diese Kette stammt aus der Zeit vor den Fragen AS bauen / ES bauen - sie wird in der alten Reihenfolge nachgebaut.",
|
||||
"vfl-m3-fertig-header": "\n>>> VF-Linienzug (Modus 2) gebaut! <<<",
|
||||
"vfl-m3-ziel-soll": "\n Ziel (Soll): X=%1 Y=%2 Z=%3",
|
||||
"vfl-m3-es-ist": "\n ES (Ist): X=%1 Y=%2 Z=%3",
|
||||
@@ -939,13 +972,13 @@
|
||||
"vfc-warnung-untermodule-nicht-geladen": "\n[vf_core] WARNUNG: DXFM_LISP nicht gesetzt - Untermodule konnten nicht geladen werden!",
|
||||
"vfc-linienzug-modus-header": "\n\nLinienzug-Modus waehlen:",
|
||||
"vfc-linienzug-modus-1": "\n 1 - Manuelle Eingabe (Punkte klicken)",
|
||||
"vfc-linienzug-modus-2": "\n 2 - 3D-Objekte + Ziel-Hoehe (Randwert-Solver, fertig)",
|
||||
"vfc-linienzug-modus-3": "\n 3 - 3D-Objekte stueckweise (Vorwaerts-Nachbau, in Arbeit)",
|
||||
"vfc-linienzug-modus-2": "\n 2 - aus 3D Linie MIT Zielhoehe (Hoehen werden gerechnet)",
|
||||
"vfc-linienzug-modus-3": "\n 3 - aus 3D Linie OHNE Zielhoehe (Vorwaerts-Bau mit vorgegebenen Winkeln)",
|
||||
"prompt-wahl-1-3": "\nIhre Wahl (1/2/3) [1]: ",
|
||||
"vfl-qc-uform-nicht-implementiert": "\nFEHLER: 'QC Linie mit GF und U-Form' ist noch nicht implementiert - bitte Option 4 oder einen anderen Modus waehlen.",
|
||||
"vfc-typ-standard-beschreibung": "Standard VarioFoerderer (AS/ES 90 Grad, horizontal versetzt)",
|
||||
"vfc-typ-etage-beschreibung": "Etage VarioFoerderer (AS/ES 30 Grad, direkt uebereinander)",
|
||||
"vfc-typ-linienzug-beschreibung": "Streckengruppe (gemischte GF/VF-Kette; Modus 1 manuell / Modus 2 Ziel-Hoehe fertig / Modus 3 stueckweise in Arbeit)",
|
||||
"vfc-typ-linienzug-beschreibung": "Streckengruppe (gemischte GF/VF-Kette; Modus 1 manuell / Modus 2 aus 3D Linie mit Zielhoehe / Modus 3 aus 3D Linie ohne Zielhoehe)",
|
||||
"vfs-schritt6-horizontal": "\n\n6/11: Horizontale Zwischenstrecke (0 Grad, L=%1 mm)",
|
||||
"vfs-schritt6-steigung": "\n\n6/11: Steigungsstrecke (%1 Grad, L=%2 mm)",
|
||||
"vfs-schritt6-gefaelle": "\n\n6/11: Gefaellestrecke (%1 Grad, L=%2 mm)",
|
||||
@@ -974,7 +1007,7 @@
|
||||
"vfe-step14": "\n\n14/15: Separator (300mm, cur-hz=%1)",
|
||||
"vfe-step15": "\n\n15/15: %1 (Ende, verkettet cur-hz=%2)",
|
||||
"vfe-eingefuegt": "\n>>> Etage-VarioFoerderer eingefuegt! <<<",
|
||||
"vfl-vwnb-titel": "\n VF-LINIENZUG - Modus 3: 3D-Objekte stueckweise (Vorwaerts-Nachbau, in Arbeit)",
|
||||
"vfl-vwnb-titel": "\n VF-LINIENZUG - Modus 3: aus 3D Linie OHNE Zielhoehe (Vorwaerts-Bau)",
|
||||
"vfl-vwnb-aus-seite-menu": "\n\nAUS-Element - Seite waehlen:\n 1 - Links\n 2 - Rechts",
|
||||
"vfl-vwnb-alert-eckwinkel": "Kein passender Bogen: Eck-Winkel %1 Grad ist nicht ~30/60/90.\nBitte die Winkel der Linien anpassen.",
|
||||
"vfl-vwnb-alert-keine-gerade": "Pfad enthaelt keine Gerade - eine Kette muss mit einer Geraden beginnen.",
|
||||
@@ -1131,6 +1164,56 @@
|
||||
"kreisel-bp-kollision": "\n KOLLISION %1: %2 <-> %3 [%4] bei X=%5 Y=%6 Z=%7",
|
||||
"kreisel-bp-marker": "\n%1 Marker gezeichnet (Layer %2).",
|
||||
"exp-kreisel-weichen": "\n[%1] Kreisel-Weichenpunkte: %2 Beruehrung(en), %3 Kollision(en) -> %4",
|
||||
"exp-kreisel-kollision": "\n[%1] WARNUNG: %2 Kreisel-Kollision(en) - Befehl KREISEL_WEICHEN zeigt sie an."
|
||||
"exp-kreisel-kollision": "\n[%1] WARNUNG: %2 Kreisel-Kollision(en) - Befehl KREISEL_WEICHEN zeigt sie an.",
|
||||
"kf-fehler-daten-fehlt": "\nFEHLER: Kettenfoerderer-Daten nicht gefunden: %1",
|
||||
"kf-fehler-daten-leer": "\nFEHLER: Kettenfoerderer-Daten konnten nicht gelesen werden.",
|
||||
"kf-fehler-block-datei": "\nFEHLER: Blockdatei fuer %1 nicht gefunden (erwartet in data/omniflo/<Dimension>/).",
|
||||
"kf-fehler-ks-fehlt": "In mindestens einem Baustein fehlt KS_EIN oder KS_AUS - die Kette kann nicht verkettet werden. Befehl KF_KS_PRUEFEN zeigt, welcher Block betroffen ist.",
|
||||
"kf-fehler-hoehe-zu-klein": "Die Einbauhoehe ist zu klein: Umlenk- und Antriebsstation bringen bereits mehr Hoehe mit, als gefordert ist. Bitte groessere Hoehe waehlen.",
|
||||
"kf-fehler-laenge-unter-min": "Das Zwischenstueck waere kuerzer als zulaessig. Bitte groessere Einbauhoehe waehlen.",
|
||||
"kf-fehler-laenge-ueber-max": "Das Zwischenstueck waere laenger als zulaessig. Bitte kleinere Einbauhoehe waehlen.",
|
||||
"kf-fehler-winkel-null": "Der gemessene Einbauwinkel des Zwischenstuecks ist waagerecht - damit laesst sich keine Hoehe erreichen. Bitte die KS-Lage der Bloecke pruefen (KF_KS_PRUEFEN).",
|
||||
"kf-fehler-dcl": "Dialogdatei kettenfoerderer.dcl nicht gefunden.",
|
||||
"kf-prompt-messpunkt-1": "\nErsten Messpunkt waehlen (Hoehenbezug unten): ",
|
||||
"kf-prompt-messpunkt-2": "\nZweiten Messpunkt waehlen (Hoehenbezug oben): ",
|
||||
"kf-messung-ergebnis": "\n>>> Gemessen: Hoehendifferenz dZ = %1 mm (zur Kontrolle dY = %2 mm).",
|
||||
"kf-konsole-hoehe-hinweis": "\n(0 eingeben, um die Hoehe aus zwei Punkten zu messen)",
|
||||
"kf-2d-gebaut": "\n>>> Draufsicht %1 eingefuegt: Schraeglaenge %2 mm, Neigung %3 Grad.",
|
||||
"kf-2d-laenge-null": "\nDraufsicht uebersprungen: die Kette hat keine messbare Grundrisslaenge.",
|
||||
"kf-2d-ks-fehlt": "\nDraufsicht uebersprungen: %1 hat kein messbares KS_EIN/KS_AUS.",
|
||||
"kf-prompt-startpunkt": "\nEinfuegepunkt waehlen (KS_EIN der Draufsicht; die Seitenansicht entsteht darueber): ",
|
||||
"kf-prompt-drehung": "\nDrehwinkel der Kette: ",
|
||||
"kf-abgebrochen": "\nAbgebrochen.",
|
||||
"kf-fertig": "\n>>> %1 erstellt: Einbauhoehe %2 mm, Zwischenstueck %3 mm.",
|
||||
"kf-konsole-variante-header": "\n\nSchraegfoerderer Stahl Typ waehlen:",
|
||||
"kf-konsole-option": "\n %1 - %2",
|
||||
"kf-konsole-variante-prompt": "\nSchraegfoerderer Stahl Typ",
|
||||
"kf-konsole-hoehe-prompt": "\nH - Einbauhoehe Schraegfoerderer [mm]",
|
||||
"kf-konsole-verbindung-header": "\n\nVerbindungselemente waehlen:",
|
||||
"kf-konsole-verbindung-prompt": "\nVerbindungselemente",
|
||||
"kf-konsole-farbe-header": "\n\nFarbe Foerderer waehlen:",
|
||||
"kf-konsole-farbe-prompt": "\nFarbe",
|
||||
"kf-konsole-antriebsmotor-header": "\n\nAntriebsmotor Foerderer waehlen:",
|
||||
"kf-konsole-antriebsmotor-prompt": "\nAntriebsmotor Foerderer",
|
||||
"kf-variante-label": "%1 %2",
|
||||
"kf-variante-label-standard": "%1 %2 (Standard)",
|
||||
"kf-konsole-movimot-header": "\n\nAntrieb mit Movimot?",
|
||||
"kf-konsole-movimot-prompt": "\nAntrieb mit Movimot",
|
||||
"kf-konsole-steuerung-header": "\n\nMit Standard Steuerung?",
|
||||
"kf-konsole-steuerung-prompt": "\nMit Standard Steuerung",
|
||||
"kf-pruef-kopf": "\n\n=== KF_KS_PRUEFEN: KS-Lage der Kettenfoerderer-Bloecke ===",
|
||||
"kf-pruef-variante": "\n\n--- Variante: %1 ---",
|
||||
"kf-pruef-block": "\n %1: KS_EIN (%2, %3) Richtung %4 | KS_AUS (%5, %6) Richtung %7",
|
||||
"kf-pruef-block-fehlt": "\n %1: Blockdatei nicht gefunden.",
|
||||
"kf-pruef-ks-fehlt": "\n %1: KS unvollstaendig - KS_EIN: %2, KS_AUS: %3",
|
||||
"kf-pruef-ks-fehlt-kurz": "\n[KF] KS_EIN/KS_AUS nicht lesbar am Baustein: %1 (Befehl KF_KS_PRUEFEN zeigt Einzelheiten)",
|
||||
"kf-pruef-fehler": "\n Geometrie nicht ermittelbar: %1",
|
||||
"kf-pruef-geo": "\n Einbauwinkel (Grad): Umlenkung %1, Zwischenstueck %2, Antrieb %3\n Hoehenbeitrag (mm): Umlenkung %4, Antrieb %5\n Zwischenstueck nativ (mm): dx %6, dy %7",
|
||||
"kf-pruef-ja": "vorhanden",
|
||||
"kf-pruef-nein": "FEHLT",
|
||||
"kf-edit-waehlen": "\nKettenfoerderer (KF_n) zum Bearbeiten waehlen: ",
|
||||
"kf-edit-kein-kf": "Der gewaehlte Block ist kein Kettenfoerderer (KF_n).",
|
||||
"kf-edit-fertig": "\n>>> %1 neu aufgebaut als %2.",
|
||||
"cmd-kettenfoerderer-bearbeiten": "\n>>> Kettenfoerderer %1 wird bearbeitet ..."
|
||||
}
|
||||
}
|
||||
|
||||
+91
-8
@@ -9,6 +9,7 @@
|
||||
"vfl-as-auto-erkannt": "\n>>> Start point lies on the KS_AUS of an existing %1 chain - no AS element needed.",
|
||||
"vfl-familie-neutral": "GF/VF",
|
||||
"vfl-sep-nach-durch-es-ueberschrieben": "\n>>> Separator AFTER ignored - the ES element already brings its own separator at the chain end (otherwise two separators in a row).",
|
||||
"vfl-sep-gf-es-automatisch": "(A separator between GF and ES is inserted automatically.)",
|
||||
"vfl-echo-position": "\n>>> Position: X=%1 Y=%2 Z=%3",
|
||||
"vfl-echo-wahl": "\n>>> Selected: %1",
|
||||
"vfl-aus-seite-header": "\n\nOUT element (AS_Element_*) - select side:",
|
||||
@@ -55,6 +56,27 @@
|
||||
"vfl-gf-laenge-modus-opt-hoehe": "\n 2 - Set target height (length will be calculated)",
|
||||
"vfl-gf-laenge-modus-opt-steigend": "\n 3 - Rising GF (special case, up to 3 degrees)",
|
||||
"vfl-gf-laenge-modus-opt-qc": "\n 4 - QC line with GF (automatic up/down calculation)",
|
||||
"vfl-gf-laenge-modus-opt-parallel": "\n 5 - Continue parallel to the carousel (distance only)",
|
||||
"vfl-richtung-header": "\n\nIn which direction should the chain be built?",
|
||||
"vfl-richtung-opt-vor": "\n 1 - Build forwards (the picked point is the start of the chain)",
|
||||
"vfl-richtung-opt-rueck": "\n 2 - Build backwards (the picked point is the end of the chain, ES outlet)",
|
||||
"vfl-prompt-es-achse-p2": "\n\nTravel direction - 2nd point (defines the direction only, the end point stays): ",
|
||||
"vfl-es-basislinie-info": "\n Outfeed axis (travel direction): %1 degrees.",
|
||||
"vfl-rueck-menu-linie-gf": "\n 1 - New line: GF (gravity section)",
|
||||
"vfl-rueck-laenge-opt-anfangspunkt": "\n 1 - Pick start of chain (length results, start height is calculated)",
|
||||
"vfl-rueck-laenge-opt-anfangshoehe": "\n 2 - Set start height (length will be calculated)",
|
||||
"vfl-rueck-prompt-anfangspunkt": "\n\nPick the start of the chain (direction is fixed by the outfeed axis): ",
|
||||
"vfl-rueck-prompt-anfangshoehe": "\nDesired height at the start of the chain (mm) <%1>: ",
|
||||
"vfl-rueck-alert-hoehe-zu-klein": "The start of the chain must be HIGHER than its end - a gravity section falls in the travel direction.",
|
||||
"vfl-rueck-erfolg-punkt": "\n>>> Built backwards: GF section %1 mm (horizontal), start height %2 mm.",
|
||||
"vfl-rueck-erfolg-hoehe": "\n>>> Built backwards: GF section %1 mm (horizontal), start height %2 mm.",
|
||||
"vfl-rueck-erfolg-parallel": "\n>>> Backwards, parallel to the carousel: GF section %1 mm (horizontal), bend %2 degrees %3.",
|
||||
"vfl-par-prompt-abstand": "\n\nDistance to the carousel (mm, perpendicular to the feed axis, from AS KS_EIN to bend KS_AUS): ",
|
||||
"vfl-par-nur-kettenanfang": "'Parallel to the carousel' only works at the start of a chain with an AS element AND a defined feed axis (2nd point in the AS dialog).",
|
||||
"vfl-par-kein-bogen": "No GF bend cancels the AS plan turn of %1 degrees (side %2) - cannot close parallel to the carousel.",
|
||||
"vfl-par-kein-versatz": "The AS element does not turn away from the feed axis - no distance can be reached this way.",
|
||||
"vfl-par-zu-klein": "Distance %1 mm too small: AS and bend alone already need %2 mm. Please choose a larger distance.",
|
||||
"vfl-par-erfolg": "\n>>> Parallel to the carousel: GF section %1 mm (horizontal), bend %2 degrees %3, resulting distance %4 mm.",
|
||||
"vfl-qc-nur-kettenanfang": "\nERROR: 'QC line with GF' is only possible at the chain start (needs its own AS side) - please choose a different mode.",
|
||||
"vfl-qc-prompt-richtung": "\n\nChoose direction (line on which AS entry and ES exit shall lie) - click a point in the travel direction: ",
|
||||
"vfl-qc-ks-ein-gemessen": "\n>>> AS KS_EIN (reference line) measured: X=%1 Y=%2 Z=%3",
|
||||
@@ -99,6 +121,11 @@
|
||||
"vfl-es-setzen-frage": "\n\nPlace ES element?",
|
||||
"vfl-es-nein-zielpunkt": "\n 2 - No (chain ends directly at the target point)",
|
||||
"vfl-prompt-endpunkt-fahrtrichtung": "\n\nSelect end point along travel direction (defines the length): ",
|
||||
"vfl-prompt-as-achse-p2": "\n\nFeed axis - 2nd point (defines the direction only, the start point stays): ",
|
||||
"vfl-basislinie-punkte-gleich": "\n The two points are identical - no direction can be derived. Aborting.",
|
||||
"vfl-basislinie-info": "\n Feed axis (travel direction): %1 degrees.",
|
||||
"vfl-basislinie-ohne": "\n No feed axis defined - the direction follows from the next click.",
|
||||
"vfl-as-seite-ermittelt": "\n AS side from the position of the next point: %1",
|
||||
"vfl-endpunkt-modus-header": "\n\nHow should the end point be determined?",
|
||||
"vfl-endpunkt-modus-opt-linie": "\n 1 - Draw target line (2 points) - the intersection defines the length",
|
||||
"vfl-prompt-ziellinie-p1": "\n\nTarget line - 1st point (any direction, Z is ignored): ",
|
||||
@@ -169,7 +196,7 @@
|
||||
"vfl-soll-xyz": "\n Target: X=%1 Y=%2 Z=%3",
|
||||
"vfl-ist-xyz": "\n Actual: X=%1 Y=%2 Z=%3",
|
||||
"vfl-abweichung-xyz": "\n Deviation: dX=%1 dY=%2 dZ=%3 mm",
|
||||
"vfl-m3-titel": "\n VF LINE PATH - Mode 2: path + target height (finished; anchors + solver + build)",
|
||||
"vfl-m3-titel": "\n VF LINE PATH - Mode 2: from 3D line WITH target height (anchors + solver + build)",
|
||||
"vfl-m3-alert-gf-modul": "Gefaellestrecke module not loaded!",
|
||||
"vfl-m3-pfad-waehlen": "\n\nSelect path objects (lines/arcs):",
|
||||
"vfl-m3-keine-objekte": "\nNo objects selected - aborting.",
|
||||
@@ -224,13 +251,18 @@
|
||||
"vfl-m3-kletter-zu-kurz-flach": "\n No climb angle fits (segment too short) -> run is built entirely flat, height is absorbed by GF1.",
|
||||
"vfl-m3-kletter-flach-gf": "\n Flat zone: GF compensation (GF1) = %1 mm",
|
||||
"vfl-m3-alert-vf-zu-lang": "VF run is %1 m long (limit %2 m) - please re-plan (e.g. insert an intermediate motor station).",
|
||||
"vfl-m2-einheit-grenze": "This VF unit cannot be built like this.\n\nMeasured: %1 m length, %2 vario curves.\nAllowed per unit (between deflection and motor station): at most %3 m and %4 vario curves.\n\nPlease classify the bend in segment %5 as a GF bend - the first unit then ends before it with a motor station and the second one starts after it with a deflection station.",
|
||||
"vfl-m2-einheit-grenze-unteilbar": "This VF unit cannot be built like this.\n\nMeasured: %1 m length, %2 vario curves.\nAllowed per unit (between deflection and motor station): at most %3 m and %4 vario curves.\n\nThere is no bend at which the run could be split - please shorten the path or plan a corner where the unit can end.",
|
||||
"vfl-m3-warnung-fueller-eingang-zu-kurz": "\n WARNING: filler right after the reversing station is too short (%1 mm < minimum %2 mm) - only the minimum clearance was built, target position not reached exactly.",
|
||||
"vfl-m3-warnung-fueller-ausgang-zu-kurz": "\n WARNING: filler right before the motor station is too short (%1 mm < minimum %2 mm) - only the minimum clearance was built, target position not reached exactly.",
|
||||
"vfl-m3-lauf-anfang-header": "\n\nThe VF run is the start of the selected path. Start the run with:",
|
||||
"vfl-m3-lauf-anfang-opt-offen": "\n 1 - No reversing station (open start, continue/merge later)",
|
||||
"vfl-m3-lauf-anfang-opt-offen": "\n 3 - No reversing station (open start, continue/merge later)",
|
||||
"vfl-m3-lauf-anfang-opt-umlenk": "\n 2 - Reversing station directly (no GF1/separator)",
|
||||
"vfl-m3-lauf-anfang-opt-umlenk-gf1": "\n 3 - Reversing station with GF1 + separator",
|
||||
"vfl-m3-lauf-anfang-opt-umlenk-gf1": "\n 1 - Reversing station with GF1 + separator",
|
||||
"vfl-m2-anfang-wert-unbekannt": "Cannot read run start: chain %1 contains the unknown value %2. Build aborted - guessing a start variant would rebuild the chain incorrectly.",
|
||||
"vfl-m3-lauf-anfang-offen-hinweis": "\n Start deliberately left open - no reversing station/GF1/separator built; continue later or join with Vario_Kette_Merge.",
|
||||
"vfl-m2-anfang-offen-gesperrt-zeile": "\n (not selectable - with an AS element the run needs a reversing station)",
|
||||
"vfl-m2-anfang-offen-gesperrt": "With an AS element an open start is not possible - the run then needs a reversing station.",
|
||||
"vfl-m3-lauf-abschluss-header": "\n\nThe VF run is the end of the selected path. End the run with:",
|
||||
"vfl-m3-lauf-abschluss-opt-offen": "\n 1 - No motor station (open end, continue/merge later)",
|
||||
"vfl-m3-lauf-abschluss-opt-motor": "\n 2 - Set motor station (no ES element)",
|
||||
@@ -246,6 +278,7 @@
|
||||
"vfl-m3-gf2-ausgleich": "\n GF2 (measured compensation): L=%1 mm",
|
||||
"vfl-m3-kurve-back-uebersprungen": "\n >>> [M3a] Vario curve in back run - skipped.",
|
||||
"vfl-m3-nichts-gebaut": "\nNothing built - aborting.",
|
||||
"vfl-m3-alt-journal": "\n Note: this chain predates the build AS / build ES questions - it is rebuilt in the old order.",
|
||||
"vfl-m3-fertig-header": "\n>>> VF line path (mode 2) built! <<<",
|
||||
"vfl-m3-ziel-soll": "\n Target (nominal): X=%1 Y=%2 Z=%3",
|
||||
"vfl-m3-es-ist": "\n ES (actual): X=%1 Y=%2 Z=%3",
|
||||
@@ -939,13 +972,13 @@
|
||||
"vfc-warnung-untermodule-nicht-geladen": "\n[vf_core] WARNING: DXFM_LISP not set - submodules could not be loaded!",
|
||||
"vfc-linienzug-modus-header": "\n\nSelect line-path mode:",
|
||||
"vfc-linienzug-modus-1": "\n 1 - Manual entry (click points)",
|
||||
"vfc-linienzug-modus-2": "\n 2 - 3D objects + target height (boundary-value solver, finished)",
|
||||
"vfc-linienzug-modus-3": "\n 3 - 3D objects step by step (forward reconstruction, work in progress)",
|
||||
"vfc-linienzug-modus-2": "\n 2 - from 3D line WITH target height (heights are calculated)",
|
||||
"vfc-linienzug-modus-3": "\n 3 - from 3D line WITHOUT target height (forward build with given angles)",
|
||||
"prompt-wahl-1-3": "\nYour choice (1/2/3) [1]: ",
|
||||
"vfl-qc-uform-nicht-implementiert": "\nERROR: 'QC line with GF and U-shape' is not yet implemented - please choose option 4 or a different mode.",
|
||||
"vfc-typ-standard-beschreibung": "Standard VarioFoerderer (AS/ES 90 degrees, offset horizontally)",
|
||||
"vfc-typ-etage-beschreibung": "Etage VarioFoerderer (AS/ES 30 degrees, directly stacked)",
|
||||
"vfc-typ-linienzug-beschreibung": "Route group (mixed GF/VF chain; mode 1 manual / mode 2 target height finished / mode 3 step by step work in progress)",
|
||||
"vfc-typ-linienzug-beschreibung": "Route group (mixed GF/VF chain; mode 1 manual / mode 2 from 3D line with target height / mode 3 from 3D line without target height)",
|
||||
"vfs-schritt6-horizontal": "\n\n6/11: Horizontal intermediate section (0 deg, L=%1 mm)",
|
||||
"vfs-schritt6-steigung": "\n\n6/11: Incline section (%1 deg, L=%2 mm)",
|
||||
"vfs-schritt6-gefaelle": "\n\n6/11: Slope section (%1 deg, L=%2 mm)",
|
||||
@@ -974,7 +1007,7 @@
|
||||
"vfe-step14": "\n\n14/15: Separator (300mm, cur-hz=%1)",
|
||||
"vfe-step15": "\n\n15/15: %1 (end, chained cur-hz=%2)",
|
||||
"vfe-eingefuegt": "\n>>> Etage VarioFoerderer inserted! <<<",
|
||||
"vfl-vwnb-titel": "\n VF LINE PATH - Mode 3: 3D objects step by step (forward reconstruction, work in progress)",
|
||||
"vfl-vwnb-titel": "\n VF LINE PATH - Mode 3: from 3D line WITHOUT target height (forward build)",
|
||||
"vfl-vwnb-aus-seite-menu": "\n\nOUT element - select side:\n 1 - Left\n 2 - Right",
|
||||
"vfl-vwnb-alert-eckwinkel": "No matching arc: corner angle %1 deg is not ~30/60/90.\nPlease adjust the angles of the lines.",
|
||||
"vfl-vwnb-alert-keine-gerade": "Path contains no straight - a chain must begin with a straight.",
|
||||
@@ -1131,6 +1164,56 @@
|
||||
"kreisel-bp-kollision": "\n COLLISION %1: %2 <-> %3 [%4] at X=%5 Y=%6 Z=%7",
|
||||
"kreisel-bp-marker": "\n%1 markers drawn (layer %2).",
|
||||
"exp-kreisel-weichen": "\n[%1] Kreisel switch points: %2 contact(s), %3 collision(s) -> %4",
|
||||
"exp-kreisel-kollision": "\n[%1] WARNING: %2 Kreisel collision(s) - command KREISEL_WEICHEN shows them."
|
||||
"exp-kreisel-kollision": "\n[%1] WARNING: %2 Kreisel collision(s) - command KREISEL_WEICHEN shows them.",
|
||||
"kf-fehler-daten-fehlt": "\nERROR: chain conveyor data not found: %1",
|
||||
"kf-fehler-daten-leer": "\nERROR: chain conveyor data could not be read.",
|
||||
"kf-fehler-block-datei": "\nERROR: block file for %1 not found (expected in data/omniflo/<dimension>/).",
|
||||
"kf-fehler-ks-fehlt": "At least one component is missing KS_EIN or KS_AUS - the chain cannot be linked. Command KF_KS_PRUEFEN shows which block is affected.",
|
||||
"kf-fehler-hoehe-zu-klein": "The installation height is too small: the deflection and drive stations already contribute more height than requested. Please choose a greater height.",
|
||||
"kf-fehler-laenge-unter-min": "The intermediate section would be shorter than permitted. Please choose a greater installation height.",
|
||||
"kf-fehler-laenge-ueber-max": "The intermediate section would be longer than permitted. Please choose a smaller installation height.",
|
||||
"kf-fehler-winkel-null": "The measured installation angle of the intermediate section is horizontal - no height can be gained. Please check the KS positions of the blocks (KF_KS_PRUEFEN).",
|
||||
"kf-fehler-dcl": "Dialog file kettenfoerderer.dcl not found.",
|
||||
"kf-prompt-messpunkt-1": "\nSelect first measuring point (lower reference): ",
|
||||
"kf-prompt-messpunkt-2": "\nSelect second measuring point (upper reference): ",
|
||||
"kf-messung-ergebnis": "\n>>> Measured: height difference dZ = %1 mm (for reference dY = %2 mm).",
|
||||
"kf-konsole-hoehe-hinweis": "\n(enter 0 to measure the height from two points)",
|
||||
"kf-2d-gebaut": "\n>>> Plan view %1 inserted: slope length %2 mm, inclination %3 deg.",
|
||||
"kf-2d-laenge-null": "\nPlan view skipped: the chain has no measurable plan length.",
|
||||
"kf-2d-ks-fehlt": "\nPlan view skipped: %1 has no measurable KS_EIN/KS_AUS.",
|
||||
"kf-prompt-startpunkt": "\nSelect insertion point (KS_EIN of the plan view; the side view is built above it): ",
|
||||
"kf-prompt-drehung": "\nRotation angle of the chain: ",
|
||||
"kf-abgebrochen": "\nCancelled.",
|
||||
"kf-fertig": "\n>>> %1 created: installation height %2 mm, intermediate section %3 mm.",
|
||||
"kf-konsole-variante-header": "\n\nSelect inclined steel conveyor type:",
|
||||
"kf-konsole-option": "\n %1 - %2",
|
||||
"kf-konsole-variante-prompt": "\nInclined steel conveyor type",
|
||||
"kf-konsole-hoehe-prompt": "\nH - installation height of inclined conveyor [mm]",
|
||||
"kf-konsole-verbindung-header": "\n\nSelect connecting elements:",
|
||||
"kf-konsole-verbindung-prompt": "\nConnecting elements",
|
||||
"kf-konsole-farbe-header": "\n\nSelect conveyor colour:",
|
||||
"kf-konsole-farbe-prompt": "\nColour",
|
||||
"kf-konsole-antriebsmotor-header": "\n\nSelect conveyor drive motor:",
|
||||
"kf-konsole-antriebsmotor-prompt": "\nConveyor drive motor",
|
||||
"kf-variante-label": "%1 %2",
|
||||
"kf-variante-label-standard": "%1 %2 (default)",
|
||||
"kf-konsole-movimot-header": "\n\nDrive with Movimot?",
|
||||
"kf-konsole-movimot-prompt": "\nDrive with Movimot",
|
||||
"kf-konsole-steuerung-header": "\n\nWith standard control system?",
|
||||
"kf-konsole-steuerung-prompt": "\nWith standard control system",
|
||||
"kf-pruef-kopf": "\n\n=== KF_KS_PRUEFEN: KS positions of the chain conveyor blocks ===",
|
||||
"kf-pruef-variante": "\n\n--- Variant: %1 ---",
|
||||
"kf-pruef-block": "\n %1: KS_EIN (%2, %3) direction %4 | KS_AUS (%5, %6) direction %7",
|
||||
"kf-pruef-block-fehlt": "\n %1: block file not found.",
|
||||
"kf-pruef-ks-fehlt": "\n %1: KS incomplete - KS_EIN: %2, KS_AUS: %3",
|
||||
"kf-pruef-ks-fehlt-kurz": "\n[KF] KS_EIN/KS_AUS not readable on component: %1 (command KF_KS_PRUEFEN shows details)",
|
||||
"kf-pruef-fehler": "\n Geometry could not be determined: %1",
|
||||
"kf-pruef-geo": "\n Installation angles (deg): deflection %1, intermediate %2, drive %3\n Height contribution (mm): deflection %4, drive %5\n Intermediate section native (mm): dx %6, dy %7",
|
||||
"kf-pruef-ja": "present",
|
||||
"kf-pruef-nein": "MISSING",
|
||||
"kf-edit-waehlen": "\nSelect chain conveyor (KF_n) to edit: ",
|
||||
"kf-edit-kein-kf": "The selected block is not a chain conveyor (KF_n).",
|
||||
"kf-edit-fertig": "\n>>> %1 rebuilt as %2.",
|
||||
"cmd-kettenfoerderer-bearbeiten": "\n>>> Editing chain conveyor %1 ..."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ Edit-Befehl (Doppelklick) zum Neuaufbau liest. Typischer Ablauf: Scanner-
|
||||
Vorlage nachbauen, in BricsCAD von Hand korrigieren/ergaenzen, Zeichnung als
|
||||
DXF speichern und mit diesem Skript die Testdaten aktualisieren.
|
||||
|
||||
Je Wrapper (Felder wie in tests/testdata/object_data.md bzw. mubea.json):
|
||||
Je Wrapper (Felder wie in doc/json-input-lisp.md bzw. mubea.json):
|
||||
|
||||
KREISEL_n -> Kreisel ("function": "insert", x/y/z = Einfuegepunkt,
|
||||
abstand = Mittenabstand AN8-SP8 aus der Blockdefinition,
|
||||
|
||||
@@ -6,7 +6,7 @@ dxf_scan_components.py - Erkennt ILS-/Omniflo-Komponenten in einem FREMDEN DXF.
|
||||
Gedacht fuer Projekt-Zeichnungen, die NICHT von unseren Makros erzeugt wurden
|
||||
(also ohne die Wrapper-Bloecke KREISEL_*, VF_*, GF_*). Das Skript sucht die
|
||||
Bauteile ueber Blocknamen-Muster, rechnet ihre Position in Weltkoordinaten um
|
||||
und schreibt das Ergebnis im JSON-Schema aus tests/testdata/object_data.md -
|
||||
und schreibt das Ergebnis im JSON-Schema aus doc/json-input-lisp.md -
|
||||
also so, dass die Anlage per JSON-Treiber mit den Produktionsmakros
|
||||
nachgebaut werden kann (Vorbild: tests/testdata/mubea.json, das bisher von
|
||||
Hand aus einem DXF abgeleitet wurde).
|
||||
@@ -1697,7 +1697,7 @@ def gf_eintraege_aus_linien(linien, as_liste, kreisel=None, sep_liste=None,
|
||||
def baue_eintraege(treffer, defaults, boegen, weichen,
|
||||
bekannte_bloecke=None, linien=None, kreisel_hoehen=None,
|
||||
kreisel_achsen=None, flach=False):
|
||||
"""Erkannte Vorkommen auf die Schemata aus object_data.md abbilden.
|
||||
"""Erkannte Vorkommen auf die Schemata aus json-input-lisp.md abbilden.
|
||||
|
||||
kreisel_hoehen: Liste (x, y, z) vom Anwender - z gilt fuer den Kreisel,
|
||||
dessen Einfuegepunkt (Eintrag x/y) hoechstens KREISEL_HOEHE_TOL entfernt
|
||||
@@ -2082,7 +2082,7 @@ def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Erkennt ILS-/Omniflo-Komponenten in einem fremden DXF "
|
||||
"und schreibt sie im JSON-Schema aus "
|
||||
"tests/testdata/object_data.md.")
|
||||
"doc/json-input-lisp.md.")
|
||||
parser.add_argument("dxf", help="Quellzeichnung (binaeres oder ASCII-DXF)")
|
||||
parser.add_argument("data_dir", help="Datenverzeichnis mit json/")
|
||||
parser.add_argument("output", help="Ziel-JSON")
|
||||
|
||||
+222
-2
@@ -101,14 +101,36 @@ def get_id(block):
|
||||
# Sprachdatei, da rein Sivas-seitig.
|
||||
GERUEST_TYP_ANZEIGE = sivas_mapping.load_flat_mapping("geruest_typ_anzeige")
|
||||
|
||||
# Kettenfoerderer: Attribut WINKEL fuehrt den Neigungswinkel als nackte Zahl
|
||||
# ("26"/"30"), Sivas-Merkmal 359 erwartet den Optionstext mit Gradzeichen.
|
||||
# Gleiche Bauart und derselbe Grund wie GERUEST_TYP_ANZEIGE.
|
||||
KF_TYP_ANZEIGE = sivas_mapping.load_flat_mapping("kf_typ_anzeige")
|
||||
|
||||
# TeileArt-Spalte der Kettenfoerderer-Zeilen. Fester Wert statt Block-Attribut:
|
||||
# er ist fuer jeden Kettenfoerderer gleich, stuende also an jedem Block nur
|
||||
# redundant herum. Die Erkennung laeuft ueber den Blocknamen
|
||||
# (pattern_kettenfoerderer), nicht ueber TEILEART. Ein Block, der das Attribut
|
||||
# doch mitbringt (Altbestand), hat weiterhin Vorrang.
|
||||
KF_TEILEART = "Schraegfoerderer Stahl"
|
||||
|
||||
SEPARATOR_BEARBEITUNG_ANZEIGE = "ohne HARTCOAT HRC 50 ± 5"
|
||||
|
||||
# Sivas-Merkmale "Streckengruppe - Variofoerderer 001..005 - Hoehe in Meter".
|
||||
# Reihenfolge = Bau-Reihenfolge der Foerdereinheiten in VF_HOEHE_m.
|
||||
VF_HOEHE_MERKMALE = ("4433", "4434", "4435", "4436", "4437")
|
||||
|
||||
|
||||
def geruest_typ_anzeige(wert):
|
||||
"""Wandelt den ASCII-Attributwert GERUEST_TYP in die Sivas-Anzeige um."""
|
||||
return GERUEST_TYP_ANZEIGE.get(wert, wert)
|
||||
|
||||
|
||||
def kf_typ_anzeige(wert):
|
||||
"""Wandelt den Kettenfoerderer-Winkel ("26"/"30") in die Sivas-Anzeige
|
||||
zu Merkmal 359 um ("Schrägförderer Stahl 26°")."""
|
||||
return KF_TYP_ANZEIGE.get(str(wert).strip(), wert)
|
||||
|
||||
|
||||
def ja_nein(flag_1_0):
|
||||
"""Wandelt ein "0"/"1"-Attribut in die Sivas-Anzeige "Ja"/"Nein" um."""
|
||||
return "Ja" if flag_1_0 == "1" else "Nein"
|
||||
@@ -120,14 +142,95 @@ def mm_zu_m(wert_mm):
|
||||
return str(round(safe_float(wert_mm, 0.0) / 1000.0, 3))
|
||||
|
||||
|
||||
# --- AS-/ES-Element (Merkmale 4427-4432) ---------------------------------
|
||||
# Zuordnung komplett in cfg/sivas.cfg ([gefaellestrecke]/[variofoerderer]),
|
||||
# hier stehen nur die Transforms. Die Sivas-Hierarchie ist: 4431/4432
|
||||
# ("AS-Element"/"ES-Element", Ja/Nein) schalten die Unterknoten Winkel
|
||||
# (4427/4429) und Seite (4428/4430) frei.
|
||||
#
|
||||
# Ob ein Element vorhanden ist, entscheidet AUSSCHLIESSLICH WINKEL_AS/
|
||||
# WINKEL_ES: das gemeinsame Strecken-Schema (*strecke-attr-front* in
|
||||
# ssg_core.lsp) laesst den Winkel leer, wenn kein Element gewaehlt wurde.
|
||||
# SEITE_AS/SEITE_ES taugen dafuer NICHT - sie tragen mit "rechts" immer einen
|
||||
# Schema-Vorgabewert. Ohne Element bleiben Winkel UND Seite leer, damit in
|
||||
# Sivas keine Seite unter einem "Nein"-Knoten haengt.
|
||||
|
||||
# Attributwert -> Sivas-Optionswert der Auswahlliste ("30"/"90" -> "30 °"/
|
||||
# "90 °", siehe Merkmalstamm). Wie [geruest_typ_anzeige] in der Config, damit
|
||||
# die exakte Schreibweise ohne Code-Aenderung nachgezogen werden kann.
|
||||
AS_ES_WINKEL_ANZEIGE = sivas_mapping.load_flat_mapping("as_es_winkel_anzeige")
|
||||
|
||||
|
||||
def winkel_text(wert):
|
||||
"""Elementwinkel ganzzahlig normiert ("90.0" -> "90"), ohne Sivas-
|
||||
Anzeigeform. Basis fuer as_es_winkel UND fuer die Gruppierung (dort darf
|
||||
die Anzeigeform keine Rolle spielen). Leerer Wert bleibt leer."""
|
||||
wert = str(wert or "").strip()
|
||||
if not wert:
|
||||
return ""
|
||||
zahl = safe_float(wert, None)
|
||||
return wert if zahl is None else str(int(zahl))
|
||||
|
||||
|
||||
def as_es_vorhanden(winkel):
|
||||
"""Merkmal 4431/4432: "Ja", sobald ein Elementwinkel gesetzt ist."""
|
||||
return "Ja" if winkel_text(winkel) else "Nein"
|
||||
|
||||
|
||||
def as_es_winkel(winkel):
|
||||
"""Merkmal 4427/4429: Elementwinkel in der Sivas-Schreibweise der
|
||||
Auswahlliste (cfg/sivas.cfg [as_es_winkel_anzeige]). Ein Winkel ohne
|
||||
Eintrag dort wird unveraendert (nur ganzzahlig normiert) uebernommen."""
|
||||
winkel = winkel_text(winkel)
|
||||
return AS_ES_WINKEL_ANZEIGE.get(winkel, winkel)
|
||||
|
||||
|
||||
def _seite_text(seite, winkel):
|
||||
"""Gemeinsamer Kern von as_seite/es_seite: Seite nur, wenn es das Element
|
||||
ueberhaupt gibt."""
|
||||
if not winkel_text(winkel):
|
||||
return ""
|
||||
return str(seite or "").strip().lower()
|
||||
|
||||
|
||||
@sivas_mapping.braucht_attribs
|
||||
def as_seite(wert, attribs):
|
||||
"""Merkmal 4428: AS-Seite, aber nur bei vorhandenem AS-Element."""
|
||||
return _seite_text(wert, attribs.get("WINKEL_AS", ""))
|
||||
|
||||
|
||||
@sivas_mapping.braucht_attribs
|
||||
def es_seite(wert, attribs):
|
||||
"""Merkmal 4430: ES-Seite, aber nur bei vorhandenem ES-Element."""
|
||||
return _seite_text(wert, attribs.get("WINKEL_ES", ""))
|
||||
|
||||
|
||||
# --- Transform-Namen, wie sie in cfg/sivas.cfg hinter "|" stehen koennen ---
|
||||
TRANSFORMS = {
|
||||
"ja_nein": ja_nein,
|
||||
"geruest_typ_anzeige": geruest_typ_anzeige,
|
||||
"kf_typ_anzeige": kf_typ_anzeige,
|
||||
"mm_zu_m": mm_zu_m,
|
||||
"as_es_vorhanden": as_es_vorhanden,
|
||||
"as_es_winkel": as_es_winkel,
|
||||
"as_seite": as_seite,
|
||||
"es_seite": es_seite,
|
||||
}
|
||||
|
||||
|
||||
def as_es_signatur(attribs):
|
||||
"""AS-/ES-Anteil des Gruppierungsschluessels (siehe
|
||||
gefaellestrecke_signature). Nutzt dieselben Transforms wie der Export,
|
||||
damit Schluessel und Zeileninhalt nicht auseinanderlaufen: ohne Element
|
||||
ist die Seite leer und darf dann auch nicht trennen."""
|
||||
return (as_es_vorhanden(attribs.get("WINKEL_AS", "")),
|
||||
winkel_text(attribs.get("WINKEL_AS", "")),
|
||||
as_seite(attribs.get("SEITE_AS", ""), attribs),
|
||||
as_es_vorhanden(attribs.get("WINKEL_ES", "")),
|
||||
winkel_text(attribs.get("WINKEL_ES", "")),
|
||||
es_seite(attribs.get("SEITE_ES", ""), attribs))
|
||||
|
||||
|
||||
def streckengruppe_objekt_text(attribs):
|
||||
"""Merkmal 4300 "Streckengruppe": "mehrere Objekte", wenn der Block ein
|
||||
kombinierter Streckengruppe-Block (Gefaelle+Vario, TYP-Attribut
|
||||
@@ -191,12 +294,54 @@ def eckrad_signature(block):
|
||||
)
|
||||
|
||||
|
||||
def kettenfoerderer_signature(block):
|
||||
"""
|
||||
Schluessel zur Gruppierung gleichartiger Kettenfoerderer (KF_n): baugleiche
|
||||
Bloecke landen in EINER Sivas-Zeile, deren Anzahl das Merkmal 353 ("Anzahl
|
||||
der gleichen Schraegfoerderer") traegt.
|
||||
|
||||
In den Schluessel gehoert JEDES Attribut, aus dem ein Merkmal der Zeile
|
||||
entsteht - sonst verschmelzen zwei unterschiedlich ausgefuehrte Foerderer
|
||||
zu einer Zeile, und die Merkmale des ERSTEN Blocks gelten fuer beide
|
||||
(gleiche Ueberlegung wie bei gefaellestrecke_signature/as_es_signatur).
|
||||
Die Kommentare nennen darum je Attribut die Merkmalnummer; einzige
|
||||
Ausnahme ist 353, das erst aus der Gruppengroesse entsteht.
|
||||
|
||||
Das ist zugleich die Voraussetzung dafuer, dass items_zusammenfassen (fuer
|
||||
die _zusammengefasst.csv) zwei KF-Zeilen NIE verschmelzen kann: gleiche
|
||||
Merkmale wuerden schon hier dieselbe Gruppe ergeben. Sonst wuerde dort
|
||||
"anzahl" addiert, waehrend 353 unveraendert stehen bliebe.
|
||||
|
||||
Die Laenge des Zwischenstuecks (L_KF_mm) ist eine FOLGE der Einbauhoehe und
|
||||
steht darum nicht eigens im Schluessel.
|
||||
"""
|
||||
attribs = block.get("attribs", {})
|
||||
return (
|
||||
attribs.get("WINKEL", "26"), # 359
|
||||
attribs.get("STANDARD_STEUERUNG", "0"), # 361
|
||||
attribs.get("FOERDERERTYP", ""), # 350
|
||||
attribs.get("H_EINBAUHOEHE_mm", "0"), # 360
|
||||
attribs.get("FARBE", ""), # 354
|
||||
attribs.get("ANTRIEBSMOTOR", ""), # 355
|
||||
attribs.get("ANTRIEBSART", ""), # 357
|
||||
attribs.get("MOVIMOT", "0"), # 356
|
||||
attribs.get("VERBINDUNGSELEMENTE", "Nein"), # 391
|
||||
attribs.get("ARTINR", ""),
|
||||
)
|
||||
|
||||
|
||||
def gefaellestrecke_signature(block):
|
||||
"""
|
||||
Schluessel zur Gruppierung gleichartiger Gefaellestrecken: Bloecke mit
|
||||
identischen Massen (Hoehe, Laenge, Winkel, Separatoren, Scanner, Typ,
|
||||
Geruest fuer Einzelmodul/Geruestoption) landen in derselben Sivas-Zeile -
|
||||
nur IDs/Bezeichnung unterscheiden sich.
|
||||
Geruest fuer Einzelmodul/Geruestoption, AS-/ES-Element) landen in
|
||||
derselben Sivas-Zeile - nur IDs/Bezeichnung unterscheiden sich.
|
||||
|
||||
AS-/ES-Element (Merkmale 4427-4432) gehoeren mit in den Schluessel: die
|
||||
Merkmale der Zeile entstehen aus dem ERSTEN Block der Gruppe, zwei sonst
|
||||
baugleiche Gefaellestrecken mit AS links bzw. AS rechts wuerden sonst zu
|
||||
einer Zeile mit nur einer der beiden Seiten verschmelzen (siehe
|
||||
as_es_signatur).
|
||||
"""
|
||||
attribs = block.get("attribs", {})
|
||||
return (
|
||||
@@ -209,6 +354,7 @@ def gefaellestrecke_signature(block):
|
||||
attribs.get("TYP", "Gefaellestrecke"),
|
||||
attribs.get("GERUEST_EINZELMODUL", "0"),
|
||||
attribs.get("GERUEST_TYP", "Schoenenberger Geruest"),
|
||||
as_es_signatur(attribs),
|
||||
)
|
||||
|
||||
|
||||
@@ -292,6 +438,20 @@ def build_variofoerderer_details(block):
|
||||
details["4354"] = vf_richtung[0].lower() if vf_richtung else ""
|
||||
details["4386"] = str(int(vf_winkel[0])) if vf_winkel else ""
|
||||
|
||||
# Hoehe je Foerdereinheit (4433-4437, "Variofoerderer 001-005 - Hoehe in
|
||||
# Meter"). Quelle ist das Attribut VF_HOEHE_m: eine kommagetrennte Liste
|
||||
# in Bau-Reihenfolge, je Eintrag der Mittelwert aus KS_EIN der
|
||||
# Umlenkstation und KS_AUS der Motorstation (siehe vf-vfhoehe-anfang/-ende
|
||||
# in Lisp/vf_core.lsp). Einheit Meter, 3 Nachkommastellen - wie L_VF_m.
|
||||
#
|
||||
# Mehr als fuenf Foerdereinheiten kann Sivas hier nicht abbilden; die
|
||||
# ueberzaehligen werden bewusst weggelassen statt zusammengefasst, damit
|
||||
# kein Merkmal einen erfundenen Wert traegt. Fehlende Eintraege bleiben
|
||||
# ganz weg (kein leeres Merkmal).
|
||||
vf_hoehen = parse_float_list(attribs.get("VF_HOEHE_m", ""))
|
||||
for nummer, hoehe in zip(VF_HOEHE_MERKMALE, vf_hoehen):
|
||||
details[nummer] = "%.3f" % hoehe
|
||||
|
||||
return {k: str(v) for k, v in details.items()}
|
||||
|
||||
|
||||
@@ -299,6 +459,7 @@ SIVAS_MAPPING_KREISEL = sivas_mapping.load_section_mapping("kreisel")
|
||||
SIVAS_MAPPING_ECKRAD = sivas_mapping.load_section_mapping("eckrad")
|
||||
SIVAS_MAPPING_GERUEST = sivas_mapping.load_section_mapping("geruest")
|
||||
SIVAS_MAPPING_WEICHEN = sivas_mapping.load_section_mapping("weichen")
|
||||
SIVAS_MAPPING_KETTENFOERDERER = sivas_mapping.load_section_mapping("kettenfoerderer")
|
||||
|
||||
|
||||
def build_kreisel_details(block):
|
||||
@@ -326,6 +487,21 @@ def build_eckrad_details(block):
|
||||
return sivas_mapping.anwenden(SIVAS_MAPPING_ECKRAD, attribs, TRANSFORMS)
|
||||
|
||||
|
||||
def build_kettenfoerderer_details(block, anzahl=1):
|
||||
"""Merkmale-Dict fuer eine Gruppe baugleicher Kettenfoerderer (KF_n,
|
||||
Lisp/KettenFoerderer.lsp).
|
||||
|
||||
350/359/354/356/360/391 kommen flach aus cfg/sivas.cfg [kettenfoerderer].
|
||||
353 ("Anzahl der gleichen Schraegfoerderer") entsteht erst hier aus der
|
||||
Gruppengroesse und kann darum nicht im Mapping stehen - gleiche Bauart wie
|
||||
3510/3512 beim Kreisel.
|
||||
"""
|
||||
attribs = block.get("attribs", {})
|
||||
details = sivas_mapping.anwenden(SIVAS_MAPPING_KETTENFOERDERER, attribs, TRANSFORMS)
|
||||
details["353"] = str(anzahl)
|
||||
return details
|
||||
|
||||
|
||||
# def build_geruest_details(block):
|
||||
#"""Merkmale-Dict fuer eine GR_-Geruest-Baugruppe (siehe pattern_geruest in
|
||||
#cfg/export.cfg, GeruestInsert.lsp *geruest-attrib-defs*). ARTINR/
|
||||
@@ -444,6 +620,8 @@ def process_blocks(blocks, anzahl_weichen_ils=0):
|
||||
btmt_beladung_ids = [] # IDs aller BTMT-Beladung*-Bloecke (eine gruppierte Zeile)
|
||||
btmt_entladung_ids = [] # IDs aller SC_Entladung*-Bloecke (eine gruppierte Zeile)
|
||||
geruest_list = [] # Liste von GR_-Geruest-Baugruppenbloecken, je einer Zeile
|
||||
# Kettenfoerderer: kettenfoerderer_signature(block) -> {"block", "ids", "anzahl"}
|
||||
kettenfoerderer_groups = {}
|
||||
|
||||
counters = {
|
||||
"anzahl_kreisel": 0,
|
||||
@@ -466,6 +644,7 @@ def process_blocks(blocks, anzahl_weichen_ils=0):
|
||||
"anzahl_btbeladung": 0,
|
||||
"anzahl_abwurfstationen": 0,
|
||||
"anzahl_geruest": 0,
|
||||
"anzahl_kettenfoerderer": 0,
|
||||
}
|
||||
|
||||
for block in blocks:
|
||||
@@ -515,6 +694,22 @@ def process_blocks(blocks, anzahl_weichen_ils=0):
|
||||
counters["anzahl_geruest"] += 1
|
||||
continue
|
||||
|
||||
# --- Kettenfoerderer / Schraegfoerderer Stahl (KF_n) ---
|
||||
# MUSS vor dem allgemeinen Omniflo-Zweig stehen: die KF-Baugruppe
|
||||
# traegt TEILEART "Omniflo Kettenfoerderer ..." und wuerde dort sonst
|
||||
# ueber ARTINR aufgeloest - ihre eigenen Merkmale (350/353/354/356/
|
||||
# 359/360/391) gingen dabei verloren. Anders als das Geruest werden
|
||||
# BAUGLEICHE Foerderer zu einer Zeile zusammengefasst, weil Merkmal
|
||||
# 353 genau diese Stueckzahl verlangt.
|
||||
if matches_any(bname, BLOCKPATTERNS.get("pattern_kettenfoerderer", [])):
|
||||
sig = kettenfoerderer_signature(block)
|
||||
if sig not in kettenfoerderer_groups:
|
||||
kettenfoerderer_groups[sig] = {"block": block, "ids": [], "anzahl": 0}
|
||||
kettenfoerderer_groups[sig]["anzahl"] += 1
|
||||
kettenfoerderer_groups[sig]["ids"].append(get_id(block))
|
||||
counters["anzahl_kettenfoerderer"] += 1
|
||||
continue
|
||||
|
||||
# --- Omniflo Gerade (AP110) ---
|
||||
# VOR dem allgemeinen Omniflo-Zweig: Geraden tragen ggf. ebenfalls
|
||||
# TEILEART "Omniflo ...", brauchen aber die Laengensumme.
|
||||
@@ -781,6 +976,31 @@ def process_blocks(blocks, anzahl_weichen_ils=0):
|
||||
})
|
||||
nr += 1
|
||||
|
||||
# Kettenfoerderer / Schraegfoerderer Stahl (KF_n) - eine Zeile je Gruppe
|
||||
# BAUGLEICHER Foerderer, deren Groesse als Merkmal 353 mitgefuehrt wird.
|
||||
# Die Sivasnr kommt - wie beim Geruest - aus dem ARTINR-Attribut (gepflegt
|
||||
# als "sivas_id" je Variante in data/json/kettenfoerderer.json); ist dort
|
||||
# nichts hinterlegt, bleibt die Spalte leer und die Zeile traegt allein
|
||||
# ihre Merkmale. Die drei Bausteine des Foerderers (Umlenkstation,
|
||||
# skaliertes Zwischenstueck, Antriebsstation) bekommen KEINE eigenen
|
||||
# Zeilen - der Schraegfoerderer ist in Sivas EIN Artikel.
|
||||
for gruppe in kettenfoerderer_groups.values():
|
||||
block = gruppe["block"]
|
||||
attribs = block.get("attribs", {})
|
||||
items.append({
|
||||
"nr": nr,
|
||||
"teileart": attribs.get("TEILEART") or attribs.get("FOERDERERTYP") or KF_TEILEART,
|
||||
"sivasnr": attribs.get("ARTINR", ""),
|
||||
"sivasnr_quoted": True,
|
||||
"bezeichnung": attribs.get("Bezeichnung", ""),
|
||||
"dispgruppe": 20,
|
||||
"anzahl": gruppe["anzahl"],
|
||||
"laenge_mm": attribs.get("L_KF_mm", ""),
|
||||
"ids": gruppe["ids"],
|
||||
"details": build_kettenfoerderer_details(block, gruppe["anzahl"]),
|
||||
})
|
||||
nr += 1
|
||||
|
||||
# VarioFoerderer-Compound-Bloecke (VF_N) - je Block eine eigene Zeile mit
|
||||
# vollstaendigen Gefaelle-/Angetrieben-Teilgruppen (immer TYP "Streckengruppe").
|
||||
for block in vario_list:
|
||||
|
||||
@@ -9,7 +9,7 @@ Hintergrund: data/polylines.dxf enthaelt 5 LWPOLYLINE-Objekte auf Layer
|
||||
"Z-6" - Streckenzuege, die reale Foerderer-Pfade der HundM05-Zeichnung
|
||||
nachbilden (siehe data/polylines.md, von Hand ausgewertet). Dieses Skript
|
||||
macht dieselbe Auswertung reproduzierbar und maschinenlesbar, als Grundlage
|
||||
fuer einen neuen Testfall (siehe tests/testdata/object_data.md fuer das
|
||||
fuer einen neuen Testfall (siehe doc/json-input-lisp.md fuer das
|
||||
allgemeine JSON-Schema).
|
||||
|
||||
Eine Polylinie kann auf einer gekippten Ebene liegen (Gruppencode
|
||||
|
||||
+24
-4
@@ -97,14 +97,31 @@ def load_flat_mapping(section, cfg_path=None):
|
||||
return {}
|
||||
|
||||
|
||||
def braucht_attribs(fn):
|
||||
"""Markiert einen Transform, der NEBEN seinem Rohwert auch das komplette
|
||||
Attribut-Dict des Blocks braucht - er wird dann als fn(wert, attribs)
|
||||
aufgerufen statt als fn(wert).
|
||||
|
||||
Noetig fuer Merkmale, deren Wert von einem ZWEITEN Attribut abhaengt: die
|
||||
AS-/ES-Seite (4428/4430) darf nur gefuellt werden, wenn der zugehoerige
|
||||
WINKEL_AS/WINKEL_ES ueberhaupt ein Element ausweist. Ohne diese Klammer
|
||||
muessten solche Merkmale wieder aus der Config heraus in Python-Code
|
||||
wandern - genau das soll sivas.cfg vermeiden.
|
||||
"""
|
||||
fn.braucht_attribs = True
|
||||
return fn
|
||||
|
||||
|
||||
def anwenden(section_mapping, attribs, transforms):
|
||||
"""Wendet eine per load_section_mapping() gelesene Zuordnung auf ein
|
||||
Block-Attribut-Dict an.
|
||||
|
||||
transforms: dict transform_name -> Funktion(wert) -> wert. Ein in der
|
||||
Config genannter, aber hier unbekannter Transform-Name wird ignoriert
|
||||
(Rohwert bleibt unveraendert) statt abzubrechen - ein Tippfehler in
|
||||
sivas.cfg darf den Export nicht zum Stillstand bringen.
|
||||
transforms: dict transform_name -> Funktion(wert) -> wert. Ein mit
|
||||
@braucht_attribs markierter Transform wird stattdessen als
|
||||
fn(wert, attribs) aufgerufen und sieht damit die uebrigen Attribute des
|
||||
Blocks. Ein in der Config genannter, aber hier unbekannter Transform-Name
|
||||
wird ignoriert (Rohwert bleibt unveraendert) statt abzubrechen - ein
|
||||
Tippfehler in sivas.cfg darf den Export nicht zum Stillstand bringen.
|
||||
|
||||
Rueckgabe: dict merkmal -> wert. Ohne Transform wird der Rohwert zu str()
|
||||
gewandelt (bisheriges Verhalten der build_*_details-Funktionen: alles
|
||||
@@ -124,6 +141,9 @@ def anwenden(section_mapping, attribs, transforms):
|
||||
if transform:
|
||||
fn = transforms.get(transform)
|
||||
if fn is not None:
|
||||
if getattr(fn, "braucht_attribs", False):
|
||||
ergebnis[merkmal] = fn(wert, attribs)
|
||||
else:
|
||||
ergebnis[merkmal] = fn(wert)
|
||||
continue
|
||||
ergebnis[merkmal] = str(wert)
|
||||
|
||||
@@ -322,6 +322,19 @@ class ProtokollSink(Sink):
|
||||
self.add("point_abs", "getpoint Startpunkt der Kette (absoluter "
|
||||
"Weltpunkt, einziger Anker der ganzen Kette)", wert=punkt)
|
||||
|
||||
def as_achse(self, punkt):
|
||||
# Zweiter absoluter Punkt - gibt NUR die Richtung der Zufuehrung,
|
||||
# der Startpunkt bleibt der Sitz des AS-Elements. "nil" heisst: die
|
||||
# Frage wurde gestellt und bewusst uebergangen (die Kettenrichtung
|
||||
# kommt dann aus dem naechsten Klick).
|
||||
if punkt is None:
|
||||
self.add("nil", "getpoint Zufuehrungsachse - 2. Punkt: keiner "
|
||||
"gewaehlt, Richtung kommt aus dem naechsten Klick")
|
||||
else:
|
||||
self.add("point_abs", "getpoint Zufuehrungsachse - 2. Punkt "
|
||||
"(gibt nur die Richtung, der Startpunkt bleibt)",
|
||||
wert=punkt)
|
||||
|
||||
def linie(self, dl, hz, frage):
|
||||
was = _vorlage(_LINIE_TEXT, frage)
|
||||
if hz is None:
|
||||
|
||||
@@ -287,6 +287,12 @@ class Sink(object):
|
||||
def praeambel_start(self):
|
||||
"""Kettenkopf beginnt (Startpunkt/Starthoehe/AS-Element)."""
|
||||
|
||||
def as_achse(self, punkt):
|
||||
"""Zufuehrungsachse des AS-Elements verbraucht (2. Punkt, gibt nur
|
||||
die Richtung). punkt = [x, y, z] oder None, wenn die Kette bewusst
|
||||
OHNE Achse gebaut wurde. Wird gar nicht gerufen, wenn das Journal
|
||||
diese Frage noch nicht kennt (vor 2026-10-21)."""
|
||||
|
||||
def praeambel_ende(self):
|
||||
"""Kettenkopf fertig."""
|
||||
|
||||
@@ -518,9 +524,31 @@ class Kern(object):
|
||||
self.sink.real_feld("hoehe", self.real(), "start_hoehe")
|
||||
if self._ja("as", "AS-Element setzen", "as"):
|
||||
self.sink.roh_feld("as_winkel", self.nimm("STR"), "as_winkel")
|
||||
# Drei Journal-Formate, unterscheidbar an der Eintragsart (siehe
|
||||
# vfl-frage-as-winkel-seite-oder-achse):
|
||||
# PT direkt nach dem Winkel -> Alt-Achse ohne Seitenfrage
|
||||
# (30-Grad-Element, 2026-10-14
|
||||
# bis 10-20); die Seite wurde
|
||||
# damals aus der Lage des
|
||||
# naechsten Punkts ermittelt.
|
||||
# STR, dann PT bzw. NIL -> Format ab 2026-10-21: Seite UND
|
||||
# (optionale) Zufuehrungsachse.
|
||||
# STR, dann etwas anderes -> Altbestand ohne Achsenfrage.
|
||||
if self.art() == "PT":
|
||||
self._as_achse()
|
||||
else:
|
||||
self._code("as_seite", SEITE, "AS-Seite", "as_seite")
|
||||
if self.art() == "PT":
|
||||
self._as_achse()
|
||||
elif self.art() == "NIL":
|
||||
self.nimm("NIL")
|
||||
self.sink.as_achse(None)
|
||||
self.sink.praeambel_ende()
|
||||
|
||||
def _as_achse(self):
|
||||
"""Zufuehrungsachse: zweiter Punkt, der NUR die Richtung gibt."""
|
||||
self.sink.as_achse([float(v) for v in self.nimm("PT").split(",")])
|
||||
|
||||
def sektionen(self):
|
||||
while self.pos < len(self.tok):
|
||||
label = self.nimm("STEP")
|
||||
|
||||
@@ -87,6 +87,11 @@ def tokens_aus_protokoll(eintraege):
|
||||
tok.append(("STR", str(e["wert"])))
|
||||
elif typ == "step":
|
||||
tok.append(("STEP", str(e["wert"])))
|
||||
elif typ == "nil":
|
||||
# Eine Frage, die gestellt und bewusst uebergangen wurde (bisher
|
||||
# nur die Zufuehrungsachse des AS-Elements) - im Journal ein
|
||||
# "NIL"-Eintrag ohne Wert.
|
||||
tok.append(("NIL", None))
|
||||
else:
|
||||
raise ValueError("unbekannter Eintragstyp: %r" % typ)
|
||||
return tok
|
||||
@@ -255,6 +260,14 @@ class SpecSink(Sink):
|
||||
def punkt_abs(self, punkt):
|
||||
self.ziel["punkt"] = punkt
|
||||
|
||||
def as_achse(self, punkt):
|
||||
# Zufuehrungsachse des AS-Elements. "ohne" ist NICHT dasselbe wie ein
|
||||
# fehlendes Feld: "ohne" heisst "die Frage wurde gestellt und bewusst
|
||||
# uebergangen" (NIL im Journal), ein fehlendes Feld heisst "das
|
||||
# Journal kennt die Frage gar nicht" (vor 2026-10-21). Nur so bleibt
|
||||
# der Rundlauf Journal -> Spec -> Journal tokengleich.
|
||||
self.ziel["as_achse"] = punkt if punkt is not None else "ohne"
|
||||
|
||||
def linie(self, dl, hz, frage):
|
||||
self.ziel["dl"] = dl
|
||||
if hz is not None:
|
||||
@@ -398,6 +411,14 @@ class SpecSchreiber(object):
|
||||
self.raus("STR", str(self.feld(start, "as_winkel")))
|
||||
self.raus("STR", code_aus_wert(SEITE, self.feld(start, "as_seite"),
|
||||
"as_seite"))
|
||||
# Optional, Gegenstueck zu SpecSink.as_achse und zu
|
||||
# vsp-praeambel in Lisp/vf_spec.lsp: Liste -> PT, "ohne" -> NIL,
|
||||
# fehlt -> gar kein Token (Journalformat vor 2026-10-21).
|
||||
achse = start.get("as_achse")
|
||||
if isinstance(achse, (list, tuple)):
|
||||
self.raus("PT", ",".join(_zahl(v) for v in achse))
|
||||
elif achse == "ohne":
|
||||
self.raus("NIL", None)
|
||||
|
||||
def sektion(self, sek, erster, naechste=None):
|
||||
label = self.feld(sek, "glied")
|
||||
@@ -641,6 +662,11 @@ def flache_objekte(spec_id, spec, kopf_extra=None):
|
||||
if start["as"]:
|
||||
kopf["as_winkel"] = start["as_winkel"]
|
||||
kopf["as_seite"] = start["as_seite"]
|
||||
# Nur schreiben, wenn vorhanden - ein fehlendes Feld ist die
|
||||
# bewusste Aussage "Journalformat ohne Achsenfrage" (siehe
|
||||
# SpecSink.as_achse), kein Datenverlust.
|
||||
if "as_achse" in start:
|
||||
kopf["as_achse"] = start["as_achse"]
|
||||
for k, v in (kopf_extra or collections.OrderedDict()).items():
|
||||
kopf[k] = v
|
||||
objekte.append(kopf)
|
||||
|
||||
+62
-62
@@ -118,7 +118,7 @@
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00030">
|
||||
<Macro>
|
||||
<Name>3D Objekte stueckweise (in Arbeit)</Name>
|
||||
<Name>aus 3D Linie ohne Zielhoehe</Name>
|
||||
<Command>^C^C(ssg-ensure "VarioFoerderer") LinienzugVarioFoerdererStueckweise</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
@@ -401,7 +401,7 @@
|
||||
<MenuMacro UID="MM_00095">
|
||||
<Macro>
|
||||
<Name>KettenFoerderer</Name>
|
||||
<Command>^C^C(ssg-ensure "OmniModulInsert") OMNI_KettenFoerderer</Command>
|
||||
<Command>^C^C(ssg-ensure "KettenFoerderer") KETTENFOERDERER</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00096">
|
||||
@@ -411,23 +411,23 @@
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00098">
|
||||
<Macro>
|
||||
<Name>TV W-W kpl</Name>
|
||||
<Command>^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_W</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00099">
|
||||
<Macro>
|
||||
<Name>TV W-AP110 kpl</Name>
|
||||
<Command>^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_AP110</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00100">
|
||||
<MenuMacro UID="MM_00099">
|
||||
<Macro>
|
||||
<Name>TV W-AP60 oben kpl.</Name>
|
||||
<Command>^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_AP60</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00100">
|
||||
<Macro>
|
||||
<Name>TV W-W kpl</Name>
|
||||
<Command>^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_W</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00101">
|
||||
<Macro>
|
||||
<Name>TV W-AP110-W kpl</Name>
|
||||
@@ -436,8 +436,8 @@
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00102">
|
||||
<Macro>
|
||||
<Name>TV W-AP oben kpl</Name>
|
||||
<Command>^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_AP</Command>
|
||||
<Name>TV W-AP60 kpl</Name>
|
||||
<Command>^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_AP60_KPL</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00103">
|
||||
@@ -460,55 +460,55 @@
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00106">
|
||||
<Macro>
|
||||
<Name>Anschlag AP-Ende fuer Spulenzug</Name>
|
||||
<Name>Anschlag AP-Ende für Spulenzug</Name>
|
||||
<Command>^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_ANSCHLAG</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00107">
|
||||
<Macro>
|
||||
<Name>TV-A fuer AP110/AP60 kpl</Name>
|
||||
<Name>TV-A für AP110/AP60 kpl</Name>
|
||||
<Command>^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_A_AP110_AP60</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00108">
|
||||
<Macro>
|
||||
<Name>TV-A fuer AP60/ST</Name>
|
||||
<Name>TV-A für AP60/ST</Name>
|
||||
<Command>^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_A_AP60_ST</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00109">
|
||||
<Macro>
|
||||
<Name>TV-A fuer AP110/ST kpl</Name>
|
||||
<Name>TV-A für AP110/ST kpl</Name>
|
||||
<Command>^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_A_AP110_ST</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00110">
|
||||
<Macro>
|
||||
<Name>TV-SW II fuer SW-SW</Name>
|
||||
<Name>TV-SW II für SW-SW</Name>
|
||||
<Command>^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_II_SW_SW</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00111">
|
||||
<Macro>
|
||||
<Name>TV-SW III fuer SW-AP110-SW</Name>
|
||||
<Name>TV-SW III für SW-AP110-SW</Name>
|
||||
<Command>^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_III_AP110_SW</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00112">
|
||||
<Macro>
|
||||
<Name>TV-SW III fuer SW-AP110</Name>
|
||||
<Command>^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_III_AP110</Command>
|
||||
<Name>TV-SW I für SW-AP110</Name>
|
||||
<Command>^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_I_AP110</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00113">
|
||||
<Macro>
|
||||
<Name>TV-SW IV fuer Anschluss SW-AP60</Name>
|
||||
<Name>TV-SW IV für Anschluss SW-AP60</Name>
|
||||
<Command>^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_IV_AP60</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00114">
|
||||
<Macro>
|
||||
<Name>TV-SW IV fuer SW-ST</Name>
|
||||
<Name>TV-SW IV für SW-ST</Name>
|
||||
<Command>^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_IV_ST</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
@@ -872,61 +872,61 @@
|
||||
<Command>^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_showroom_ils.lsp")) (c:TEST_SHOWROOM_ILS)</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00210">
|
||||
<MenuMacro UID="MM_00189">
|
||||
<Macro>
|
||||
<Name>Testanlage test_system</Name>
|
||||
<Command>^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_test_system.lsp")) (c:TEST_TEST_SYSTEM)</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00189">
|
||||
<MenuMacro UID="MM_00190">
|
||||
<Macro>
|
||||
<Name>KS 2D/3D pruefen (CSV)</Name>
|
||||
<Command>^C^C(load (strcat (getenv "DXFMAKRO") "/Lisp/ks_pruefung.lsp")) KS_PRUEFEN</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00201">
|
||||
<MenuMacro UID="MM_00202">
|
||||
<Macro>
|
||||
<Name>Kreisel bearbeiten</Name>
|
||||
<Command>(ssg-ensure "KreiselInsert") KreiselEdit</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00202">
|
||||
<MenuMacro UID="MM_00203">
|
||||
<Macro>
|
||||
<Name>Eckrad bearbeiten</Name>
|
||||
<Command>(ssg-ensure "KreiselInsert") EckradEdit</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00203">
|
||||
<MenuMacro UID="MM_00204">
|
||||
<Macro>
|
||||
<Name>Omniflo Element bearbeiten</Name>
|
||||
<Command>(ssg-ensure "OmniModulInsert") OMNI_EDIT</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00204">
|
||||
<MenuMacro UID="MM_00205">
|
||||
<Macro>
|
||||
<Name>Gefaellestrecke bearbeiten</Name>
|
||||
<Command>(ssg-ensure "Gefaellestrecke") GEFAELLESTRECKE_EDIT</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00205">
|
||||
<MenuMacro UID="MM_00206">
|
||||
<Macro>
|
||||
<Name>VarioFoerderer bearbeiten</Name>
|
||||
<Command>(ssg-ensure "VarioFoerderer") VARIOFOERDERER_EDIT</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00206">
|
||||
<MenuMacro UID="MM_00207">
|
||||
<Macro>
|
||||
<Name>TRO-Marker bearbeiten</Name>
|
||||
<Command>(ssg-ensure "Tro_Edit") TRO_EDIT</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00207">
|
||||
<MenuMacro UID="MM_00208">
|
||||
<Macro>
|
||||
<Name>Verbindung bearbeiten</Name>
|
||||
<Command>(ssg-ensure "Connection_Edit") CONNECTION_EDIT</Command>
|
||||
</Macro>
|
||||
</MenuMacro>
|
||||
<MenuMacro UID="MM_00209">
|
||||
<MenuMacro UID="MM_00210">
|
||||
<Macro>
|
||||
<Name>SSG Bearbeiten (Auto)</Name>
|
||||
<Command>(ssg-ensure "SSG_LIB_Commands") SSG_BLOCKEDIT</Command>
|
||||
@@ -1088,7 +1088,7 @@
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>3D Objekte stueckweise (in Arbeit)</NameRef>
|
||||
<NameRef>aus 3D Linie ohne Zielhoehe</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00030"/>
|
||||
</MenuItem>
|
||||
@@ -1150,7 +1150,7 @@
|
||||
<PopMenuRef pUID="PM_00084"/>
|
||||
<PopMenuRef pUID="PM_00088"/>
|
||||
<PopMenuItem>
|
||||
<NameRef>~KettenFoerderer</NameRef>
|
||||
<NameRef>KettenFoerderer</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00095"/>
|
||||
</MenuItem>
|
||||
@@ -1430,109 +1430,109 @@
|
||||
<PopMenu UID="PM_00097">
|
||||
<Name>Verbinder</Name>
|
||||
<PopMenuItem>
|
||||
<NameRef>~TV W-W kpl</NameRef>
|
||||
<NameRef>TV W-AP110 kpl</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00098"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>~TV W-AP110 kpl</NameRef>
|
||||
<NameRef>TV W-AP60 oben kpl.</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00099"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>~TV W-AP60 oben kpl.</NameRef>
|
||||
<NameRef>TV W-W kpl</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00100"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>~TV W-AP110-W kpl</NameRef>
|
||||
<NameRef>TV W-AP110-W kpl</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00101"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>~TV W-AP oben kpl</NameRef>
|
||||
<NameRef>TV W-AP60 kpl</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00102"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>~TV 80</NameRef>
|
||||
<NameRef>TV 80</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00103"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>~TV 50</NameRef>
|
||||
<NameRef>TV 50</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00104"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>~Endplatte Al-Profil AP schraubbar</NameRef>
|
||||
<NameRef>Endplatte Al-Profil AP schraubbar</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00105"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>~Anschlag AP-Ende fuer Spulenzug</NameRef>
|
||||
<NameRef>Anschlag AP-Ende für Spulenzug</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00106"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>~TV-A fuer AP110/AP60 kpl</NameRef>
|
||||
<NameRef>TV-A für AP110/AP60 kpl</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00107"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>~TV-A fuer AP60/ST</NameRef>
|
||||
<NameRef>TV-A für AP60/ST</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00108"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>~TV-A fuer AP110/ST kpl</NameRef>
|
||||
<NameRef>TV-A für AP110/ST kpl</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00109"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>~TV-SW II fuer SW-SW</NameRef>
|
||||
<NameRef>TV-SW II für SW-SW</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00110"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>~TV-SW III fuer SW-AP110-SW</NameRef>
|
||||
<NameRef>TV-SW III für SW-AP110-SW</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00111"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>~TV-SW III fuer SW-AP110</NameRef>
|
||||
<NameRef>TV-SW I für SW-AP110</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00112"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>~TV-SW IV fuer Anschluss SW-AP60</NameRef>
|
||||
<NameRef>TV-SW IV für Anschluss SW-AP60</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00113"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>~TV-SW IV fuer SW-ST</NameRef>
|
||||
<NameRef>TV-SW IV für SW-ST</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00114"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>~Muffe</NameRef>
|
||||
<NameRef>Muffe</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00115"/>
|
||||
</MenuItem>
|
||||
@@ -1930,66 +1930,66 @@
|
||||
<PopMenuItem>
|
||||
<NameRef>Testanlage test_system</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00210"/>
|
||||
<MacroRef MenuMacroID="MM_00189"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>KS 2D/3D pruefen (CSV)</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00189"/>
|
||||
<MacroRef MenuMacroID="MM_00190"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
</PopMenu>
|
||||
<PopMenu UID="PM_00200">
|
||||
<PopMenu UID="PM_00201">
|
||||
<Alias>POP501</Alias>
|
||||
<Name>SSG_LIB Edit Context</Name>
|
||||
<PopMenuItem>
|
||||
<NameRef>Kreisel bearbeiten</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00201"/>
|
||||
<MacroRef MenuMacroID="MM_00202"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Eckrad bearbeiten</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00202"/>
|
||||
<MacroRef MenuMacroID="MM_00203"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Omniflo Element bearbeiten</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00203"/>
|
||||
<MacroRef MenuMacroID="MM_00204"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Gefaellestrecke bearbeiten</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00204"/>
|
||||
<MacroRef MenuMacroID="MM_00205"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>VarioFoerderer bearbeiten</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00205"/>
|
||||
<MacroRef MenuMacroID="MM_00206"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>TRO-Marker bearbeiten</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00206"/>
|
||||
<MacroRef MenuMacroID="MM_00207"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem>
|
||||
<NameRef>Verbindung bearbeiten</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00207"/>
|
||||
<MacroRef MenuMacroID="MM_00208"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
<PopMenuItem IsSeparator="true"/>
|
||||
<PopMenuItem>
|
||||
<NameRef>SSG Bearbeiten (Auto)</NameRef>
|
||||
<MenuItem>
|
||||
<MacroRef MenuMacroID="MM_00209"/>
|
||||
<MacroRef MenuMacroID="MM_00210"/>
|
||||
</MenuItem>
|
||||
</PopMenuItem>
|
||||
</PopMenu>
|
||||
|
||||
@@ -158,6 +158,11 @@
|
||||
(ssg-ensure "export")
|
||||
(ssg-ensure "external_call")
|
||||
(ssg-ensure "OmniModulInsert")
|
||||
;; Kettenfoerderer vorladen statt lazy: der erste Menueklick musste sonst
|
||||
;; das Laden des Moduls mitbezahlen, der Dialog erschien dadurch spuerbar
|
||||
;; verzoegert. Das Modul ist klein, der Startaufschlag faellt nicht ins
|
||||
;; Gewicht. (Zum Nachmessen: Schalter "kf-zeit", siehe KettenFoerderer.lsp)
|
||||
(ssg-ensure "KettenFoerderer")
|
||||
;; Tro_Edit wird nicht vorgeladen - der Dispatcher SSG_BLOCKEDIT und die
|
||||
;; Menuemakros holen es per (ssg-ensure "Tro_Edit") bei Bedarf nach.
|
||||
(ssg-ensure "SSG_LIB_Commands")
|
||||
|
||||
+20
-20
@@ -27,7 +27,7 @@
|
||||
[->Streckengruppe]
|
||||
[Werte manuell]^C^C(ssg-ensure "VarioFoerderer") LinienzugVarioFoerdererManuell
|
||||
[aus 3D Linie mit Zielhoehe]^C^C(ssg-ensure "VarioFoerderer") LinienzugVarioFoerdererZielhoehe
|
||||
[<-3D Objekte stueckweise (in Arbeit)]^C^C(ssg-ensure "VarioFoerderer") LinienzugVarioFoerdererStueckweise
|
||||
[<-aus 3D Linie ohne Zielhoehe]^C^C(ssg-ensure "VarioFoerderer") LinienzugVarioFoerdererStueckweise
|
||||
[Vario_Kette_Merge]^C^C(ssg-ensure "VarioFoerderer") Vario_Kette_Merge
|
||||
[<-VarioFoerderer nachruesten (Marker)]^C^C(ssg-ensure "VarioFoerderer") VARIOFOERDERER_NACHRUESTEN
|
||||
[->Gefaellestrecke]
|
||||
@@ -92,27 +92,27 @@
|
||||
[Schwenkschiene Schiebetür R]^C^C(ssg-ensure "OmniModulInsert") OMNI_SCHW_400_R
|
||||
[Schwenkschiene Schiebetür L mit Sensorik]^C^C(ssg-ensure "OmniModulInsert") OMNI_SCHW_400_L_SENSORIK
|
||||
[<-<-<-Schwenkschiene Schiebetür R mit Sensorik]^C^C(ssg-ensure "OmniModulInsert") OMNI_SCHW_400_R_SENSORIK
|
||||
[~KettenFoerderer]^C^C(ssg-ensure "OmniModulInsert") OMNI_KettenFoerderer
|
||||
[KettenFoerderer]^C^C(ssg-ensure "KettenFoerderer") KETTENFOERDERER
|
||||
[Ladeschleifen]^C^C(ssg-ensure "OmniModulInsert") OMNI_LADESCHLEIFE_AP110
|
||||
[->Verbinder]
|
||||
[~TV W-W kpl]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_W
|
||||
[~TV W-AP110 kpl]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_AP110
|
||||
[~TV W-AP60 oben kpl.]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_AP60
|
||||
[~TV W-AP110-W kpl]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_AP110_W
|
||||
[~TV W-AP oben kpl]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_AP
|
||||
[~TV 80]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_80
|
||||
[~TV 50]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_50
|
||||
[~Endplatte Al-Profil AP schraubbar]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_ENDPLATTE
|
||||
[~Anschlag AP-Ende fuer Spulenzug]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_ANSCHLAG
|
||||
[~TV-A fuer AP110/AP60 kpl]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_A_AP110_AP60
|
||||
[~TV-A fuer AP60/ST]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_A_AP60_ST
|
||||
[~TV-A fuer AP110/ST kpl]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_A_AP110_ST
|
||||
[~TV-SW II fuer SW-SW]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_II_SW_SW
|
||||
[~TV-SW III fuer SW-AP110-SW]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_III_AP110_SW
|
||||
[~TV-SW III fuer SW-AP110]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_III_AP110
|
||||
[~TV-SW IV fuer Anschluss SW-AP60]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_IV_AP60
|
||||
[~TV-SW IV fuer SW-ST]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_IV_ST
|
||||
[<-~Muffe]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_MUFFE
|
||||
[TV W-AP110 kpl]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_AP110
|
||||
[TV W-AP60 oben kpl.]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_AP60
|
||||
[TV W-W kpl]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_W
|
||||
[TV W-AP110-W kpl]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_AP110_W
|
||||
[TV W-AP60 kpl]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_AP60_KPL
|
||||
[TV 80]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_80
|
||||
[TV 50]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_50
|
||||
[Endplatte Al-Profil AP schraubbar]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_ENDPLATTE
|
||||
[Anschlag AP-Ende für Spulenzug]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_ANSCHLAG
|
||||
[TV-A für AP110/AP60 kpl]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_A_AP110_AP60
|
||||
[TV-A für AP60/ST]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_A_AP60_ST
|
||||
[TV-A für AP110/ST kpl]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_A_AP110_ST
|
||||
[TV-SW II für SW-SW]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_II_SW_SW
|
||||
[TV-SW III für SW-AP110-SW]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_III_AP110_SW
|
||||
[TV-SW I für SW-AP110]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_I_AP110
|
||||
[TV-SW IV für Anschluss SW-AP60]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_IV_AP60
|
||||
[TV-SW IV für SW-ST]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_IV_ST
|
||||
[<-Muffe]^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_MUFFE
|
||||
[->Boegen fuer Weichen]
|
||||
[~APB 110 R400/45 140 nur fuer Delta]^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R400_45_140
|
||||
[~APB 110 R550/45 194 nur fuer Delta]^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_45_194
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
test_export_sivas_as_es.py - Sivas-Merkmale 4427-4432 (AS-/ES-Element) fuer
|
||||
Gefaellestrecke (GF_N) und Streckengruppe (VF_N).
|
||||
|
||||
Pruefpunkte: Vorhandensein haengt am Winkel (nicht an der Seite, die immer
|
||||
einen Vorgabewert traegt), der Winkel wird in die Sivas-Schreibweise der
|
||||
Auswahlliste uebersetzt, ohne Element bleiben Winkel UND Seite leer, die
|
||||
Zuordnung steht vollstaendig in cfg/sivas.cfg, und die GF-Gruppierung trennt
|
||||
Bloecke mit unterschiedlichem AS-/ES-Element.
|
||||
|
||||
Laeuft komplett ohne BricsCAD (reine Python-Logik).
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib"))
|
||||
|
||||
import export_sivas # noqa: E402
|
||||
import sivas_mapping # noqa: E402
|
||||
|
||||
# Sivas-Schreibweise der Winkel-Auswahlliste (cfg/sivas.cfg
|
||||
# [as_es_winkel_anzeige]) - die Tests vergleichen gegen die Config, damit ein
|
||||
# Nachziehen der Schreibweise dort nicht die halbe Testdatei bricht.
|
||||
W30 = export_sivas.as_es_winkel("30")
|
||||
W90 = export_sivas.as_es_winkel("90")
|
||||
|
||||
|
||||
def _strecke(nr, typ="Gefaellestrecke", **attr):
|
||||
"""GF_N-/VF_N-Block mit dem gemeinsamen Strecken-Attributschema."""
|
||||
attribs = {"ID": f"000{nr}", "Bezeichnung": f"GF_{nr}", "ARTINR": "6220",
|
||||
"MONTAGEHOEHE_m": "2.000", "HOEHE_VON_mm": "2000",
|
||||
"HOEHE_BIS_mm": "1000", "TYP": typ,
|
||||
"L_GF_m": "3.000", "GF_WINKEL": "3",
|
||||
"SEITE_AS": "links", "WINKEL_AS": "90",
|
||||
"SEITE_ES": "links", "WINKEL_ES": "90"}
|
||||
attribs.update(attr)
|
||||
return {"block_name": f"GF_{nr}", "x": 0.0, "y": 0.0, "z": 2000.0,
|
||||
"rotation": 0.0, "attribs": attribs}
|
||||
|
||||
|
||||
def test_as_es_vorhanden_mit_winkel_und_seite():
|
||||
details = export_sivas.build_gefaellestrecke_details(_strecke(1))
|
||||
assert details["4431"] == "Ja"
|
||||
assert details["4427"] == W90
|
||||
assert details["4428"] == "links"
|
||||
assert details["4432"] == "Ja"
|
||||
assert details["4429"] == W90
|
||||
assert details["4430"] == "links"
|
||||
|
||||
|
||||
def test_zuordnung_steht_in_der_config():
|
||||
"""Die sechs Merkmale muessen in BEIDEN Strecken-Abschnitten von
|
||||
sivas.cfg stehen (GF_N und VF_N lesen dieselben Attribute)."""
|
||||
for abschnitt in ("gefaellestrecke", "variofoerderer"):
|
||||
mapping = sivas_mapping.load_section_mapping(abschnitt)
|
||||
for merkmal, attribut, transform in (
|
||||
("4431", "WINKEL_AS", "as_es_vorhanden"),
|
||||
("4427", "WINKEL_AS", "as_es_winkel"),
|
||||
("4428", "SEITE_AS", "as_seite"),
|
||||
("4432", "WINKEL_ES", "as_es_vorhanden"),
|
||||
("4429", "WINKEL_ES", "as_es_winkel"),
|
||||
("4430", "SEITE_ES", "es_seite")):
|
||||
assert merkmal in mapping, f"{merkmal} fehlt in [{abschnitt}]"
|
||||
ist_attribut, _alt, _default, ist_transform = mapping[merkmal]
|
||||
assert ist_attribut == attribut, f"[{abschnitt}] {merkmal}"
|
||||
assert ist_transform == transform, f"[{abschnitt}] {merkmal}"
|
||||
assert ist_transform in export_sivas.TRANSFORMS
|
||||
|
||||
|
||||
def test_winkel_in_sivas_schreibweise():
|
||||
"""4427/4429 tragen den Optionswert der Auswahlliste, nicht die nackte
|
||||
Attributzahl (Vorgabe aus cfg/sivas.cfg [as_es_winkel_anzeige])."""
|
||||
details = export_sivas.build_gefaellestrecke_details(
|
||||
_strecke(1, WINKEL_AS="30", WINKEL_ES="90.0"))
|
||||
assert details["4427"] == W30
|
||||
assert details["4429"] == W90
|
||||
# Unbekannter Winkel faellt auf die ganzzahlige Rohzahl zurueck
|
||||
assert export_sivas.as_es_winkel("60.0") in (W30, W90, "60")
|
||||
|
||||
|
||||
def test_ohne_winkel_kein_element_und_keine_seite():
|
||||
"""Leerer WINKEL_AS = kein AS-Element; die Seite darf dann NICHT
|
||||
durchgereicht werden (SEITE_AS traegt mit "rechts" immer einen
|
||||
Schema-Vorgabewert)."""
|
||||
details = export_sivas.build_gefaellestrecke_details(
|
||||
_strecke(1, WINKEL_AS="", SEITE_AS="rechts"))
|
||||
assert details["4431"] == "Nein"
|
||||
assert details["4427"] == ""
|
||||
assert details["4428"] == ""
|
||||
# ES bleibt davon unberuehrt
|
||||
assert details["4432"] == "Ja"
|
||||
assert details["4430"] == "links"
|
||||
|
||||
|
||||
def test_seite_rechts():
|
||||
details = export_sivas.build_gefaellestrecke_details(
|
||||
_strecke(1, SEITE_AS="rechts", SEITE_ES="rechts"))
|
||||
assert details["4428"] == "rechts"
|
||||
assert details["4430"] == "rechts"
|
||||
|
||||
|
||||
def test_variofoerderer_hat_dieselben_merkmale():
|
||||
block = _strecke(1, typ="Streckengruppe", L_VF_m="2.000", VF_WINKEL="0",
|
||||
ANTRIEBFAHRTRICHTUNG="Auf", MOTORSEITE="rechts",
|
||||
WINKEL_AS="30", SEITE_AS="rechts")
|
||||
details = export_sivas.build_variofoerderer_details(block)
|
||||
assert details["4431"] == "Ja"
|
||||
assert details["4427"] == W30
|
||||
assert details["4428"] == "rechts"
|
||||
assert details["4429"] == W90
|
||||
|
||||
|
||||
def test_gruppierung_trennt_nach_as_seite():
|
||||
"""Sonst baugleiche Gefaellestrecken mit AS links bzw. rechts duerfen
|
||||
nicht in einer Sivas-Zeile landen (die Zeile wuerde nur eine der beiden
|
||||
Seiten zeigen)."""
|
||||
links = export_sivas.gefaellestrecke_signature(_strecke(1, SEITE_AS="links"))
|
||||
rechts = export_sivas.gefaellestrecke_signature(_strecke(2, SEITE_AS="rechts"))
|
||||
assert links != rechts
|
||||
assert links == export_sivas.gefaellestrecke_signature(_strecke(3, SEITE_AS="links"))
|
||||
|
||||
|
||||
def test_gruppierung_trennt_nach_as_winkel():
|
||||
assert (export_sivas.gefaellestrecke_signature(_strecke(1, WINKEL_AS="30"))
|
||||
!= export_sivas.gefaellestrecke_signature(_strecke(2, WINKEL_AS="90")))
|
||||
|
||||
|
||||
def test_gruppierung_ohne_element_ignoriert_die_seite():
|
||||
"""Ohne AS-Element ist die Seite bedeutungslos und steht auch nicht in der
|
||||
Zeile - sie darf die Gruppierung dann nicht aufspalten."""
|
||||
assert (export_sivas.gefaellestrecke_signature(
|
||||
_strecke(1, WINKEL_AS="", SEITE_AS="links"))
|
||||
== export_sivas.gefaellestrecke_signature(
|
||||
_strecke(2, WINKEL_AS="", SEITE_AS="rechts")))
|
||||
|
||||
|
||||
def test_reihenfolge_im_details_json():
|
||||
"""Die sechs Merkmale stehen im details-JSON direkt HINTER 2950
|
||||
(Anlagenhoehe) - so vorgegeben, und so steht es in beiden Abschnitten von
|
||||
sivas.cfg. Die Reihenfolge der JSON-Keys folgt der Zeilenreihenfolge der
|
||||
Config (configparser und dict erhalten beide die Einfuegereihenfolge)."""
|
||||
erwartet = ["2950", "4431", "4427", "4428", "4432", "4429", "4430"]
|
||||
gf = list(export_sivas.build_gefaellestrecke_details(_strecke(1)))
|
||||
vf = list(export_sivas.build_variofoerderer_details(
|
||||
_strecke(2, typ="Streckengruppe", L_VF_m="2.000")))
|
||||
assert gf[:len(erwartet)] == erwartet
|
||||
assert vf[:len(erwartet)] == erwartet
|
||||
|
||||
|
||||
def test_altbestand_ohne_die_attribute():
|
||||
"""Bloecke aus Zeichnungen, die vor der Einfuehrung von WINKEL_AS gebaut
|
||||
wurden, haben die Attribute gar nicht - dann greift der leere Default und
|
||||
es wird "Nein" gemeldet (statt KeyError). Das ist die einzig moegliche
|
||||
Aussage: Sivas kennt nur Ja/Nein, kein "unbekannt"."""
|
||||
block = _strecke(1)
|
||||
for tag in ("WINKEL_AS", "SEITE_AS", "WINKEL_ES", "SEITE_ES"):
|
||||
del block["attribs"][tag]
|
||||
details = export_sivas.build_gefaellestrecke_details(block)
|
||||
assert details["4431"] == "Nein"
|
||||
assert details["4432"] == "Nein"
|
||||
assert details["4427"] == details["4428"] == ""
|
||||
assert details["4429"] == details["4430"] == ""
|
||||
|
||||
|
||||
def test_transform_mit_attribs_kontext():
|
||||
"""Der @braucht_attribs-Transform muss das komplette Attribut-Dict sehen -
|
||||
sonst koennte die Seite ihre Abhaengigkeit vom Winkel nicht pruefen."""
|
||||
assert getattr(export_sivas.as_seite, "braucht_attribs", False)
|
||||
assert getattr(export_sivas.es_seite, "braucht_attribs", False)
|
||||
assert not getattr(export_sivas.ja_nein, "braucht_attribs", False)
|
||||
|
||||
mapping = {"4428": ("SEITE_AS", None, "", "as_seite")}
|
||||
attribs = {"SEITE_AS": "links", "WINKEL_AS": "90"}
|
||||
assert sivas_mapping.anwenden(mapping, attribs, export_sivas.TRANSFORMS) \
|
||||
== {"4428": "links"}
|
||||
attribs_ohne = {"SEITE_AS": "links", "WINKEL_AS": ""}
|
||||
assert sivas_mapping.anwenden(mapping, attribs_ohne, export_sivas.TRANSFORMS) \
|
||||
== {"4428": ""}
|
||||
@@ -26,12 +26,14 @@
|
||||
;; also genau die Werte, mit denen die Ketten in BricsCAD gebaut wurden.
|
||||
;;
|
||||
;; JSON-Aufbau (FLACH, weil ssg-load-json zeilenweise liest - Details in
|
||||
;; tests/testdata/object_data.md Abschnitt 8):
|
||||
;; doc/json-input-lisp.md Abschnitt 6):
|
||||
;; Kopf-Objekt (traegt "test_id"): test_id, anlagetyp, modus,
|
||||
;; anzahl_eingaben, block, dxf_handle, startpunkt_mm,
|
||||
;; rotation_grad, beschreibung, sivas_* , erwartung_hinweis
|
||||
;; Eingabe-Objekt (traegt "typ"): point_abs | point_rel | real | int |
|
||||
;; string | step - in exakter Frage-Reihenfolge
|
||||
;; string | step | nil - in exakter Frage-Reihenfolge
|
||||
;; ("nil" = Frage gestellt und bewusst uebergangen, z.B.
|
||||
;; keine Zufuehrungsachse gewaehlt)
|
||||
;; Ein Kopf-Objekt beginnt eine Kette, die folgenden Eingabe-Objekte gehoeren
|
||||
;; dazu (hmrec:gruppiere).
|
||||
;;
|
||||
@@ -291,6 +293,13 @@
|
||||
(list (cons "STR" (hmrec:als-string (ssg-val e "wert")))))
|
||||
((= typ "step")
|
||||
(list (cons "STEP" (hmrec:als-string (ssg-val e "wert")))))
|
||||
;; Eine Frage, die gestellt und bewusst uebergangen wurde (bisher nur die
|
||||
;; Zufuehrungsachse des AS-Elements, siehe ProtokollSink.as_achse in
|
||||
;; lib/vf_journal_export.py) - im Journal ein wertloser "NIL"-Eintrag.
|
||||
;; Er MUSS mitlaufen: beim Replay poppt ihn vfl-in-point, sonst zoege
|
||||
;; dieser Aufruf den naechsten Wert aus der Queue (Desync).
|
||||
((= typ "nil")
|
||||
(list (cons "NIL" nil)))
|
||||
(T nil)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -12,7 +12,7 @@ Zwei Ebenen:
|
||||
|
||||
Die Testdaten stammen aus lib/vf_journal_export.py (Journale der VF_n-Bloecke
|
||||
aus data/polylines.dxf, XDATA-App SSG_VF_EDIT) und nicht aus Handarbeit -
|
||||
Schema siehe tests/testdata/object_data.md Abschnitt 8.
|
||||
Schema siehe doc/json-input-lisp.md Abschnitt 6.
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
;; hundm05.json auch andere Objekte der Anlage stehen - erkennbar an
|
||||
;; "function". Format wie in tests/testdata/kreisel_tests.json, damit die
|
||||
;; Felder nicht zweimal beschrieben werden muessen (Schema: siehe
|
||||
;; tests/testdata/object_data.md Abschnitt 1).
|
||||
;; doc/json-input-lisp.md Abschnitt 1).
|
||||
;; vsp-gruppieren ignoriert diese Objekte, sie stoeren die Ketten also nicht.
|
||||
;; lib/vf_spec_export.py uebernimmt sie beim Neuerzeugen der Spec-Daten
|
||||
;; unveraendert ans Dateiende (sonst waeren sie beim naechsten Lauf weg).
|
||||
@@ -61,7 +61,7 @@
|
||||
;; Unterstuetzt: Kreisel (function "insert", wie test_kreisel.lsp) und
|
||||
;; beliebige eigenstaendige Bloecke ueber "block" (Separator/Scanner sowie
|
||||
;; BTMT-Beladung/SC_Entladung, wie in mubea.json - Schema tests/testdata/
|
||||
;; object_data.md Abschnitt 5). Unterscheidung ueber das Feld "block": nur
|
||||
;; json-input-lisp.md Abschnitt 2). Unterscheidung ueber das Feld "block": nur
|
||||
;; Bloecke haben es, Kreisel-Eintraege nicht. hundm05:bau-sensor ist dabei
|
||||
;; blockname-agnostisch (reiner _.INSERT), der "kind"-Wert "sensor" bleibt
|
||||
;; als Sammelbegriff fuer "kein Kreisel" bestehen (siehe dort).
|
||||
@@ -125,7 +125,7 @@
|
||||
"kreisel-insert-script lieferte nil"))))))
|
||||
|
||||
;; Separator/Scanner/BTMT-Beladung/SC_Entladung bauen ("block"-Eintraege,
|
||||
;; siehe object_data.md Abschnitt 5). ils-insert-sensor/ils-insert-station
|
||||
;; siehe json-input-lisp.md Abschnitt 2). ils-insert-sensor/ils-insert-station
|
||||
;; (SSG_LIB_Commands.lsp) sind dafuer NICHT scriptbar (fragen Punkt/Rotation
|
||||
;; per getpoint/pause in einer Schleife) - wir bauen den _.INSERT darum
|
||||
;; direkt selbst nach, wie mubea:build-separator-one in tests/test_mubea.lsp
|
||||
|
||||
@@ -180,7 +180,7 @@ class TestSpecBau:
|
||||
# ============================================================
|
||||
# tests/testdata/hundm05.json enthaelt neben den Ketten auch andere Objekte
|
||||
# der Anlage - Format wie tests/testdata/kreisel_tests.json (Schema in
|
||||
# tests/testdata/object_data.md Abschnitt 1). Gebaut werden sie von
|
||||
# doc/json-input-lisp.md Abschnitt 1). Gebaut werden sie von
|
||||
# hundm05:bau-zusatzobjekte in tests/test_hundm05.lsp.
|
||||
|
||||
class TestZusatzobjekte:
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
;; --- Vario (VF_*): L_GF/L_VF fuer gegebenes deltaL+deltaH+winkel loesen, dann bauen ---
|
||||
;; deltaL ist (wie bei der Gefaellestrecke) die horizontale PROJIZIERTE
|
||||
;; Gesamtlaenge des VF (Vorlauf L_GF1 + Foerderer L_VF + Nachlauf L_GF2 +
|
||||
;; Boegen/AS-ES-Elemente), analog foerderer_tests.json/object_data.md 3.1 -
|
||||
;; Boegen/AS-ES-Elemente), analog foerderer_tests.json/json-input-lisp.md 3 -
|
||||
;; KEIN abgeleiteter Wert. "winkel" erzwingt einen bestimmten Bogenwinkel aus
|
||||
;; der Kandidatenliste von berechne-alle-winkel (wie foerderer:winkel-
|
||||
;; erzwingen in test_foerderer.lsp), statt den automatisch kleinsten
|
||||
@@ -295,7 +295,7 @@
|
||||
;; --- Eine einzelne Gefaellestrecke bauen (Modus 1) ---
|
||||
;; Aufbau AUSSCHLIESSLICH aus Anfangspunkt (start-mm) und horizontaler
|
||||
;; Gesamtlaenge deltaL - KEIN Endpunkt (wie Produktion/gefaellestrecke.dcl
|
||||
;; Modus 1, siehe object_data.md 2.1). L_stau wird aus deltaL abgeleitet
|
||||
;; Modus 1, siehe json-input-lisp.md 4.1). L_stau wird aus deltaL abgeleitet
|
||||
;; (identische Formel wie test_gefaellestrecke.lsp):
|
||||
;; L_stau = (deltaL - aus-dx - ein-dx - sep_x) / cos(v)
|
||||
;; sep_x = 300 * cos(v), v = Element-Winkel (winkel_grad, Default 3 Grad)
|
||||
|
||||
+504
-2
@@ -399,6 +399,146 @@
|
||||
)
|
||||
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; TESTS: vf_linienzug.lsp - "Parallel zum Kreisel" (Rechenkerne)
|
||||
;; ------------------------------------------------------------
|
||||
;; Die Bau-Funktion vfl-gf-parallel-kreisel braucht eine Zeichnung (sie misst
|
||||
;; AS und Bogen an echten Bloecken); ihre beiden Rechenkerne sind davon frei
|
||||
;; und stehen deshalb hier:
|
||||
;; vfl-par-bogen-waehlen - welcher Bogen hebt den AS-Schwenk auf?
|
||||
;; vfl-par-gf-laenge - wie lang wird das GF-Stueck dazwischen?
|
||||
;; Die Plan-Turn-Werte unten sind die Vorzeichen-Konvention aus
|
||||
;; vf-element-plan-turn (KS_EIN -> KS_AUS in der XY-Ebene, links positiv).
|
||||
(defun tu-tests-vfl-parallel ( / _b30 _b60 _b90 _kand _l _plan _plan3 _g _p _w)
|
||||
(princ "\n[vf_linienzug Parallel zum Kreisel]")
|
||||
|
||||
;; --- Bogenwahl: der Bogen muss den AS-Schwenk GENAU aufheben ---
|
||||
;; Rechts-Boegen schwenken negativ, Links-Boegen positiv.
|
||||
(setq _b30 '(30 . -30.0) _b60 '(60 . -60.0) _b90 '(90 . -90.0))
|
||||
(setq _kand (list _b30 _b60 _b90))
|
||||
;; AS links 30 Grad (Schwenk +30) -> 30-Grad-Bogen nach rechts
|
||||
(tu-eq "vfl-par-bogen/as30-rechts" 30 (vfl-par-bogen-waehlen 30.0 _kand 2.0))
|
||||
;; AS links 90 Grad (Schwenk +90) -> 90-Grad-Bogen nach rechts
|
||||
(tu-eq "vfl-par-bogen/as90-rechts" 90 (vfl-par-bogen-waehlen 90.0 _kand 2.0))
|
||||
;; Generisch: auch ein 60-Grad-Schwenk findet seinen Bogen - die Zuordnung
|
||||
;; folgt den gemessenen Bloecken, nicht einer gepflegten Tabelle.
|
||||
(tu-eq "vfl-par-bogen/as60-rechts" 60 (vfl-par-bogen-waehlen 60.0 _kand 2.0))
|
||||
;; kleine Messabweichung bleibt in der Toleranz
|
||||
(tu-eq "vfl-par-bogen/toleranz-ok" 30 (vfl-par-bogen-waehlen 31.2 _kand 2.0))
|
||||
;; ausserhalb der Toleranz: lieber nil als ein schiefer Bogen
|
||||
(tu-nil "vfl-par-bogen/zu-weit-weg" (vfl-par-bogen-waehlen 45.0 _kand 2.0))
|
||||
(tu-nil "vfl-par-bogen/leere-liste" (vfl-par-bogen-waehlen 30.0 '() 2.0))
|
||||
;; Gegenseite: Links-Boegen heben einen negativen AS-Schwenk auf
|
||||
(setq _kand (list '(30 . 30.0) '(60 . 60.0) '(90 . 90.0)))
|
||||
(tu-eq "vfl-par-bogen/as-rechts30-links" 30 (vfl-par-bogen-waehlen -30.0 _kand 2.0))
|
||||
|
||||
;; --- GF-Laenge: abstand = perp-as + L*k + perp-bogen ---
|
||||
;; Glatter Fall: k = 1 (AS schwenkt 90 Grad aus der Achse), feste Anteile
|
||||
;; zusammen 500 -> fuer 2000 mm Abstand bleiben 1500 mm GF.
|
||||
(tu-eqf "vfl-par-laenge/k1" 1500.0 (vfl-par-gf-laenge 2000.0 200.0 300.0 1.0))
|
||||
;; Gegenseite: k negativ -> der Abstand zaehlt auf der anderen Seite, der
|
||||
;; Betrag der Eingabe bleibt derselbe (Seite kommt aus der AS-Variante).
|
||||
(tu-eqf "vfl-par-laenge/k-negativ" 1500.0
|
||||
(vfl-par-gf-laenge 2000.0 -200.0 -300.0 -1.0))
|
||||
;; Schraege Ausschleusung: k = sin(60 Grad)
|
||||
(setq _l (vfl-par-gf-laenge 2000.0 0.0 0.0 (sin (/ (* 60.0 pi) 180.0))))
|
||||
(tu-eqf "vfl-par-laenge/k-sin60" (/ 2000.0 (sin (/ (* 60.0 pi) 180.0))) _l)
|
||||
;; Abstand kleiner als der feste Anteil -> negative Laenge (der Aufrufer
|
||||
;; meldet das als "Abstand zu klein", die Rechnung selbst raet nicht).
|
||||
(tu-true "vfl-par-laenge/zu-klein-negativ"
|
||||
(< (vfl-par-gf-laenge 100.0 200.0 300.0 1.0) 0.0))
|
||||
;; AS schwenkt gar nicht aus der Achse -> keine Loesung
|
||||
(tu-nil "vfl-par-laenge/kein-versatz" (vfl-par-gf-laenge 2000.0 0.0 0.0 0.0))
|
||||
|
||||
;; --- Grenzen einer VF-Einheit (Modus 2) ---
|
||||
;; Zwischen Umlenk- und Motorstation: hoechstens 2 Vario-Kurven und 25 m.
|
||||
;; Plan-Eintraege: ("Linie" hz laenge ...) / ("Bogen" hz chord ...) - nur
|
||||
;; Typ und Laenge (3. Feld) zaehlen hier.
|
||||
(setq _plan (list '("Linie" 0.0 9000.0 "VF") '("Bogen" 0.0 500.0)
|
||||
'("Linie" 0.0 8000.0 "VF") '("Bogen" 0.0 500.0)
|
||||
'("Linie" 0.0 6000.0 "VF")))
|
||||
;; 24000 mm, 2 Kurven -> alles im Rahmen
|
||||
(setq _g (vfl-m2-lauf-grenzen _plan 0 4 25000.0 2))
|
||||
(tu-eqf "vfl-m2-grenzen/laenge" 24000.0 (nth 0 _g))
|
||||
(tu-eq "vfl-m2-grenzen/kurven" 2 (nth 1 _g))
|
||||
(tu-nil "vfl-m2-grenzen/ok" (nth 2 _g))
|
||||
;; Dritte Kurve -> an ihr (Index 5) teilen, obwohl die Laenge noch passt
|
||||
(setq _plan3 (append _plan (list '("Bogen" 0.0 400.0) '("Linie" 0.0 300.0 "VF"))))
|
||||
(tu-eq "vfl-m2-grenzen/dritte-kurve" 5 (nth 2 (vfl-m2-lauf-grenzen _plan3 0 6 25000.0 2)))
|
||||
;; Zu lang -> am ersten Bogen teilen, nach dem die Grenze reisst (Index 3:
|
||||
;; bis dahin sind 9000+500+8000 = 17500 drin, die Grenze liegt bei 15000).
|
||||
(tu-eq "vfl-m2-grenzen/zu-lang" 3 (nth 2 (vfl-m2-lauf-grenzen _plan 0 4 15000.0 2)))
|
||||
;; Eine einzige lange Gerade: zu lang, aber kein Bogen zum Teilen -> -1
|
||||
(tu-eq "vfl-m2-grenzen/unteilbar" -1
|
||||
(nth 2 (vfl-m2-lauf-grenzen (list '("Linie" 0.0 30000.0 "VF")) 0 0 25000.0 2)))
|
||||
|
||||
;; --- Vorgabewert aus einem Prompt ziehen (Dialog-Feld vorbelegen) ---
|
||||
;; Die Konsolen-Prompts tragen ihre Vorgabe in Klammern; der Zahlen-Dialog
|
||||
;; liest sie daraus. Gesucht ist die LETZTE Klammergruppe MIT Zahl - die
|
||||
;; echten Texte enthalten davor "<" ohne Partner ("0 < Winkel <= 3") und
|
||||
;; runde Klammern mit Fliesstext, beides darf nicht stoeren.
|
||||
(tu-eq "vflw-vorgabe/neigungswinkel" "3"
|
||||
(vflw-vorgabe-aus-prompt "\nNeigungswinkel (Grad, 0 < Winkel <= 3) [3]: "))
|
||||
(tu-eq "vflw-vorgabe/neigungswinkel-berechnet" "3"
|
||||
(vflw-vorgabe-aus-prompt
|
||||
"\nNeigungswinkel (Grad, 0 < Winkel <= 3) [3] (deltaL wird berechnet und eingefuegt): "))
|
||||
(tu-eq "vflw-vorgabe/spitze-klammer" "2154.0"
|
||||
(vflw-vorgabe-aus-prompt "\nGewuenschte Hoehe am Kettenanfang (mm) <2154.0>: "))
|
||||
(tu-eq "vflw-vorgabe/negativ" "-12.5"
|
||||
(vflw-vorgabe-aus-prompt "Hoehendifferenz <-12.5>: "))
|
||||
;; Ohne Klammergruppe bleibt das Feld leer (nil), nicht geraten.
|
||||
(tu-nil "vflw-vorgabe/ohne-vorgabe"
|
||||
(vflw-vorgabe-aus-prompt "\nAbstand zum Kreisel (mm, senkrecht zur Achse): "))
|
||||
(tu-nil "vflw-vorgabe/keine-zahl"
|
||||
(vflw-vorgabe-aus-prompt "Bitte Namen eingeben [frei]: "))
|
||||
|
||||
;; --- Modus-2-Lauf-Anfang: Journal-Wert normieren ---
|
||||
;; Die Antwort wird als selbstbeschreibender Wert gefuehrt, damit ein
|
||||
;; Umsortieren/Umnummerieren der Optionen bestehende Ketten nicht
|
||||
;; umdeutet. Alte Ketten tragen dort noch die Ziffern der ALTEN Folge -
|
||||
;; die Zuordnung dafuer steht als Tabelle in *vfl-m2-anfang-alt* und wird
|
||||
;; hier komplett durchlaufen, statt einzelne Faelle abzuschreiben.
|
||||
(foreach _p *vfl-m2-anfang-alt*
|
||||
(tu-eq (strcat "vfl-m2-anfang/alt-" (car _p))
|
||||
(cdr _p) (vfl-m2-anfang-norm (car _p))))
|
||||
;; Jeder Tabellenwert muss auch ein gueltiger heutiger Wert sein - sonst
|
||||
;; laeuft eine Alt-Kette in den Unbekannt-Abbruch.
|
||||
(foreach _p *vfl-m2-anfang-alt*
|
||||
(tu-true (strcat "vfl-m2-anfang/alt-ziel-gueltig-" (car _p))
|
||||
(and (member (cdr _p) *vfl-m2-anfang-werte*) t)))
|
||||
;; Neue Werte gehen unveraendert durch.
|
||||
(foreach _w *vfl-m2-anfang-werte*
|
||||
(tu-eq (strcat "vfl-m2-anfang/neu-" _w) _w (vfl-m2-anfang-norm _w)))
|
||||
;; Unbekanntes wird NICHT geraten - nil heisst fuer den Aufrufer Abbruch.
|
||||
(tu-nil "vfl-m2-anfang/unbekannte-ziffer" (vfl-m2-anfang-norm "4"))
|
||||
(tu-nil "vfl-m2-anfang/leer" (vfl-m2-anfang-norm ""))
|
||||
(tu-nil "vfl-m2-anfang/tippfehler" (vfl-m2-anfang-norm "mit_gf1"))
|
||||
(tu-nil "vfl-m2-anfang/kein-string" (vfl-m2-anfang-norm 3))
|
||||
(tu-nil "vfl-m2-anfang/nil" (vfl-m2-anfang-norm nil))
|
||||
|
||||
;; --- Rueckwaerts bauen: Punkt entgegen der Fahrtrichtung zuruecksetzen ---
|
||||
;; vfl-rueck-punkt ist der Rechenkern des Rueckwaerts-Baus: zu einem
|
||||
;; BEKANNTEN Endpunkt den Startpunkt eines Bausteins finden. Vorwaerts gilt
|
||||
;; P_next = P + (L*cos hz, L*sin hz, -L*tan w) - hier also mit umgekehrtem
|
||||
;; Vorzeichen. Die Hoehe muss STEIGEN (der Vorgaenger liegt hoeher).
|
||||
(tu-eqf "vfl-rueck-punkt/ost-flach"
|
||||
(list 0.0 0.0 0.0) (vfl-rueck-punkt '(1000.0 0.0 0.0) 0.0 1000.0 0.0))
|
||||
(tu-eqf "vfl-rueck-punkt/nord-flach"
|
||||
(list 0.0 0.0 0.0) (vfl-rueck-punkt '(0.0 1000.0 0.0) 90.0 1000.0 0.0))
|
||||
;; 45 Grad Gefaelle: 1000 mm horizontal zurueck = 1000 mm hoeher
|
||||
(tu-eqf "vfl-rueck-punkt/45-grad"
|
||||
(list 0.0 0.0 1000.0) (vfl-rueck-punkt '(1000.0 0.0 0.0) 0.0 1000.0 45.0))
|
||||
;; Rundlauf: vorwaerts wieder auf den Ausgangspunkt (3 Grad, schraeg)
|
||||
(setq _l (vfl-rueck-punkt '(5000.0 3000.0 1800.0) 30.0 2000.0 3.0))
|
||||
(tu-eqf "vfl-rueck-punkt/rundlauf-x" 5000.0
|
||||
(+ (car _l) (* 2000.0 (cos (/ (* 30.0 pi) 180.0)))))
|
||||
(tu-eqf "vfl-rueck-punkt/rundlauf-y" 3000.0
|
||||
(+ (cadr _l) (* 2000.0 (sin (/ (* 30.0 pi) 180.0)))))
|
||||
(tu-eqf "vfl-rueck-punkt/rundlauf-z" 1800.0
|
||||
(- (caddr _l) (* 2000.0 (/ (sin (/ (* 3.0 pi) 180.0)) (cos (/ (* 3.0 pi) 180.0))))))
|
||||
)
|
||||
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; TESTS: vf_linienzug.lsp - Laenge aus einer Ziellinie (X/Y)
|
||||
;; ------------------------------------------------------------
|
||||
@@ -446,6 +586,86 @@
|
||||
(+ (cadr _ks) (sin (/ pi 6.0))) 0.0)))
|
||||
(tu-true "vfl-laenge-bis-ziellinie/realfall-plausibel"
|
||||
(and _l (> _l 1430.0) (< _l 1431.0)))
|
||||
|
||||
;; --- AS-Seite aus der Lage des naechsten Punkts zur Basislinie ---
|
||||
;; Basislinie zeigt nach +X; ein Ziel mit +Y liegt links davon, mit -Y rechts.
|
||||
(tu-eq "vfl-seite-aus-lage/links"
|
||||
"links" (vfl-seite-aus-lage '(0.0 0.0 0.0) '(1000.0 0.0 0.0) '(500.0 800.0 0.0)))
|
||||
(tu-eq "vfl-seite-aus-lage/rechts"
|
||||
"rechts" (vfl-seite-aus-lage '(0.0 0.0 0.0) '(1000.0 0.0 0.0) '(500.0 -800.0 0.0)))
|
||||
;; Richtung der Basislinie umdrehen -> Seite dreht mit
|
||||
(tu-eq "vfl-seite-aus-lage/basislinie-umgedreht"
|
||||
"rechts" (vfl-seite-aus-lage '(1000.0 0.0 0.0) '(0.0 0.0 0.0) '(500.0 800.0 0.0)))
|
||||
;; schraege Basislinie (45 Grad): Ziel oberhalb davon liegt links
|
||||
(tu-eq "vfl-seite-aus-lage/schraeg"
|
||||
"links" (vfl-seite-aus-lage '(0.0 0.0 0.0) '(1000.0 1000.0 0.0) '(0.0 1000.0 0.0)))
|
||||
;; Z spielt keine Rolle (rein planare Entscheidung)
|
||||
(tu-eq "vfl-seite-aus-lage/z-ignoriert"
|
||||
"rechts" (vfl-seite-aus-lage '(0.0 0.0 5000.0) '(1000.0 0.0 -200.0) '(500.0 -800.0 999.0)))
|
||||
|
||||
;; --- VF-Hoehe je SEGMENT (Attribut VF_HOEHE_m, Sivas 4433-4437) ---
|
||||
;; Ein Eintrag je GERADEM VF-Abschnitt: Mittelwert aus dessen KS_EIN und
|
||||
;; KS_AUS, in METERN mit 3 Nachkommastellen. Zwischen Umlenk- und
|
||||
;; Motorstation koennen mehrere Abschnitte liegen (auf/ab/horizontal), die
|
||||
;; Liste laeuft darum parallel zu L_VF_m und VF_WINKEL.
|
||||
(vf-vfhoehe-reset)
|
||||
(tu-eq "vf-vfhoehe/leer-nach-reset" "" (vfl-join-komma *vf-acc-vfhoehe*))
|
||||
|
||||
;; 2000 mm und 3000 mm -> Mittel 2500 mm -> "2.500"
|
||||
(vf-vfhoehe-segment 2000.0 3000.0)
|
||||
(tu-eq "vf-vfhoehe/mittelwert-meter" "2.500" (vfl-join-komma *vf-acc-vfhoehe*))
|
||||
|
||||
;; Drei Abschnitte wie im realen Block (L_VF_m hatte dort 3 Eintraege):
|
||||
;; horizontal, horizontal, steigend - alle drei bekommen einen Wert.
|
||||
(vf-vfhoehe-reset)
|
||||
(vf-vfhoehe-segment 2076.0 2076.0) ; horizontal
|
||||
(vf-vfhoehe-segment 2076.0 2076.0) ; horizontal
|
||||
(vf-vfhoehe-segment 2076.0 2600.0) ; steigend -> Mittel 2338
|
||||
(tu-eq "vf-vfhoehe/drei-abschnitte"
|
||||
"2.076,2.076,2.338" (vfl-join-komma *vf-acc-vfhoehe*))
|
||||
|
||||
;; Unvollstaendige Messung haengt NICHTS an - sonst verschoebe sich die
|
||||
;; Liste gegen L_VF_m und eine Hoehe landete beim falschen Foerderer.
|
||||
(vf-vfhoehe-reset)
|
||||
(vf-vfhoehe-segment 1000.0 2000.0)
|
||||
(vf-vfhoehe-segment nil 3000.0)
|
||||
(vf-vfhoehe-segment 4000.0 nil)
|
||||
(tu-eq "vf-vfhoehe/unvollstaendig-ignoriert" "1.500" (vfl-join-komma *vf-acc-vfhoehe*))
|
||||
|
||||
;; negative Hoehen (Kette unter Null) muessen durchgehen
|
||||
(vf-vfhoehe-reset)
|
||||
(vf-vfhoehe-segment -500.0 -1500.0)
|
||||
(tu-eq "vf-vfhoehe/negativ" "-1.000" (vfl-join-komma *vf-acc-vfhoehe*))
|
||||
(vf-vfhoehe-reset)
|
||||
|
||||
;; vf-meter-3: GENAU 3 Nachkommastellen, unabhaengig von DIMZIN.
|
||||
;; (rtos x 2 3) allein kuerzt nachfolgende Nullen ("2.5", "-1") - real im
|
||||
;; Testlauf aufgetreten, deshalb eigene Formatierung.
|
||||
(tu-eq "vf-meter-3/glatt" "2.500" (vf-meter-3 2500.0))
|
||||
(tu-eq "vf-meter-3/ganzzahlig" "3.000" (vf-meter-3 3000.0))
|
||||
(tu-eq "vf-meter-3/negativ" "-1.000" (vf-meter-3 -1000.0))
|
||||
(tu-eq "vf-meter-3/null" "0.000" (vf-meter-3 0.0))
|
||||
(tu-eq "vf-meter-3/drei-stellen" "1.234" (vf-meter-3 1234.0))
|
||||
|
||||
;; --- SONDERFALL Standard/Etage: Hoehe ueber die GANZE Kette ---
|
||||
;; Nur ein Motor und nur ein gerader VF-Abschnitt, darum zaehlt dort
|
||||
;; AS-KS_EIN .. ES-KS_AUS statt des Segmentwerts (Nutzer-Vorgabe 2026-10-21).
|
||||
(vf-vfhoehe-reset)
|
||||
(vf-vfhoehe-kette 1000.0 3000.0)
|
||||
(tu-eq "vf-vfhoehe-kette/mittelwert" "2.000" (vfl-join-komma *vf-acc-vfhoehe*))
|
||||
|
||||
;; ERSETZT den beim Bau gesammelten Segmentwert, haengt ihn NICHT an -
|
||||
;; sonst stuenden fuer eine Standard-Anlage zwei Hoehen in der Liste.
|
||||
(vf-vfhoehe-reset)
|
||||
(vf-vfhoehe-segment 5000.0 5000.0) ; Segmentwert aus vfs-vf-koerper
|
||||
(vf-vfhoehe-kette 1000.0 3000.0)
|
||||
(tu-eq "vf-vfhoehe-kette/ersetzt-segmentwert" "2.000" (vfl-join-komma *vf-acc-vfhoehe*))
|
||||
|
||||
;; fehlender Endpunkt -> lieber leer als geraten
|
||||
(vf-vfhoehe-reset)
|
||||
(vf-vfhoehe-kette 1000.0 nil)
|
||||
(tu-eq "vf-vfhoehe-kette/ohne-endpunkt-leer" "" (vfl-join-komma *vf-acc-vfhoehe*))
|
||||
(vf-vfhoehe-reset)
|
||||
)
|
||||
|
||||
|
||||
@@ -794,6 +1014,14 @@
|
||||
(tu-eq "omni:filter/anzahl" 2 (length (omni:filter _lst "KurvenWinkel" 45)))
|
||||
(tu-eq "omni:filter/wert"
|
||||
100 (cdr (assoc "Sivasnr" (car (omni:filter _lst "KurvenWinkel" 45)))))
|
||||
|
||||
;; Verbinder-Pfad: Backslashes normalisiert, abschliessender Trenner entfernt
|
||||
(tu-eq "omni:verbinder-pfad/backslash"
|
||||
"C:/x/data/omniflo/Verbinder/TV_W-W_kpl.dwg"
|
||||
(omni:verbinder-pfad "C:\\x\\data" "TV_W-W_kpl"))
|
||||
(tu-eq "omni:verbinder-pfad/trenner"
|
||||
"C:/x/data/omniflo/Verbinder/VB_ENDP_AP.dwg"
|
||||
(omni:verbinder-pfad "C:/x/data/" "VB_ENDP_AP"))
|
||||
)
|
||||
|
||||
|
||||
@@ -2270,6 +2498,279 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; TESTS: KettenFoerderer.lsp + ssg_ks_insert.lsp (KS-Orientierung)
|
||||
;; ------------------------------------------------------------
|
||||
;; Reine Rechenkerne des Kettenfoerderers: Hoehenbilanz, Massstab,
|
||||
;; Grenzpruefung, KS-Winkel. Alles ohne Zeichnung und ohne Blockdateien -
|
||||
;; die zeichnungsabhaengigen Teile (kf-geometrie-messen, kf-kette-bauen)
|
||||
;; brauchen BricsCAD und bleiben dem Befehl KF_KS_PRUEFEN vorbehalten.
|
||||
(defun tu-tests-kf ( / _l _s _defs)
|
||||
(princ "\n[KettenFoerderer]")
|
||||
(if (not (car (atoms-family 1 '("KF-LAENGE-BERECHNEN"))))
|
||||
(tu-record nil "KettenFoerderer-Modul geladen"
|
||||
"KettenFoerderer.lsp nicht geladen - siehe tests/test_unit.scr")
|
||||
(progn
|
||||
;; --- ks-winkel-normalisieren: auf -180..180 falten ---
|
||||
(tu-eqf "ks-winkel-norm/190" -170.0 (ks-winkel-normalisieren 190.0))
|
||||
(tu-eqf "ks-winkel-norm/-190" 170.0 (ks-winkel-normalisieren -190.0))
|
||||
(tu-eqf "ks-winkel-norm/26" 26.0 (ks-winkel-normalisieren 26.0))
|
||||
(tu-eqf "ks-winkel-norm/360" 0.0 (ks-winkel-normalisieren 360.0))
|
||||
(tu-nil "ks-winkel-norm/nil" (ks-winkel-normalisieren nil))
|
||||
|
||||
;; --- ks-xy-winkel: X-Achse eines KS-Eintrags (origin x-end y-end z-end)
|
||||
(tu-eqf "ks-xy-winkel/entlang-X" 0.0
|
||||
(ks-xy-winkel '((0.0 0.0 0.0) (1.0 0.0 0.0) (0.0 2.0 0.0) (0.0 0.0 3.0))))
|
||||
(tu-eqf "ks-xy-winkel/entlang-Y" 90.0
|
||||
(ks-xy-winkel '((0.0 0.0 0.0) (0.0 1.0 0.0) (-2.0 0.0 0.0) (0.0 0.0 3.0))))
|
||||
;; versetzter Ursprung: nur die RICHTUNG zaehlt, nicht die Lage
|
||||
(tu-eqf "ks-xy-winkel/versetzt-45" 45.0
|
||||
(ks-xy-winkel (list '(100.0 50.0 0.0) '(101.0 51.0 0.0) '(99.0 51.0 0.0) '(100.0 50.0 1.0))))
|
||||
;; senkrechte X-Achse (keine XY-Laenge) -> nil statt Division durch 0
|
||||
(tu-nil "ks-xy-winkel/senkrecht"
|
||||
(ks-xy-winkel '((0.0 0.0 0.0) (0.0 0.0 1.0) (0.0 2.0 0.0) (0.0 0.0 3.0))))
|
||||
|
||||
;; --- kf-hz-folge: Folgebaustein an KS_AUS des Vorgaengers ausrichten ---
|
||||
;; Vorgaenger zeigt 26 Grad, Folgebaustein ist waagerecht gezeichnet (0)
|
||||
(tu-eqf "kf-hz-folge/26-auf-0" 26.0 (kf-hz-folge 26.0 0.0))
|
||||
;; Folgebaustein ist selbst schon um 26 Grad gezeichnet -> keine Drehung
|
||||
(tu-eqf "kf-hz-folge/26-auf-26" 0.0 (kf-hz-folge 26.0 26.0))
|
||||
;; fehlende Eigenrichtung -> Baustein uebernimmt die Vorgaengerrichtung
|
||||
(tu-eqf "kf-hz-folge/ohne-beta" 26.0 (kf-hz-folge 26.0 nil))
|
||||
(tu-nil "kf-hz-folge/ohne-phi" (kf-hz-folge nil 0.0))
|
||||
|
||||
;; --- kf-dy-eingebaut: Hoehenbeitrag nach Rz(hz) und X-Massstab ---
|
||||
;; waagerechter Baustein, waagerecht eingebaut -> kein Hoehengewinn
|
||||
(tu-eqf "kf-dy/0-grad" 0.0 (kf-dy-eingebaut 1000.0 0.0 0.0 1.0))
|
||||
;; 1000 mm unter 30 Grad -> 500 mm (sin 30 = 0.5)
|
||||
(tu-eqf "kf-dy/30-grad" 500.0 (kf-dy-eingebaut 1000.0 0.0 30.0 1.0))
|
||||
;; derselbe Baustein doppelt skaliert -> doppelter Hoehengewinn
|
||||
(tu-eqf "kf-dy/30-grad-skaliert-2" 1000.0 (kf-dy-eingebaut 1000.0 0.0 30.0 2.0))
|
||||
;; senkrecht eingebaut -> die volle Laenge als Hoehe
|
||||
(tu-eqf "kf-dy/90-grad" 1000.0 (kf-dy-eingebaut 1000.0 0.0 90.0 1.0))
|
||||
|
||||
;; --- kf-laenge-berechnen: Hoehenbilanz nach der Laenge aufloesen ---
|
||||
;; H=1000, Stationen tragen nichts bei, 30 Grad -> L = 1000/sin30 = 2000
|
||||
(tu-eqf "kf-laenge/30-grad-glatt" 2000.0
|
||||
(kf-laenge-berechnen 1000.0 0.0 0.0 0.0 30.0))
|
||||
;; Stationen tragen 100+150 bei -> nur 750 mm bleiben fuer das Stueck
|
||||
(tu-eqf "kf-laenge/mit-stationen" 1500.0
|
||||
(kf-laenge-berechnen 1000.0 100.0 150.0 0.0 30.0))
|
||||
;; Gegenprobe: die errechnete Laenge ergibt wieder genau H
|
||||
(setq _l (kf-laenge-berechnen 1000.0 100.0 150.0 0.0 30.0))
|
||||
(tu-eqf "kf-laenge/rundlauf-ergibt-H" 1000.0
|
||||
(+ 100.0 150.0 (kf-dy-eingebaut _l 0.0 30.0 1.0)))
|
||||
;; bereits geneigt gezeichnetes Zwischenstueck: dy-nativ wird abgezogen
|
||||
;; (dy-nativ skaliert NICHT mit, nur X wird skaliert)
|
||||
(tu-eqf "kf-laenge/mit-dy-nativ" 1800.0
|
||||
(kf-laenge-berechnen 1000.0 0.0 0.0 (/ 100.0 (cos (/ pi 6.0))) 30.0))
|
||||
;; waagerecht -> keine Hoehe erreichbar
|
||||
(tu-nil "kf-laenge/0-grad-unloesbar"
|
||||
(kf-laenge-berechnen 1000.0 0.0 0.0 0.0 0.0))
|
||||
|
||||
;; --- kf-skala-berechnen ---
|
||||
(tu-eqf "kf-skala/2000-von-1000" 2.0 (kf-skala-berechnen 2000.0 1000.0))
|
||||
(tu-nil "kf-skala/ohne-nativlaenge" (kf-skala-berechnen 2000.0 0.0))
|
||||
(tu-nil "kf-skala/ohne-laenge" (kf-skala-berechnen nil 1000.0))
|
||||
|
||||
;; --- kf-laenge-pruefen: Grenzen aus der JSON ---
|
||||
(tu-nil "kf-pruefen/in-ordnung" (kf-laenge-pruefen 2000.0 100.0 20000.0))
|
||||
(tu-eq "kf-pruefen/zu-kurz" "kf-fehler-laenge-unter-min"
|
||||
(kf-laenge-pruefen 50.0 100.0 20000.0))
|
||||
(tu-eq "kf-pruefen/zu-lang" "kf-fehler-laenge-ueber-max"
|
||||
(kf-laenge-pruefen 99999.0 100.0 20000.0))
|
||||
;; negative Laenge = Stationen bringen mehr Hoehe mit als gefordert
|
||||
(tu-eq "kf-pruefen/negativ" "kf-fehler-hoehe-zu-klein"
|
||||
(kf-laenge-pruefen -10.0 100.0 20000.0))
|
||||
(tu-eq "kf-pruefen/nil" "kf-fehler-winkel-null"
|
||||
(kf-laenge-pruefen nil 100.0 20000.0))
|
||||
|
||||
;; --- kf-zahl: JSON-Wert als Zahl (Parser liefert Zahl ODER String) ---
|
||||
(tu-eqf "kf-zahl/int" 26.0 (kf-zahl 26))
|
||||
(tu-eqf "kf-zahl/real" 26.0 (kf-zahl 26.0))
|
||||
(tu-eqf "kf-zahl/string" 26.0 (kf-zahl "26"))
|
||||
(tu-nil "kf-zahl/nil" (kf-zahl nil))
|
||||
|
||||
;; --- kf-attrib-defs: VF-Schema + KF-Zusatz, KEIN Tag doppelt ---
|
||||
(setq _defs (kf-attrib-defs))
|
||||
(tu-true "kf-attrib-defs/hat-ID" (assoc "ID" _defs))
|
||||
(tu-true "kf-attrib-defs/hat-FOERDERERTYP" (assoc "FOERDERERTYP" _defs))
|
||||
(tu-true "kf-attrib-defs/hat-WINKEL" (assoc "WINKEL" _defs))
|
||||
(tu-true "kf-attrib-defs/hat-STANDARD_STEUERUNG"
|
||||
(assoc "STANDARD_STEUERUNG" _defs))
|
||||
;; Reihenfolge wie im Sivas-Merkmalstamm: 361 folgt direkt auf den Typ,
|
||||
;; STANDARD_STEUERUNG steht also unmittelbar hinter WINKEL
|
||||
(tu-eq "kf-attrib-defs/361-folgt-auf-winkel" "STANDARD_STEUERUNG"
|
||||
(car (nth (1+ (kf-tag-index "WINKEL" _defs)) _defs)))
|
||||
;; FOERDERERTYP ist die BAUART im Klartext, der Winkel steht in WINKEL
|
||||
(tu-eq "kf-attrib-defs/FOERDERERTYP-ist-bauart" "Schraegfoerderer Stahl"
|
||||
(cadr (assoc "FOERDERERTYP" _defs)))
|
||||
(tu-true "kf-attrib-defs/hat-MOVIMOT" (assoc "MOVIMOT" _defs))
|
||||
;; Farbe und Antriebsmotor sind ZWEI Eigenschaften (Sivas 354 bzw. 355), nicht
|
||||
;; ein kombiniertes AUSFUEHRUNG-Attribut
|
||||
(tu-true "kf-attrib-defs/hat-FARBE" (assoc "FARBE" _defs))
|
||||
(tu-true "kf-attrib-defs/hat-ANTRIEBSMOTOR" (assoc "ANTRIEBSMOTOR" _defs))
|
||||
(tu-nil "kf-attrib-defs/kein-AUSFUEHRUNG" (assoc "AUSFUEHRUNG" _defs))
|
||||
;; Der Kettenfoerderer traegt sich selbst - die Geruest-Tags aus dem
|
||||
;; VF-Schema werden bewusst NICHT mitgefuehrt
|
||||
(tu-nil "kf-attrib-defs/kein-GERUEST_EINZELMODUL"
|
||||
(assoc "GERUEST_EINZELMODUL" _defs))
|
||||
(tu-nil "kf-attrib-defs/kein-GERUEST_TYP" (assoc "GERUEST_TYP" _defs))
|
||||
;; TYP/ARTINR stehen in BEIDEN Listen - der Zusatz muss gewinnen, und
|
||||
;; der Tag darf nur EINMAL vorkommen (zwei ATTDEFs gleichen Tags waeren
|
||||
;; im Block ungueltig, ssg-attrib-set-on traefe nur den ersten).
|
||||
(tu-eq "kf-attrib-defs/TYP-ueberschrieben" "Kettenfoerderer"
|
||||
(cadr (assoc "TYP" _defs)))
|
||||
(setq _s 0)
|
||||
(foreach _d _defs (if (= (car _d) "TYP") (setq _s (1+ _s))))
|
||||
(tu-eq "kf-attrib-defs/TYP-nur-einmal" 1 _s)
|
||||
(setq _s 0)
|
||||
(foreach _d _defs (if (= (car _d) "ARTINR") (setq _s (1+ _s))))
|
||||
(tu-eq "kf-attrib-defs/ARTINR-nur-einmal" 1 _s)
|
||||
;; Der Winkel steht ALLEIN in FOERDERERTYP - kein zweites Winkel-Tag
|
||||
(tu-nil "kf-attrib-defs/kein-KF_WINKEL" (assoc "KF_WINKEL" _defs))
|
||||
(tu-nil "kf-attrib-defs/kein-KF_TYP" (assoc "KF_TYP" _defs))
|
||||
;; Das Schema ist EIGENSTAENDIG, nicht vom VF-Streckenschema geerbt -
|
||||
;; keines der VF-Tags darf durchschlagen
|
||||
(tu-nil "kf-attrib-defs/kein-SEITE_AS" (assoc "SEITE_AS" _defs))
|
||||
(tu-nil "kf-attrib-defs/kein-ANZAHL_VF" (assoc "ANZAHL_VF" _defs))
|
||||
(tu-nil "kf-attrib-defs/kein-TEILEART" (assoc "TEILEART" _defs))
|
||||
(tu-eq "kf-attrib-defs/LAYER-ist-F-3" "F-3" (cadr (assoc "LAYER" _defs)))
|
||||
|
||||
;; --- kf-variante-finden: ueber den Winkel, auch als String ---
|
||||
(tu-eq "kf-variante-finden/26" "A"
|
||||
(cdr (assoc "name"
|
||||
(kf-variante-finden 26
|
||||
'((("winkel" . 26) ("name" . "A"))
|
||||
(("winkel" . 30) ("name" . "B")))))))
|
||||
(tu-eq "kf-variante-finden/30-als-string" "B"
|
||||
(cdr (assoc "name"
|
||||
(kf-variante-finden 30
|
||||
'((("winkel" . "26") ("name" . "A"))
|
||||
(("winkel" . "30") ("name" . "B")))))))
|
||||
(tu-nil "kf-variante-finden/unbekannt"
|
||||
(kf-variante-finden 45 '((("winkel" . 26) ("name" . "A")))))
|
||||
|
||||
;; --- kf-antriebsart (Merkmal 357): Dropdown mit EINER Option ---
|
||||
;; Der Wert kommt aus dem ERSTEN Listeneintrag - nicht aus dem Code.
|
||||
(tu-eq "kf-antriebsart/aus-daten" "1.1 kW"
|
||||
(kf-antriebsart '(("antriebsart" (("name" . "1.1 kW") ("wert" . "1.1 kW"))))))
|
||||
;; eine zweite Option aendert die Vorgabe NICHT (Index 0 bleibt massgebend)
|
||||
(tu-eq "kf-antriebsart/erster-eintrag-gewinnt" "1.1 kW"
|
||||
(kf-antriebsart '(("antriebsart" (("name" . "1.1 kW") ("wert" . "1.1 kW"))
|
||||
(("name" . "0.55 kW") ("wert" . "0.55 kW"))))))
|
||||
;; Liste fehlt -> Rueckfall, aber als STRING (nicht T/nil)
|
||||
(tu-eq "kf-antriebsart/ohne-eintrag" "1.1 kW" (kf-antriebsart '(("titel" . "x"))))
|
||||
(tu-true "kf-antriebsart/ist-string"
|
||||
(= (type (kf-antriebsart '(("titel" . "x")))) 'STR))
|
||||
;; Dezimalpunkt, kein Komma (Nutzervorgabe)
|
||||
(tu-nil "kf-antriebsart/kein-komma"
|
||||
(vl-string-search "," (kf-antriebsart '(("titel" . "x")))))
|
||||
|
||||
;; --- kf-drehung-gesamt: Drehwinkel fuer KF_EDIT ---
|
||||
;; Regression: der Drehwinkel wird beim Bau in die Geometrie eingerechnet,
|
||||
;; die Blockreferenz selbst hat IMMER Drehung 0 (ssg-block-wrap-welt).
|
||||
;; KF_EDIT las nur Gruppencode 50 und baute eine mit 90 Grad gebaute
|
||||
;; Kette ungedreht neu. Der gebaute Winkel steht jetzt als XDATA.
|
||||
(tu-eqf "kf-drehung/nur-xdata" 90.0 (kf-drehung-gesamt 90.0 0.0))
|
||||
;; Referenz nachtraeglich von Hand um 90 Grad gedreht (Gruppencode 50 in
|
||||
;; Bogenmass) -> beides addiert sich
|
||||
(tu-eqf "kf-drehung/xdata-plus-referenz" 180.0
|
||||
(kf-drehung-gesamt 90.0 (/ pi 2.0)))
|
||||
;; Altbestand ohne XDATA: nur die Referenzdrehung (bisheriges Verhalten)
|
||||
(tu-eqf "kf-drehung/ohne-xdata" 45.0 (kf-drehung-gesamt nil (/ pi 4.0)))
|
||||
;; nichts bekannt -> 0, kein Absturz und kein nil
|
||||
(tu-eqf "kf-drehung/nichts" 0.0 (kf-drehung-gesamt nil nil))
|
||||
(tu-true "kf-drehung/ist-zahl" (numberp (kf-drehung-gesamt nil nil)))
|
||||
;; Summe ueber 180 Grad wird auf -180..180 gefaltet (270 = -90)
|
||||
(tu-eqf "kf-drehung/normalisiert" -90.0
|
||||
(kf-drehung-gesamt 180.0 (/ pi 2.0)))
|
||||
;; ganze Zahl aus der XDATA (nicht real) darf nicht abstuerzen
|
||||
(tu-eqf "kf-drehung/ganzzahl" 30.0 (kf-drehung-gesamt 30 0.0))
|
||||
|
||||
;; --- kf-neigung-aus-punkten: Kern der 3D-Aufrichtung ---
|
||||
;; Liefert (Schraeglaenge Neigungswinkel) aus Ketten-Start und -Ende.
|
||||
;; Die Kette wird AUFGERICHTET eingebaut, die Hoehe laeuft also in Z.
|
||||
;; 3-4-5-Dreieck: 3000 waagerecht, 4000 hoch -> 5000 schraeg
|
||||
(tu-eqf "kf-neigung/3-4-5-laenge" 5000.0
|
||||
(car (kf-neigung-aus-punkten '(0.0 0.0 0.0) '(3000.0 0.0 4000.0) 0.0)))
|
||||
;; 45 Grad: gleiche Betraege waagerecht und hoch
|
||||
(tu-eqf "kf-neigung/45-grad" 45.0
|
||||
(cadr (kf-neigung-aus-punkten '(0.0 0.0 0.0) '(1000.0 0.0 1000.0) 0.0)))
|
||||
;; waagerecht -> Winkel 0, Laenge = Horizontalabstand
|
||||
(tu-eqf "kf-neigung/waagerecht" '(2000.0 0.0)
|
||||
(kf-neigung-aus-punkten '(0.0 0.0 0.0) '(2000.0 0.0 0.0) 0.0))
|
||||
;; Der Horizontalanteil wird auf die KETTENRICHTUNG projiziert, nicht
|
||||
;; auf die Welt-X-Achse: bei 90 Grad Basisdrehung laeuft die Kette in Y.
|
||||
;; Ohne Projektion kaeme hier 0 heraus und der Winkel waere 90 statt 45.
|
||||
(tu-eqf "kf-neigung/gedreht-90" '(1414.213562 45.0)
|
||||
(kf-neigung-aus-punkten '(0.0 0.0 0.0) '(0.0 1000.0 1000.0) 90.0))
|
||||
;; fallende Kette -> negativer Winkel
|
||||
(tu-eqf "kf-neigung/fallend" -45.0
|
||||
(cadr (kf-neigung-aus-punkten '(0.0 0.0 1000.0) '(1000.0 0.0 0.0) 0.0)))
|
||||
;; Start = Ende -> nil statt Division durch 0
|
||||
(tu-nil "kf-neigung/nulllaenge"
|
||||
(kf-neigung-aus-punkten '(5.0 5.0 5.0) '(5.0 5.0 5.0) 0.0))
|
||||
|
||||
;; --- kf-matrix-aufrecht: Y_lokal wird zu Z_welt ---
|
||||
;; Das ist die Kernaussage der Aufrichtung. Geprueft wird sie an den
|
||||
;; Bildern der Einheitsvektoren, nicht an den Matrixeintraegen - so
|
||||
;; bleibt der Test lesbar und unabhaengig von der Schreibweise.
|
||||
(tu-eqf "kf-matrix/Y-lokal-wird-Z-welt" '(0.0 0.0 1.0)
|
||||
(mat3-mul-vec3 (kf-matrix-aufrecht 0.0 0.0) '(0.0 1.0 0.0)))
|
||||
;; Die Fahrtrichtung (X) bleibt bei Basisdrehung 0 die Welt-X-Achse
|
||||
(tu-eqf "kf-matrix/X-bleibt-X" '(1.0 0.0 0.0)
|
||||
(mat3-mul-vec3 (kf-matrix-aufrecht 0.0 0.0) '(1.0 0.0 0.0)))
|
||||
;; Basisdrehung 90 Grad dreht die Fahrtrichtung in die Welt-Y-Achse,
|
||||
;; die Hoehe bleibt dabei in Z
|
||||
(tu-eqf "kf-matrix/basis-90-dreht-X-nach-Y" '(0.0 1.0 0.0)
|
||||
(mat3-mul-vec3 (kf-matrix-aufrecht 90.0 0.0) '(1.0 0.0 0.0)))
|
||||
(tu-eqf "kf-matrix/basis-90-haelt-Z" '(0.0 0.0 1.0)
|
||||
(mat3-mul-vec3 (kf-matrix-aufrecht 90.0 0.0) '(0.0 1.0 0.0)))
|
||||
|
||||
;; --- Standard-Variante: steht in den DATEN, nicht im Code ---
|
||||
(tu-true "kf-variante-standard-p/markiert"
|
||||
(kf-variante-standard-p '(("winkel" . 26) ("standard" . T))))
|
||||
(tu-nil "kf-variante-standard-p/ohne-feld"
|
||||
(kf-variante-standard-p '(("winkel" . 30))))
|
||||
;; Index fuer die Vorauswahl - auch wenn der Standard NICHT der erste ist
|
||||
(tu-eq "kf-standard-index/zweiter" 1
|
||||
(kf-standard-index '((("winkel" . 26))
|
||||
(("winkel" . 30) ("standard" . T)))))
|
||||
(tu-eq "kf-standard-index/erster" 0
|
||||
(kf-standard-index '((("winkel" . 26) ("standard" . T))
|
||||
(("winkel" . 30)))))
|
||||
;; keine Variante markiert -> erste, statt nil (der Dialog braucht einen Index)
|
||||
(tu-eq "kf-standard-index/keiner" 0
|
||||
(kf-standard-index '((("winkel" . 26)) (("winkel" . 30)))))
|
||||
|
||||
;; --- kf-punkt-differenzen: zweite Hoehen-Eingabeart (2 Punkte) ---
|
||||
;; Gemessen wird die Differenz in Z - die Baugruppe steht aufgerichtet im
|
||||
;; Modell. Zurueckgegeben wird (dz dy): die HOEHE zuerst, dY nur zur
|
||||
;; Kontrolle (wer in einer Draufsicht pickt, sieht dz = 0).
|
||||
(tu-eqf "kf-punkt-diff/dz" '(1500.0 0.0)
|
||||
(kf-punkt-differenzen '(0.0 0.0 0.0) '(2000.0 0.0 1500.0)))
|
||||
;; Vorzeichen egal - die Reihenfolge der Punkte darf keine Rolle spielen
|
||||
(tu-eqf "kf-punkt-diff/umgekehrt" '(1500.0 0.0)
|
||||
(kf-punkt-differenzen '(2000.0 0.0 1500.0) '(0.0 0.0 0.0)))
|
||||
;; in einer Draufsicht gepickt: dz = 0, dY gross
|
||||
(tu-eqf "kf-punkt-diff/draufsicht" '(0.0 1200.0)
|
||||
(kf-punkt-differenzen '(0.0 0.0 0.0) '(3000.0 1200.0 0.0)))
|
||||
;; Punkte ohne Z (2D-Pick) duerfen nicht abstuerzen: dz ist dann 0
|
||||
(tu-eqf "kf-punkt-diff/ohne-z" '(0.0 800.0)
|
||||
(kf-punkt-differenzen '(0.0 0.0) '(100.0 800.0)))
|
||||
(tu-nil "kf-punkt-diff/nil" (kf-punkt-differenzen nil '(1.0 2.0 3.0)))
|
||||
|
||||
;; --- kf-auswahl-wert: "wert" vor "name", Vorgabe bei leerem Index ---
|
||||
(tu-eq "kf-auswahl-wert/wert" "Nein"
|
||||
(kf-auswahl-wert '((("name" . "Nein") ("wert" . "Nein"))) 0 "X"))
|
||||
(tu-eq "kf-auswahl-wert/ausserhalb" "X"
|
||||
(kf-auswahl-wert '((("name" . "Nein") ("wert" . "Nein"))) 5 "X"))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(defun c:TEST_UNIT ( / out-dir report)
|
||||
(tu-reset)
|
||||
(princ "\n================================================================")
|
||||
@@ -2277,11 +2778,12 @@
|
||||
(princ "\n================================================================")
|
||||
|
||||
(foreach fn '("tu-tests-core" "tu-tests-lang" "tu-tests-id" "tu-tests-vfcore"
|
||||
"tu-tests-etage" "tu-tests-vfl-es" "tu-tests-vfl-ziellinie"
|
||||
"tu-tests-etage" "tu-tests-vfl-es" "tu-tests-vfl-parallel"
|
||||
"tu-tests-vfl-ziellinie"
|
||||
"tu-tests-export" "tu-tests-hoehen" "tu-tests-gf" "tu-tests-omni" "tu-tests-kreisel" "tu-tests-kreisel-bp"
|
||||
"tu-tests-sepliste" "tu-tests-json" "tu-tests-geruest"
|
||||
"tu-tests-sepscan" "tu-tests-vfl-segs" "tu-tests-vfl-abbruch"
|
||||
"tu-tests-werkzeuge")
|
||||
"tu-tests-werkzeuge" "tu-tests-kf")
|
||||
(tu-run-block fn))
|
||||
|
||||
(princ "\n\n----------------------------------------------------------------")
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
; Modul, gehoert dessen load-Zeile HIER dazu (nicht in test_unit.lsp).
|
||||
(load (strcat (getenv "DXFM_LISP") "/GeruestInsert.lsp") "GeruestInsert.lsp nicht gefunden")
|
||||
(load (strcat (getenv "DXFM_LISP") "/count_sep_scan.lsp") "count_sep_scan.lsp nicht gefunden")
|
||||
(load (strcat (getenv "DXFM_LISP") "/KettenFoerderer.lsp") "KettenFoerderer.lsp nicht gefunden")
|
||||
(load (strcat (getenv "DXFMAKRO") "/tests/test_unit.lsp"))
|
||||
(c:TEST_UNIT)
|
||||
(command "_.QUIT")
|
||||
|
||||
Reference in New Issue
Block a user