mubea:build-vario(-one) liest jetzt ein optionales "typ"-Feld ("standard"
Default, "etage") und dispatcht auf berechne-etage/etage-foerderanlage-
einfuegen bzw. vf-block-erstellen mit dem passenden Typ. Neuer Testfall
VF_Mubea_Etage_0061 bildet Objekt-ID 0061 aus Mubea_Quali.dxf nach
(deltaL=12790, deltaH=0, seite=links, Winkel=9, L_GF1=1602.4).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The TRO markers written by sps_skel (lib/tro_annotate.py) are blocks
TRO_SYM_<type> carrying ID and TYPE as attributes. This wires them into the
existing SSG_LIB mechanisms rather than adding new ones.
The double-click hook and the EATTEDIT override already exist: ***DOUBLECLICK
routes [INSERT] to SSG_BLOCKEDIT, and c:EATTEDIT is undefined and forwarded to
the same dispatcher. So all that was missing was a branch:
Blockname TRO_* -> c:TRO_EDIT (Lisp/Tro_Edit.lsp) -> dcl/tro_edit.dcl
Tro_Edit.lsp follows the conventions of the other edit commands: DCL path from
DXFM_DCL, ssg-start/ssg-end around the command, ssg-attrib-read and
ssg-attrib-set-on for the attributes, all user-visible text via ssg-text/
ssg-textf with keys in lang/de_DE.json and en_GB.json. Implied selection is read
before ssg-start, since ssg-start clears it - the same note Gefaellestrecke.lsp
carries.
TYPE is a picklist rather than free text so it cannot drift from the type
catalogue. The list comes from Lisp/tro_types.lsp, generated on the sps_skel side
by "tro_annotate.py --emit-lisp" into DXFM_LISP. If that file is absent the
dialog offers the block's current type and still works.
Loading is lazy: the module is not preloaded in the MNL. The menu macros and the
dispatcher pull it with (ssg-ensure "Tro_Edit") on first use, and the dispatcher
falls back to native EATTEDIT if the module cannot be found. ssg_load.lsp loads
it for the non-menu path.
Menu: SSG_LIB > TRO with "Marker bearbeiten" and "Bearbeiten (Auto)", plus an
entry in the POP501 edit context menu.
The dialog changes attributes only. The marker shape belongs to the block
definition of the type and FB_BLOCK is derived from it, so both follow on the next
tro_annotate.py run; the dialog states this and the command prints a reminder when
the type was changed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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>
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.
omni:make-gerade: itoa(fix(CDATE*1e6)) als Kollisions-Suffix sprengte den
32-Bit-INT-Bereich und liess den Lisp-Fehler mitten im BLOCK/INSERT-Kommando
laufen (BricsCAD blieb dann auf eine Eingabe wartend haengen) - trat bei der
Omniflo-Streckenzug-Testschleife auf, da ssg-timestamp nur Sekundenaufloesung
hat und mehrere Geraden pro Sekunde entstehen. Ersetzt durch einen laufenden
Zaehler.
linienzug_tests.json: die in 3e23003 neu eingefuehrte "ES-Element setzen?"-
Frage fehlte im Testskript und hat die restliche Eingabe-Queue um einen
Eintrag verschoben.
cs-assign prueft je Sensor nicht mehr linear alle ILS-Carrier, sondern
nur noch die Kandidaten der eigenen Grid-Zelle (Aufloesung sqrt(Anzahl
Carrier)). Aufwand sinkt von O(Sensoren x Carrier) auf ~O(Sensoren +
Carrier), Zuordnungslogik bleibt unveraendert.
0_BG* im Sivasnr-Rohwert ist kein echter Sivas-Code, sondern ein Blockname-
Platzhalter fuer mehrere reale TEF-Teile (z.B. 0_BG071090 = 0_B10071 +
0_B10090 + 0_B10090, siehe SivasnrTEF im Katalog). Bisher wurde der
Platzhalter selbst als Sivasnummer gezaehlt, wodurch u.a. 0_B10071 in der
Summierung fehlte.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Baut aus export.csv ein gerichtetes Graph-Modell der Anlage und schreibt
es als .json (vollstaendig), .dot (GraphViz) und .mmd (Mermaid).
Statt der CSV-Spalte "Nachbarn" (ungerichtet, Strecken werden dort
absichtlich nicht gegeneinander getestet, und ein langer Kreisel
ueberdeckt flaechig die halbe Anlage) arbeitet das Modul mit
Anschlusspunkten: eine Kante entsteht nur, wenn ein Elementende im
Grundriss auf der Flaeche eines anderen Elements liegt.
Richtung exakt aus K1/K2 (KS_EIN/KS_AUS), sobald der Export diese
Spalten fuellt; solange sie leer sind heuristisch aus Schwerkraft
(Gefaellestrecke) bzw. dem Merkmal Antriebfahrtrichtung (Foerderer).
Jede Kante traegt die verwendete Quelle in "richtung_quelle".
Warnt zudem, wenn Insertpoint-Werte an der 24-Bit-Fixed-Point-Grenze
von csv:kos-encode (+-8388.607 Einheiten) abgeschnitten sind.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
build_variofoerderer_merkmale las noch die alten Attributnamen ohne
_mm-Suffix (HOEHE_VON, HOEHE_BIS, DELTA_H, DELTA_L) sowie SEITE/WINKEL.
Umbenannt wurden diese in *strecke-attr-front* (ssg_core.lsp) zu
HOEHE_VON_mm/HOEHE_BIS_mm/DELTA_H_mm/DELTA_L_mm bzw. aufgeteilt in
SEITE_AS/SEITE_ES und GF_WINKEL/VF_WINKEL. Da attribs.get() still den
Default "" liefert, blieben die Felder in der Merkmale-Spalte leer statt
einen Fehler zu melden - betroffen waren alle VF_n- UND GF_n-Zeilen
(beide nutzen denselben Builder). export_sivas.py war bereits nachge-
zogen, export_csv.py nicht; aufgefallen ist es nicht, weil
tests/reference/export_raw.json noch die alten Namen enthaelt.
- Attributnamen korrigiert, Alt-Namen per att()-Helper als Fallback,
damit aeltere export_raw.json-Dateien und noch nicht neu aufgebaute
Bloecke weiter Werte liefern
- Seite_AS/Seite_ES ersetzen das immer leere Seite
- VF_Winkel neu neben Winkel (= GF_WINKEL)
Geprueft gegen results/export_raw.json (neue Namen) und
tests/reference/export_raw.json (Alt-Namen); Pflichtfelder aus
tests/test_foerderer.py bleiben vorhanden.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Die erste/letzte Zeile der .dbg-Datei ("=== DEBUG START/ENDE ...") hatte
schon einen Zeitstempel, fiel aber bei nil-Rueckgabe von menucmd (DIESEL
edtime, z.B. ohne aktiven Grafikbildschirm) auf den nichtssagenden
Platzhalter "(kein Zeitstempel)" zurueck. Neue Hilfsfunktion
dbg-timestamp faellt stattdessen auf die Systemvariable CDATE zurueck
und wird von dbgopen/dbgclose gemeinsam genutzt (vorher dupliziert).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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>
ssg-id-generate wird bereits ueberall sonst direkt beim Einfuegen
aufgerufen (KreiselInsert.lsp, Gefaellestrecke.lsp, vf_core.lsp,
vf_linienzug.lsp, OmniModulInsert.lsp, TEFInsert.lsp). Separator/Scanner
waren die einzige Ausnahme: weder ils-insert-sensor (Produktion) noch
mubea:build-separator-one (Testharness) riefen es auf - ihre ID kam
bisher ausschliesslich aus dem einmaligen ssg-id-check-all-Durchlauf vor
dem Export. Das war vermutlich die Ursache fuer die beobachtete doppelte
ID (Kreisel und Separator teilten sich "0003").
- Lisp/SSG_LIB_Commands.lsp (ils-insert-sensor) und tests/test_mubea.lsp
(mubea:build-separator-one) rufen jetzt ssg-id-generate direkt nach dem
INSERT auf.
- ssg_id.lsp: ssg-id-set-and-verify prueft nach jedem ssg-attrib-set-on
sofort zurueck und warnt laut, falls das Schreiben (z.B. mangels
ID-ATTDEF an der Instanz) stillschweigend fehlschlaegt. Ausfuehrliches
dbg-Logging (ssg-id-collect-blocks/-max/-generate/-check-all/-set-and-
verify) fuer die weitere Diagnose.
- ssg-id-check-all bleibt als Sicherheitsnetz fuer Faelle, die kein
Insert-Hook abfangen kann (Copy/Array/Spiegeln in BricsCAD, Drawing-
Merges).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- export_neighbors.py: kreisel_half_bboxes() teilt die Kreisel-BBox entlang
der Achse durch Antriebs-/Spannstation (AN8/SP8) in eine linke und eine
rechte Haelfte (je ca. 400mm breit, siehe [Kreisel] durchmesser_mm in
cfg/export.cfg, gespiegelt von component_defaults.json). compute_neighbor_ids
ersetzt jeden Kreisel-Eintrag in der Kollisionsgruppe durch dieses Paar
(TeileId-L/-R) statt einer einzelnen BBox - Nachbarn einer Gefaellestrecke/
eines Foerderers zeigen jetzt, welche Haelfte tatsaechlich beruehrt.
- compute_sensor_zuordnung(): ordnet jeden Separator/Scanner per BBox-
Ueberschneidung seiner Gefaellestrecke, seinem Foerderer oder einer
Kreiselhaelfte zu (Prioritaet in dieser Reihenfolge), ersetzt die
ZUORDNUNG-Attribut-Merkmale im CSV-Export bei Treffer.
- compute_scanner_nearest_separator(): sucht zusaetzlich, unabhaengig von der
Zuordnung, zu jedem Scanner den raeumlich naechstgelegenen Separator.
- ssg_id.lsp: ssg-id-collect-blocks erfasst jetzt auch Separator_SP/S-LP/
Scanner-Bloecke, damit ssg-id-check-all ihr (neues) ID-Attribut vor jedem
Export befuellt; export_csv.py bevorzugt dieses echte ID-Attribut als
TeileId und faellt nur bei leerem Attribut auf eine laufende SEP-/SCN-
Ersatznummer zurueck.
- data/ils/Scanner_2D.dwg, Scanner_3D.dwg, Separator_SP_2D.dwg: ID-ATTDEF
ergaenzt.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Neues Entwickler-Tool (bin/dbg2lsp.bat + lib/dbg2lsp.py), das das manuelle
Einfuegen von dbgf/dbg/dbgreturn/dbgopen/dbgclose automatisiert:
- --method NAME: dbgf + dbg je Parameter + dbgreturn um die letzte Rumpf-Form
- --recursive: verfolgt den Aufrufgraphen ueber Dateigrenzen hinweg (Builtins
werden automatisch uebersprungen, da sie kein defun im Suchpfad haben)
- --add-open DATEI METHODE: dbgopen/dbgclose fuer einen Einstiegspunkt
(z.B. ein c:BEFEHL-Kommando), inkl. aller (exit)-Stellen
Dokumentiert in doc/dbg2lsp.md, Kurzeintrag in CLAUDE.md.
Ausserdem: set_attributs.py aus doc/tools.md und CLAUDE.md entfernt - das
Skript existiert nicht mehr in lib/.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
mubea:build-separator-one nutzte (and blockname (ssg-ils-block-laden
blockname)) fuer eff - AutoLISPs AND liefert bei mehreren wahren
Ausdruecken T zurueck statt des letzten Werts (anders als in Common
Lisp/Scheme). Sobald ein Blockname (z.B. "Scanner") direkt gefunden
wurde, statt ueber den Separator_SP-Fallback zu laufen, wurde eff=T
an "_.INSERT" uebergeben. Fix: (if blockname (ssg-ils-block-laden
blockname)).
Ausserdem: Scanner-Testeintrag in mubea.json ergaenzt und
_vario_count/_separator_count in test_mubea.py, damit erwartete
Ergebniszahlen auch bei "anzahl">1 (Template->mehrere Kopien) stimmen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Vergleicht je Basisblock die KS_EIN/KS_AUS-Urspruenge der _2D- und _3D-Variante (via extract-ks-from-block) und listet dx/dy/dz. Ausgabe ks_pruefung.csv. Menuepunkt unter Tests ergaenzt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>