[FEAT] Weitere Objekte der Anlage in hundm05.json bauen (Kreisel)

tests/testdata/hundm05.json enthaelt jetzt neben den 5 Spec-Ketten auch
andere Objekte der Anlage - erkennbar am Feld "function", im Format der
jeweiligen Einzel-Testdaten (ein Kreisel also wie in kreisel_tests.json).
Damit beschreibt EINE Datei die ganze Anlage.

- tests/test_hundm05.lsp: hundm05:bau-zusatzobjekte sammelt alle Objekte mit
  "function" und baut sie; hundm05:bau-kreisel ruft kreisel-insert-script
  (wie tests/test_kreisel.lsp) und liefert einen Ergebnis-Record in derselben
  Form wie die Ketten. Eigener ssg-start-Rahmen mit ATTREQ/ATTDIA 0, weil
  vsp-bau-datei seinen schon geschlossen hat und (command "_.INSERT" ...)
  sonst nach Attributwerten fragt. Je Objekt gefangen, damit ein Fehler die
  restlichen nicht mitnimmt.
- Lisp/vf_spec.lsp: "kind" ist jetzt ein Record-Feld (Default "linienzug")
  statt eines Literals in vsp-result-json - so schreibt vsp-results-schreiben
  beide Objektarten in EINE Ergebnisdatei.
- lib/vf_spec_export.py: Objekte der Ziel-Datei, die keine Kette beschreiben,
  werden beim Neuschreiben unveraendert ans Dateiende uebernommen. Ohne das
  waere jeder von Hand ergaenzte Eintrag beim naechsten Generatorlauf weg -
  die Datei ist erzeugt UND handgepflegt. spec_aus_flachen_objekten
  ueberspringt sie jetzt statt zu werfen, genau wie vsp-gruppieren in LISP.
- tests/test_hundm05.py: die Ketten-Tests filtern auf kind "linienzug"
  (Records ohne das Feld stammen aus aelteren Laeufen und waren nur Ketten);
  neue Klasse TestZusatzobjekte prueft Status, expect_block_prefix,
  expect_hoehe (Attribut HOEHE), expect_kreiselart (KREISELART) und den
  Einfuegepunkt - dieselben Erwartungsfelder wie tests/test_kreisel.py.
- tests/test_vf_spec.py: neuer Test, dass die Zusatzobjekte die
  Ketten-Zerlegung nicht beeinflussen - auch nicht, wenn sie mitten zwischen
  den Sektionen stehen (der eingetragene Kreisel stand zunaechst inmitten
  der Sub-Knoten von Kette 5; nach dem Regenerieren steht er am Dateiende).

Verifiziert: 118 pytest-Tests gruen, Spec-Regenerierung uebernimmt das
Zusatzobjekt (58 Objekte), beide .lsp lint-sauber. Die Kreisel-Tests warten
auf den naechsten TEST_HUNDM05-Lauf.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-03 14:49:46 +02:00
parent e91f1d00d0
commit 2dd5382060
8 changed files with 296 additions and 12 deletions
+1 -1
View File
@@ -168,7 +168,7 @@ Abhaengigkeiten: `ezdxf`, Standard-Library. Benoetigen Umgebungsvariablen (`DXFM
| `split_block_library.py` | Teilt `ils_library.dxf` in einzelne DXF-Dateien pro Block auf (mit Abhaengigkeiten). Export-Prefixe: Vario_, Staustrecke_, _3D_AS_, _3D_ES_ |
| `vf_journal_export.py` | Liest die Eingabe-Journale der `VF_n`-Bloecke (XDATA-App `SSG_VF_EDIT`, Marker `"linienzug"`) aus einer Zeichnung und schreibt sie als Frage-Antwort-Protokoll im Schema von `tests/testdata/linienzug_tests.json` (Gegenstueck zu `vfl-entry->string`; kein ezdxf, reine Gruppencode-Lesung). Optional `--csv <sivas_export.csv>` fuer Strecken-ID und Erwartungswerte je Kette. Aufruf: `python vf_journal_export.py <dxf> <output.json> [--csv ...] [--kein-startpunkt-fix]` — erzeugt `tests/testdata/hm_recformat.json` aus `data/polylines.dxf` (die Aufzeichnung, aus der `tests/testdata/hundm05.json` als Spec abgeleitet wird) |
| `dxf_vf_abbild.py` | Abbild der `VF_`/`GF_`-Wrapperbloecke einer Testzeichnung: Attribute UND Bausteinzusammensetzung je Kette, Ketten ueber den Einfuegepunkt der Spec zugeordnet (der Blockname taugt nicht - die VF-Nummer beginnt in jeder Zeichnung neu bei 1). Regressionsnetz fuer Umbauten am Bau-Ablauf: `--referenz` vergleicht gegen `tests/reference/hundm05_attribute.json` (Exit 1 bei Abweichung), `--schreibe-referenz` frischt sie nach einem GEPRUEFTEN Lauf auf. Faengt genau das, was der Ergebnis-Record nicht sieht - eine vertauschte `vfl-acc-*`-Reihenfolge (Komma-Listen `L_VF_m`/`L_GF_m`/`GF_WINKEL`, in der Zeichnung unsichtbar, im Sivas-Export falsch) und eine falsche Blockvariante. Liest ASCII-DXF streamend; binaere DXF kann `dxf_scan_components.py`. Genutzt von `tests/test_vf_geometrie.py` |
| `vf_spec_export.py` | Uebersetzt ein Eingabe-Journal in eine **Spec** und zurueck (`spec_aus_journal` / `journal_aus_spec`) - Gegenstueck zu `vsp-journal` in `Lisp/vf_spec.lsp`, beide muessen dieselbe Tokenfolge liefern. Der Rundlauf `journal_aus_spec(spec_aus_journal(tok)) == tok` laeuft in `tests/test_vf_spec.py` gegen die 5 echten HundM-Ketten und beweist, dass die Spec das Journal verlustfrei abbildet. Schreibt das flache Spec-JSON (vom LISP-Parser lesbar). Aufruf: `python vf_spec_export.py <protokoll.json> <spec.json>` — erzeugt `tests/testdata/hundm05.json` (Spec, Eingabe fuer `TEST_HUNDM05`/`VF_SPEC_BAU`) aus `tests/testdata/hm_recformat.json` (Aufzeichnung) |
| `vf_spec_export.py` | Uebersetzt ein Eingabe-Journal in eine **Spec** und zurueck (`spec_aus_journal` / `journal_aus_spec`) - Gegenstueck zu `vsp-journal` in `Lisp/vf_spec.lsp`, beide muessen dieselbe Tokenfolge liefern. Der Rundlauf `journal_aus_spec(spec_aus_journal(tok)) == tok` laeuft in `tests/test_vf_spec.py` gegen die 5 echten HundM-Ketten und beweist, dass die Spec das Journal verlustfrei abbildet. Schreibt das flache Spec-JSON (vom LISP-Parser lesbar). Objekte der Ziel-Datei, die keine Kette beschreiben (von Hand ergaenzte Anlagenteile mit `function`, z.B. Kreisel), werden beim Neuschreiben unveraendert ans Dateiende uebernommen - sonst waeren sie beim naechsten Lauf weg. Aufruf: `python vf_spec_export.py <protokoll.json> <spec.json>` — erzeugt `tests/testdata/hundm05.json` (Spec, Eingabe fuer `TEST_HUNDM05`/`VF_SPEC_BAU`) aus `tests/testdata/hm_recformat.json` (Aufzeichnung) |
| `dxf_scan_components.py` | Erkennt ILS-/Omniflo-Komponenten in einer **fremden** Projektzeichnung (ohne unsere Wrapper-Bloecke) und schreibt sie im JSON-Schema aus `tests/testdata/object_data.md` — Grundlage fuer Nachbau-Testfaelle wie `tests/testdata/mubea.json`. Liest binaere DXF im GB-Bereich streamend per mmap (ezdxf-DOM waere zu gross), loest INSERTs inkl. OCS/Extrusionsrichtung rekursiv in Weltkoordinaten auf, paart AN8/SP8 zu Kreiseln und Antrieb/Umlenkung zu Foerderern. Aufruf: `python dxf_scan_components.py <dxf> <data_dir> <output.json> [--fenster X0 Y0 X1 Y1]` — ohne `--fenster` liefert eine Anlagenzeichnung leicht ueber 1300 Eintraege, zuviel fuer einen Testlauf |
### Entwickler-Tools (`lib/`) - kein ezdxf, reine Text-/AutoLISP-Verarbeitung