Commit Graph

25 Commits

Author SHA1 Message Date
m.stangl 842e93c571 [FIX] CSV-Export K1/K2 = Eingang/Ausgang; GF-Richtung ueber die Hoehe
K1 ist jetzt IMMER der Eingang eines Elements, K2 IMMER der Ausgang
(AS = Eingangs-Element mit KS_EIN, ES = Ausgangs-Element mit KS_AUS).

- VarioFoerderer/Strecke (VF_*): Richtung liegt ueber die Elementrolle fest
  -> K1 = AS-Ende (KS_EIN), K2 = ES-Ende (KS_AUS). Verhalten unveraendert.
- Gefaellestrecke (GF_*): Foerderrichtung ist bergab, also durch die HOEHE
  bestimmt (HOEHE_VON_mm > HOEHE_BIS_mm, siehe check_hoehen.lsp). Der Eingang
  ist das HOEHERE Ende, der Ausgang das TIEFERE - unabhaengig davon, welches
  physische Element das AS bzw. ES ist. csv:vfgf-k-kos-strings sortiert bei
  GF darum nach Z (hoeheres Z -> K1, tieferes Z -> K2); Fallback auf die
  Rolle, wenn nur ein Ende gefunden wird.

Verifiziert: vario-VF K1 bei VF-x=0 (AS), K2 bei VF-x=15000 (ES);
mubea-GF 0016 AS_z=1852 >= ES_z=1537 -> K1=Eingang(hoch), K2=Ausgang(tief).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-09-04 21:41:43 +02:00
m.stangl 7eff324056 [FIX] VF/GF K1/K2-Export: KS_EIN/KS_AUS aus dem RICHTIGEN AS/ES-Element
csv:vfgf-k-kos-strings suchte KS_EIN/KS_AUS flach ueber den GANZEN VF_n/GF_n-
Wrapper. Da sowohl das AS_Element als auch das ES_Element JEWEILS ein KS_EIN
UND ein KS_AUS fuehren (siehe check_hoehen.lsp ch-measure-vfgf), lieferte die
flache Suche zwei Treffer und (car ...) griff den falschen: K2 (ES) landete
auf dem KS_AUS des AS_Elements, also auf der Anfangs-/linken Seite statt am
ES-Ende. Fuer results/vario.dxf standen K1 und K2 dadurch beide nahe x=0.

Neue Helferfunktion csv:vfgf-ks-loc: erst das passende Element (AS_ELEMENT*
bzw. ES_ELEMENT*) suchen, dann NUR IN DESSEN Blockdefinition das KS
(KS_EIN fuer K1, KS_AUS fuer K2) und ueber die Weltlage des Elements
(world-pt/R-world/Skalierung) in den Wrapper-Frame transformieren -
gleiche zweistufige Logik wie ch-measure-vfgf. Am vario-Testfall verifiziert:
K1 (AS) bei VF-x=0, K2 (ES) bei VF-x=15000 (rechtes Ende).

Behebt zugleich die Ursache der ausgefallenen Ein-/Ausschleus-Kollision
(export_neighbors.py testet die AS/ES-Box an K1/K2 gegen die Kreisel).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-09-04 20:49:03 +02:00
m.stangl c88be420be [ADD] AS/ES-Koordinatensysteme als K1/K2 exportieren + Kollision/Schleuselemente daran ausrichten
Export (Lisp/export.lsp):
- Neue csv:vfgf-k-kos-strings leitet fuer VF_n/GF_n-Wrapper K1 (AS/KS_EIN) und
  K2 (ES/KS_AUS) aus den verschachtelten AS_Element/ES_Element ab (via
  ssg-collect-nested-inserts) und schreibt sie wie K1-K4 als Positions-String.
  Bisher waren die K-Spalten fuer Strecken leer.

Kollisionspruefung Kreisel<->GF/VF (lib/export_neighbors.py):
- compute_neighbor_ids testet Strecken (GF/VF UND "ILS 2.0 Strecke - Modul")
  nicht mehr ueber die grosse Wrapper-Box, sondern ueber je eine kleine feste
  Box an der AS- (K1) und ES-Position (K2). Fallback auf Wrapper-Box, wenn
  K1/K2 fehlen (Altbestand).

Schleuselement-Positionen (lib/export_neighbors.py):
- compute_strecke_kreisel_schleus setzt Aus-/Einschleuselement ans AS/ES-KOS,
  um eine halbe Box entlang der Foerderachse nach aussen versetzt (AS: davor,
  ES: dahinter) - realistischer als der bisherige Kreiselrand-Punkt.

Keine Magic Numbers (cfg/export.cfg [Boundingbox]):
- element_box_laenge/breite/hoehe_mm (250/100/30) ersetzen die WEICHE_BOX_*-
  Konstanten; gelesen von load_element_box_mm und an alle Rechenfunktionen
  durchgereicht (WEICHE_BOX_* nur noch dokumentierter Fallback).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-09-04 14:00:52 +02:00
s.ayadi 29b7bf1a10 [FIX] Weltposition verpackter Separator_SP-Symbole bei gekippten Ketten
ssg-collect-nested-inserts-rel/csv:sep-proxies-erzeugen nahmen bislang eine
reine Z-Drehung ohne OCS-/Extrusionsrichtung an. Fuer die um den Gefaelle-/
Neigungswinkel gekippte Staustrecke/Separator-Kette (Gefaellestrecke.lsp,
vf_standard.lsp) ist das falsch: die eingebettete Separator_SP-Weltposition
blieb dadurch unabhaengig von der gewaehlten Fahrtrichtung eingefroren.

Fix generalisiert die Rotationskomposition auf volle 3x3-Matrizen (Arbitrary
Axis Algorithm fuer die Extrusion, neue mat3-*-Helfer in ssg_core.lsp statt
vf_core.lsp, da ssg_core immer vor jedem Feature-Modul geladen ist). Fuer
flache Elemente (Extrusion (0 0 1)) reduziert sich das exakt auf die alte
reine Z-Drehung - kein Verhaltensunterschied dort.

Verifiziert per Python/ezdxf-Nachbau des neuen Algorithmus gegen die drei
real gebauten Testzeichnungen (data/gf.dxf, data/gf_north.dxf,
data/gf_south.dxf): liefert jetzt fuer alle drei Fahrtrichtungen exakt die
unabhaengig berechnete Grundwahrheit statt eines eingefrorenen Werts.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-04 12:42:10 +02:00
s.ayadi 21684101f9 [FIX] Eindeutige IDs und korrekte ZUORDNUNG der verpackten Separatoren
Beim CSV-Export von Mubea trugen Gefaellestrecke/VF/Kreisel und die aus
ihnen erzeugten Separator-Kopien dieselbe ID (26 Dubletten 0001-0026), und
die ZUORDNUNG der Separatoren zeigte auf den falschen Carrier.

ssg-id-check-all: neue Phase 0 ermittelt das globale Maximum der bereits
vergebenen IDs, BEVOR die erste neue ID vergeben wird (ausgelagert nach
ssg-id-max-in-ss, das auch ssg-id-max nutzt). Bisher wurde max-id erst
waehrend Phase 1 mitgezogen (Start 0); da (ssget "X" ...) in BricsCAD die
zuletzt erzeugten Entities zuerst liefert, standen die noch ID-losen
Separator-Kopien ganz vorne und bekamen 0001, 0002, ... - genau die IDs der
weiter hinten liegenden Wrapper-Bloecke. Phase 2 konnte das nicht heilen,
weil frisch vergebene IDs nicht in id-map landen.

ssg-collect-nested-inserts: fuehrt Position, Z-Drehung und Skalierung jetzt
ueber alle Verschachtelungsebenen mit (Records statt nackter Entity-Namen).
Vorher gab die Rekursion Entities tieferer Ebenen mit ihrer ROH-Position aus
der Zwischen-Blockdefinition zurueck - zwei Separatoren an derselben lokalen
Stelle in zwei verschieden platzierten Zwischenbloecken landeten dadurch auf
exakt derselben Weltposition.

csv:sep-proxies-erzeugen: die Kopie steht jetzt exakt auf Position/Drehung/
Skalierung ihres verpackten Vorbilds; der kosmetische Versatz von 500 mm ist
weg (er kippte Separatoren am Kettenende in die Boundingbox des Nachbar-
Carriers). Der vla-InsertBlock-Aufruf ist gekapselt, damit ein Sonderfall
nur diese eine Kopie ausfallen laesst statt den ganzen Export abzubrechen.

csv:sep-proxies-zuordnung-setzen (neu, laeuft NACH ssg-id-check-all, da ein
frisch gebauter Wrapper vorher keine ID hat): fuer einen VERPACKTEN Separator
ist der Carrier bekannt - es ist der Wrapper, in dem er steckt. ZUORDNUNG
wird daher auf die Wrapper-ID gesetzt (Separator in VF 0010 -> ZUORDNUNG
0010) und ueber *cs-sep-fix-by-handle* festgenagelt: cs-zuordnung-lauf
uebernimmt sie unveraendert statt sie geometrisch neu zu raten, und
csv:block-to-json reicht sie als "zuordnung_fix" an export_csv.py durch.
Ohne das ueberschrieb compute_sensor_zuordnung (Prioritaet GF > Foerderer >
Kreiselhaelfte) den bekannten Wert - in der Mubea-Zeichnung landeten 26 in
VF/GF verpackte Separatoren so bei einer Kreiselhaelfte.

export_csv.py: respektiert "zuordnung_fix" und ersetzt eine vorhandene
ZUORDNUNG nicht mehr durch "nicht zugeordnet" - nur ein echter Treffer
ueberschreibt, wie im Docstring von compute_sensor_zuordnung beschrieben.

tests/test_export_ids.py (neu): prueft je tests/output/*_export.csv, dass
jede TeileId hoechstens einmal vorkommt und jede Sensor-Zuordnung auf eine
existierende TeileId zeigt. Gegen die fehlerhafte Mubea-CSV schlaegt der
Test mit allen 26 Dubletten an.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-03 11:38:18 +02:00
s.ayadi e2f038465b [FEAT] Verpackte Separator_SP-Sensoren in VF_n/GF_n/KREISEL_n vor Export erfassen
Separator_SP_2D/_3D-Sensorsymbole, die beim Zusammenbau der Compound-Bloecke
(VF_n/GF_n/KREISEL_n) als Sub-INSERT in deren Blockdefinition verpackt
wurden, waren fuer (ssget "X" ...) unsichtbar und blieben daher ohne eigene
ID und ohne Zeile im Export-JSON. csv:sep-proxies-erzeugen (export.lsp)
sucht solche verpackten Symbole jetzt vor jedem EXPORTCSV/EXPORTSIVAS ueber
den neuen rekursiven Helfer ssg-collect-nested-inserts (ssg_core.lsp) und
legt fuer jeden Fund eine echte, temporaere Kopie an seiner Weltposition an
(silent ueber vla-InsertBlock statt command-line INSERT). Diese Kopie
durchlaeuft ID-Vergabe/Export unveraendert ueber die bestehenden Funktionen
und wird danach wieder entfernt (csv:sep-proxies-loeschen).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 10:03:00 +02:00
m.stangl 9341d4c5c2 Sensor-Zuordnung: billiger Schnelltest vor teurem Lauf
cs-zuordnung-noetig-p prueft ohne jede Boundingbox (nur Attribute lesen +
interne Ketten-Separatoren aus der Blockdefinition zaehlen), ob der teure
cs-zuordnung-lauf (Boundingbox+Regen je Carrier und Sensor) ueberhaupt
noetig ist. Voller Lauf nur bei leeren ZUORDNUNG-Eintraegen oder wenn die
Summe ANZAHL_SCANNER/ANZAHL_SEPARATOR ueber alle Carrier nicht zur Anzahl
der Scanner-/Separator-Symbole (+ interne Ketten-Separatoren) passt.
Sonst wird uebersprungen (neue Meldung sens-skip).

csv:run-export ruft die Zuordnung jetzt nur noch bei Bedarf auf. Der
interaktive Befehl ZAEHLE_SEP_SCAN rechnet weiterhin immer komplett neu
(deckt auch den Fall ab, dass ein Sensor ohne Summenaenderung von einem
Carrier zu einem anderen verschoben wurde).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-21 15:54:47 +02:00
m.stangl edfba75801 Sensor-Zuordnung: Separator/Scanner je Kreisel/Strecke zaehlen vor Export
count_sep_scan.lsp neu als wiederverwendbare Engine (cs-zuordnung-lauf),
die automatisch vor jedem CSV-/Sivas-Export laeuft (export.lsp,
csv:run-export). Zaehlt Separator_SP/Scanner je Carrier (Kreisel/Eckrad,
VF_*, GF_*) ueber die gemeinsamen cfg/export.cfg-Muster und schreibt
ANZAHL_SEPARATOR/ANZAHL_SCANNER, so dass die Summe zur Szene passt.

Scanner ausserhalb jeder Carrier-Boundingbox ohne ZUORDNUNG werden per
Abstand dem naechsten Kreisel/Strecke zugeschlagen (ZUORDNUNG = Carrier-ID).
Ist der Abstand zum zweitnaechsten Kandidaten fast gleich (<= strittig_diff_mm,
neu in cfg/export.cfg [Sensorzuordnung]), gilt die Zuordnung als strittig:
Konsolenausgabe der ergaenzten Scanner + JSON-"warnung"-Feld mit den IDs der
strittigen Kandidaten (csv:block-to-json), das export_csv.py in der Spalte
"Warnungen" ausgibt.

Menue: ZAEHLE_SEP_SCAN-Vorlauf vor EXPORTSIVAS entfernt (laeuft jetzt
automatisch im Export); interaktiver Befehl bleibt erhalten.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-21 15:37:50 +02:00
m.stangl 9c8f84799c [CHANGE] Omniflo-Nachbarschaft: STRtree-Broad-Phase + KOS-Verfeinerung (10mm); Gerade-K1/K2 im CSV-Export
Die Omniflo-Nachbarschaftserkennung (export_neighbors.py, nur EXPORTCSV) wird
zweistufig:
- Broad-Phase ueber shapely-STRtree auf den Bounding-Boxen (Fallback: das
  bisherige Raster, falls shapely fehlt).
- Narrow-Phase (KOS-Verfeinerung): zwei moegliche Nachbarn gelten nur dann als
  benachbart, wenn ein Anschluss-Koordinatensystem K1-K4 des einen naeher als
  omniflo_ks_toleranz_mm (neu, Default 10mm) an einem K-Punkt des anderen
  liegt. Das verwirft bloss ueberlappende BBoxen ohne echten Anschluss.
  Elemente ohne K1-K4 fallen auf reine BBox-Ueberschneidung zurueck.

Geraden fuehren keine echten K-Bloecke in der Zeichnung; ihre K1 (Anfang) /
K2 (Ende) werden beim Export aus Einfuegepunkt + Laenge + Rotation
synthetisiert (csv:gerade-k-kos-strings in export.lsp) und stehen damit in den
CSV-Spalten K1/K2 - wie echte KOS - und nehmen an der Kollisionspruefung teil.

Verifiziert an results/test-omnicollision: gerichtete Nachbarschaften 20 -> 14.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-31 16:56:10 +02:00
m.stangl bd79e3d1b6 [FIX] export.lsp: klare Fehlermeldung statt Lisp-Crash bei fehlendem DXFM_LIB
Ist BricsCAD nicht ueber bin/start_briscad.bat gestartet worden, ist DXFM_LIB
in der Sitzung nicht gesetzt. Bisher liess das (strcat (getenv "DXFM_LIB") ...)
mit "bad argument type <NIL> ; expected <STRING>" abstuerzen. Jetzt wird das
vorher geprueft und ueber ssg-textf (exp-dxfm-lib-missing, de/en) gemeldet;
JSON/CSV-Sammlung laeuft weiter, nur der Python-Aufruf entfaellt.
2026-07-31 16:02:33 +02:00
s.ayadi 88fc00a5c0 [FIX] Python-Interpreter fuer Export robust ermitteln + Sprachtexte
Unter Windows 11 traf ein blankes "python" den WindowsApps-Platzhalter
(kein echter Interpreter, Exitcode 49). Der Export schrieb die JSON, aber
nie eine CSV - ohne jede Fehlermeldung, da "fire and forget" per startapp.

- export:python-exe: Aufloesungsreihenfolge cfg/export.cfg [python]
  interpreter= -> DXFM_PYTHON -> Projekt-venv -> %SystemRoot%/py.exe ->
  "python"; WindowsApps-Platzhalter werden verworfen
- export:run-python: synchroner Aufruf per WScript.Shell.Run, stdout/stderr
  nach DXFM_LOG/export_python.log, Exitcode-Auswertung
- export:log-ausgeben: erste Logzeilen in die BricsCAD-Kommandozeile
- setenv.bat setzt DXFM_PYTHON (venv oder py-Launcher)
- cfg/export.cfg: neue Sektion [python]
- lang/de_DE.json, lang/en_GB.json: neue Meldungstexte (exp-python-exe,
  exp-export-done, exp-python-error, exp-python-store-hint, exp-csv-missing,
  exp-python-call-failed)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 12:06:11 +02:00
m.stangl dc23a5f1a0 fix 2026-07-28 16:27:36 +02:00
m.stangl 52264f1531 Export: Insertpoint (24-Zeichen KOS) und K1-K4 (12-Zeichen Position) je Block
csv:block-to-json ergaenzt fuer jeden Block einen Insertpoint-String
(Position+Rotation als Z-Quaternion, csv:kos-encode) sowie K1-K4 als
reine Positions-Strings (csv:trans-encode, 0.1 mm). KS_EIN/KS_AUS werden
auf K1/K2 gemappt, falls keine echten K1/K2 vorhanden sind. Neue CSV-
Spalten Insertpoint;K1;K2;K3;K4 in export_csv.py.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 14:38:08 +02:00
m.stangl f51b421e23 Export der BB enthält mindesthöhe 2026-07-23 14:06:06 +02:00
m.stangl 193b0dea04 CSV-Export: Bounding-Box (Position/Boundingbox) und Planquadrat-Spalte ergaenzt
Nur EXPORTCSV betroffen, EXPORTSIVAS bleibt unveraendert:
- Position/Boundingbox: Bounding-Box je Block per vla-getboundingbox
  (Lisp/export.lsp, csv:get-bbox), Mittelpunkt und Ausdehnung x/y/z.
- Planquadrat: aus x/y-Koordinate berechnet nach cfg/export.cfg
  [Planquadrate] (Schrittweite, numerisch/alphabetisch je Achse,
  alphabetische Zaehlung mit Excel-Spalten-Umlauf Z->AA), siehe
  lib/export_planquadrat.py.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-22 12:52:33 +02:00
m.stangl 2eca169326 Uebersetzung aller Benutzermeldungen auf ssg-text/ssg-textf umgestellt
Vollstaendiger i18n-Rollout ueber alle Feature- und Kernmodule: alle benutzersichtbaren princ/prompt/getXXX/alert-Texte laufen jetzt ueber die zentrale Sprachtabelle in ssg_lang.lsp (Deutsch/Englisch, umschaltbar via SSG_SPRACHE). 403 Tabelleneintraege, 497 Aufrufstellen in 17 Dateien.

Ausgeschlossen wie geplant: Debug-Ausgaben (dbg*), Lademeldungen, [DUMMY]-Platzhalter, [CFG]/[OMNI]-Diagnosemarker.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 21:24:18 +02:00
m.stangl ab7fc92e23 Ausgabeverzeichnis nur über Lisp Variable festlegen. Anscheinend speichert Bricscad Umgebungen über die Sessions hinweg. Die Ausgaben der Tests landen woanders als der generelle Export 2026-07-10 21:26:41 +02:00
m.stangl 2abcd0964c Test für alle Elemente ist jetzt interativ. Man kann jeden Test in einem Reiter offen lassen und ansehen (csv Export aller Files ist dann manuell zu machen), oder auch automatisch schliessen, dafür ist aber der csv Export anschliessend auch mit automatisch. 2026-07-02 16:35:16 +02:00
m.stangl f87260c605 .cfg Parser hinzu implementieren lassen. Spezifische Omniflo export routine die syncron in Lisp lief entfernt 2026-07-02 14:06:05 +02:00
m.stangl 4863df7bac Sivas Export Format geändert 2026-06-29 17:08:37 +02:00
m.stangl 1f7aeb420d Ids werden jetzt in Bricscad von einer Lisp Funktion in Form einer aufsteigenden Nummer erzeugt 2026-06-23 10:11:47 +02:00
m.stangl 0b501e5ea5 Anwendung der Erzeugung einer Id für jedes Element 2026-06-16 17:14:19 +02:00
m.stangl 9f78ff7f0a Alle LISP-Module auf ssg-cfg-or umgestellt (hardcodierte Konstanten entfernt)
Alle bisher hart codierten Geometrie-, Farb- und Default-Werte in den
LISP-Modulen werden jetzt ueber ssg-cfg-or aus component_defaults.json
gelesen (mit Fallback auf den bisherigen Wert als Sicherheitsnetz).

Lisp/KreiselInsert.lsp:
  - Geometrie-Konstanten: *kreisel-durchmesser*, *kreisel-pin-abstand*,
    *kreisel-default-laenge*, *kreisel-default-hoehe*, *eckrad-default-hoehe*
  - Beschriftungs-Einstellungen: Texthöhe, Farbe, Abstand
  - Linienfarben (color_linie_1/2, color_pin) fuer Layer/CECOLOR
  - Toleranzen: toleranz_kollinear, toleranz_winkel

Lisp/OmniModulInsert.lsp:
  - Default-Werte fuer HOEHE und DREHUNG beim Einfuegen und Bearbeiten
  - Textgroessen (textHeight, textGap) fuer Vorschau-Dialog
  - Max-Laengen fuer AP60, AP110, APG110

Lisp/VarioFoerderer.lsp:
  - staustrecke-basis, FESTE_HORIZONTAL
  - bogen-winkel Liste (zweifach, in Bibliotheks-Extraktion und Berechnung)
  - gefaelle_winkel (3°) an allen Stellen im Anlagen-Aufbau
  - skalierung_basis fuer Block-Skalierung
  - separator_block_dx/dz, station_block_dx/dz fuer Blockeinfuegung

Lisp/Gefaellestrecke.lsp:
  - Default-Wert fuer deltaL, default_winkel
  - separator_breite fuer Laengenberechnung

Lisp/export.lsp:
  - default_hoehe fuer HOEHE-Attribut-Fallback in Bogen/Weiche/Gerade
  - default_gerade_laenge fuer Laenge-Fallback
  - mm_pro_meter (1000.0) fuer Umrechnung mm->m bei Laengenangaben

Lisp/ssg_dialog.lsp:
  - dialog_preview_bg_color (-18) fuer fill_image Hintergrundfarbe

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 11:26:22 +02:00
m.stangl 9fe08411df Update der Attribute Höhe und Drehung vor Aufruf der Exports durchgeführt 2026-06-11 12:08:40 +02:00
m.stangl 0e8d264b6a eigene Export Routine aus den Tests extrahiert 2026-06-11 12:03:23 +02:00