From 32bf5488384354591f7e8605aec4a0e0190203cb Mon Sep 17 00:00:00 2001 From: Samer Ayadi Date: Wed, 28 Oct 2026 13:52:52 +0100 Subject: [PATCH] JAM_EDIT: Feld Kapazitaet (Attribut CAPACITY) fuer DB_JamArea aus sps_skel Co-Authored-By: Claude Opus 5.5 --- CLAUDE.md | 2 +- Lisp/Jam_Edit.lsp | 51 ++++++++++++++++++++++++++++++++++++++++++----- Lisp/README.md | 2 +- dcl/jam_edit.dcl | 10 +++++++++- doc/kommandos.md | 2 +- lang/de_DE.json | 2 ++ lang/en_GB.json | 2 ++ 7 files changed, 62 insertions(+), 9 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 1b751f2..2b3c506 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -116,7 +116,7 @@ Detaillierte Dokumentation aller Funktionen und Befehle: siehe `Lisp/README.md`. | `SSG_LIB_Commands.lsp` | ILS_BTMT_Beladung, ILS_BTMT_Entladung, ILS_SCANNER_INSERT, ILS_SEPARATOR_INSERT, ILS_EINGANG_INSERT, ILS_AUSGANG_INSERT, SSG_BLOCKEDIT, SSG_DIM_SWITCH, SSG_SPRACHE | BTMT Be-/Entladung (`ils-insert-station`: wiederholtes Einfuegen von `BTMT-Beladung` bzw. `SC_Entladung`, Drehung interaktiv, Layer aus `LAYER`-Attribut, Dimension via `ssg-ils-block-laden`) + Sensoren (`ils-insert-sensor`) + Eingang-/Ausgang-Symbol (frei platzierbar wie BTMT Be-/Entladung, ueber `ils-insert-station` mit den Rohnamen `Eingang`/`Ausgang`, Bloecke `Eingang_.dwg`/`Ausgang_.dwg` in data/ils) + Doppelklick/Kontextmenue-Dispatcher + Konfiguration (2D/3D, Sprache) | | `Tro_Edit.lsp` | TRO_INSERT, TRO_EDIT | TRO-Marker (Block `TRO_SYM_`) fuer sps_skel (lib/tro_annotate.py): TRO_EDIT/TRO_INSERT teilen EINEN Dialog (`tro_edit.dcl`) fuer alle Typen: Kennung, Typ und eine Slot-Liste (Bauteil-TeileId je `separator`/`switch`/`scanner`/`drive`/`line`, Attribut `SLOTS`), die Slots kommen aus dem Typ (`*TRO-SLOTS*`), gleichnamige Slots bleiben beim Typwechsel; +/- fuer Lagerlinien; "Im Plan waehlen <" (done_dialog 2 -> getpoint -> naechstes Bauteil passender Art aus dem XRECORD `SPS_SKEL_PARTS`, Pruefung ueber `*TRO-SLOT-KINDS*`); Warnzeile fuer leere Separatoren/doppelte Bauteile, speichern geht trotzdem. TRO_INSERT setzt eine bestehende Blockdefinition ein (Enter = Mitte der Bauteile; bricht ab, wenn der Typ noch keine Blockdefinition in der Zeichnung hat - die entsteht nur ueber tro_annotate.py), `KEY` bleibt leer = neuer TRO. Zurueck nach sps_skel: DXF speichern, `tro_annotate --read-tros`. Typliste/Slots aus `tro_types.lsp` (von `tro_annotate.py --emit-lisp` nach DXFM_LISP geschrieben). Der Dispatcher SSG_BLOCKEDIT leitet Blocknamen `TRO_*` zu TRO_EDIT. | | `Connection_Edit.lsp` | CONNECTION_INSERT, CONNECTION_EDIT | Verbindung zwischen zwei TRO-Markern als Block `CONNECTION_ARROW` (Pfeilmitte); Beziehung ueber die INTERNEN Nummern der TRO-Marker (`FROM_UID`/`TO_UID` = Attribut `UID` des Markers, Namen `FROM_TRO`/`TO_TRO` = Attribut `ID`, `KIND` flow/weiche; aeltere Bloecke `FROM_ID`/`TO_ID` werden mitgelesen und mitgeschrieben), damit Umbenennen/Verschieben die Zuordnung nicht bricht. Zurueck nach sps_skel: `tro_annotate --read-tros` liest die Bloecke mit (hinzugefuegt/geloescht -> `[.edit_connections]` in `cfg/tro_overrides.ini`); loeschen = Block loeschen. Dialog `connection_edit.dcl`; SSG_BLOCKEDIT leitet `CONNECTION_*` hierher (vor dem TRO-Zweig) | -| `Jam_Edit.lsp` | JAM_EDIT | Staubereich `JAM_AREA` aus sps_skel (`tro_annotate.py --anlage`, Name `Jam_`) bearbeiten: Foerderer und laufende Nummer per Dialog `jam_edit.dcl`, Knopf zurueck auf den abgeleiteten Wert (`AUTO`), Warnung bei doppeltem Namen. `TRO`/`ENTRY` sind stabiler Schluessel und werden nicht geaendert. SSG_BLOCKEDIT leitet `JAM_*` hierher; in die SCL kommt die Aenderung ueber `tro_annotate --read-jams` | +| `Jam_Edit.lsp` | JAM_EDIT | Staubereich `JAM_AREA` aus sps_skel (`tro_annotate.py --anlage`, Name `Jam_`) bearbeiten: Foerderer, laufende Nummer und Kapazitaet (`CAPACITY`, fuer `DB_JamArea`; alte Bloecke ohne das Attribut: Feld gesperrt) per Dialog `jam_edit.dcl`, Knopf zurueck auf den abgeleiteten Wert (`AUTO`), Warnung bei doppeltem Namen. `TRO`/`ENTRY` sind stabiler Schluessel und werden nicht geaendert. SSG_BLOCKEDIT leitet `JAM_*` hierher; in die SCL kommt die Aenderung ueber `tro_annotate --read-jams` | | `TEFInsert.lsp` | TEF_FOERDERER_LINIE | Linie zwischen zwei Punkten zeichnen und mit 1000-mm-TEF-Geraden (`0_B10030`) belegen; Rest ueber ein zurueckversetztes Element, damit der Foerderer exakt am Linienende endet; geneigte Linien per Rz*Ry wie `ssg_ks_insert.lsp` | | `GeruestInsert.lsp` | GERUEST, GERUEST_SAEULEN, GERUEST_ROHRABHAENGER, GERUEST_WANDBEFESTIGUNG, GERUEST_TRAEGER, GERUEST_TRAEGER_BESCHRIFTEN, OMNI_FAHRSTRECKE, OMNI_FAHRSTRECKE_BESCHRIFTEN | Geruest-Baugruppen aus `data/json/geruest.json` konfigurieren und einfuegen. **Ein Dialog je Bereich**: Rohrabhaenger / Saeulen / Wandbefestigung oeffnen NUR ueber ihren eigenen Menuebefehl (`geruest-starten id`, Dialogtitel aus dem ASCII-Feld `titel`); eine Umschaltung im Dialog gibt es nicht (DCL hat kein Reiter-Tile), `GERUEST` ohne Bereich zeigt nur einen Hinweis. Der Dialogstand beginnt je Aufruf frisch. 1"- und 2"-Saeulen liegen in EINER Baugruppe `Saeulen` mit gemeinsamer Anbauteil-Liste; **`teileart` und `dummy` duerfen je Geometrie-Variante ueberschrieben werden** (`geruest-variante-wert`, Variante gewinnt vor Baugruppe; fuer `dummy` ueber `geruest-dummy-wahl`: fehlt die DWG der Variante, Meldung + Rueckfall auf den Baugruppen-Dummy; ist der Dummy zugleich eine Teile-DWG, wird er per `geruest-ohne-pfad` nicht doppelt eingefuegt) - so liefert `R 1"` weiterhin TEILEART `Geruest Saeule 1 Zoll` und die `R 2"`-Varianten `Geruest Saeule 2 Zoll`, die Groessen bleiben im Export also unterscheidbar. **Das Layout steht als Vorlage in `dcl/geruest.dcl`** (bzw. `dcl/geruest_traeger.dcl`); nur die datenabhaengigen Bloecke - ein `radio_button` je Variante (Key `v`, `geruest-radio-key`/`-index`), Mengenfeld + Ankreuzfeld je Anbauteil - werden zur Laufzeit an Markerzeilen `//@NAME@` eingesetzt (`geruest-dcl-ersetzungen` -> `ssg-dcl-vorlage-fuellen` in ssg_core, Temp-Datei, nach `unload_dialog` geloescht). Grund: DCL kann Tiles weder zur Laufzeit erzeugen noch ausblenden, Radiobutton-Labels lassen sich per `set_tile` nicht aendern, und eine `list_box` kann keine Eingabefelder enthalten. Varianten bewusst als Radiobuttons statt `list_box`: BricsCAD zeichnet die Listenspalte nur halb so breit, und ein `tabs`-Wert passt nur schrift-/skalierungsabhaengig. Inhalt: Basis-Variante aus `geometrie_varianten` (Radiobuttons, siehe oben), **Winkel Platte** (0/90 Grad, `*geruest-winkel-werte*`): Ausrichtung der Anbauteile zur Basis - die Teile-DWGs aus oben/unten/sonstiges werden um diesen Winkel um Z gedreht in den Block eingefuegt, Basis und Dummy bleiben ungedreht (`geruest-teile-dwgs-rot`; in Konfigurationen als echter Wert `winkel_platte`, kein Block-Attribut), Laenge (gegen `attribute.Laenge` min/max geprueft, Retry-Schleife), Farbe (`attribute.Teilefarbe`, Freitext bei `frei_option`) und **eine Befestigungsspalte** "Befestigung oben und unten" mit allen `anbaugruppen.befestigung` - die Anzahl ist die GESAMTanzahl je Teil (oben und unten zusammen; Tile-Keys `b`/`bm`, Zustand `*geruest-dlg-bef*`). Unter jedem Teil (auch in Sonstiges) zeigt eine Textzeile "Art.-Nr. ..." die Artikelnummer(n) (`geruest-artnr-anzeige`: Einzelteil -> `sivas_id`, Gruppe -> eindeutige Nummern der Teile; DCL kennt keine Schriftgroesse, darum normale Groesse in eigener Zeile). `anbaugruppen` ist ein Objekt mit zwei Listen: `befestigung` (Befestigungsspalte) und `sonstiges` (Teile, die weder oben noch unten sitzen, z.B. die Saeulen-Haltearme) - letztere bekommen eine eigene Zeile darunter (nur wenn nicht leer), in ARTINR/BEZEICHNUNG nach "unten" als "sonstiges" (`geruest-anbau-liste`; ein altes flaches Array gilt als `befestigung`). **Zwei Mengenfelder im JSON, bewusst verschieden benannt**: `stueckzahl` = wie oft ein Teil TATSAECHLICH geschrieben wird (je Variante bzw. je Satz/Anbauteil, fehlt = 1), `anzahl_vorgabe` = NUR die Vorbelegung des Anzahl-Feldes im Dialog (Anbaugruppen, fehlt = 1); ein Anbauteil wird Anzahl x `stueckzahl` mal geschrieben, bei einer Gruppe (`teile`) zaehlt die Anzahl die Saetze (`geruest-stueckzahl`/`geruest-anzahl-vorgabe`). In Konfigurationen (`befestigung`/`sonstiges`, dazu `winkel_platte`) heisst der gespeicherte Dialogwert `anzahl`. Aeltere Konfigurationen mit getrennten `oben`/`unten`-Listen laden weiter: deren Mengen werden zur Gesamtanzahl addiert (`geruest-konfig-befestigung`), Sonstiges-Teile darin still in die Sonstiges-Zeile umgehaengt (`geruest-konfig-sonstiges`); beim naechsten Speichern steht alles im neuen Format. Baugruppen ohne `attribute`-Block (Wandbefestigung) bekommen Laenge/Farbe gesperrt, Baugruppen ohne Anbauteile bekommen gar keine Spalten (ein leerer DCL-Cluster ist unzulaessig). Im generierten Label wird `"` zu `''` ersetzt (`geruest-dcl-label`) - fuenf Artikelnamen enthalten ein Anfuehrungszeichen, das das DCL-Label sonst vorzeitig beendet und die Datei zerstoert. **Konfigurationen**: gepflegte Bibliothek je Baugruppe unter `konfigurationen` in `geruest.json` (schreibgeschuetzt) plus eigene in `cfg/geruest_user.json` (gitignored, `geruest-user-schreiben`; getrennte Datei, damit Benutzerdaten und versionierte Bibliothek nicht kollidieren). Eigene Eintraege sind in der Liste mit `*` markiert und nur diese loeschbar. **Geaenderte Konfiguration**: beim Anwenden wird der Dialogstand als Vergleichsbasis gemerkt (`*geruest-dlg-konfig-basis*`); jede Eingabe vergleicht den aktuellen Record damit (`geruest-dlg-aenderung-pruefen`, Vergleich statt Flag - Zuruecknehmen hebt die Markierung wieder auf) und kennzeichnet den Listeneintrag mit "(geaendert)" plus Statuszeile `kstatus`. Speichern bietet bei einer gewaehlten EIGENEN Konfiguration deren Namen als Vorgabe an (Enter = ueberschreiben, `geruest-konfig-name-vorgabe`); Bibliotheks-Konfigurationen brauchen einen neuen Namen. Konfigurationen verweisen ueber den ANZEIGENAMEN auf Variante und Anbauteile; ein unbekannter Name wird gemeldet und uebersprungen, statt die Konfiguration scheitern zu lassen. Speichern/Loeschen laufen ueber `done_dialog 2`/`3` (Dialog schliessen, Aktion, neu zeigen) - `getstring` funktioniert aus einem `action_tile`-Rueckruf heraus nicht. Der Block wird - wie KREISEL_n/VF_n - SELBST zusammengebaut: Dummy-DWG aus `data/geruest` liefert nur Geometrie, das Attribut-Schema kommt aus `*geruest-attrib-defs*` (ID, ARTINR, LAENGE, BEZEICHNUNG, TEILEART, TEILEFARBE, LAYER) und wird per `ssg-attrib-merge` mit den Dummy-Tags zusammengefuehrt - sonst verschluckt `ssg-attrib-set-on` stillschweigend jeden Tag, den die Dummy-DWG nicht als ATTDEF kennt. **Teile-Geometrie**: jede ausgewaehlte Artikelnummer (Basis/oben/unten inkl. aufgeloester Gruppen), fuer die `data/geruest/.dwg` existiert, wird zusaetzlich einmal bei 0,0,0 mit in den Block eingefuegt (`geruest-teile-dwgs`, dedupliziert, fehlende DWGs still uebergangen) - reine visuelle Rueckmeldung, die Attribut-Logik bleibt davon unberuehrt. **TEILEFARBE** ist eine kommagetrennte Liste parallel zu ARTINR (z.B. `,,RAL7030,,RAL7030`): Teile mit `"farbig": true` in `geruest.json` (je Artikel; eine Gruppe vererbt es an ihre Teile, fehlend = false) bekommen die im Dialog gewaehlte Baugruppenfarbe, alle anderen einen leeren Eintrag. ARTINR und TEILEFARBE entstehen aus demselben Durchlauf (`geruest-teile-paare`/`-paare-n`, `geruest-farbliste`), sind also garantiert gleich lang. `export_sivas.py` schreibt daraus je Artikelnummer das Merkmal `{"108": ""}` in `details` (Nummer aus `cfg/export.cfg` `[Sivas] merkmal_teilefarbe`). Blockname `GR__` (Kollisionszaehler wie in OmniModulInsert). **Das `GR_`-Praefix ist nicht kosmetisch**: `SSG_BLOCKEDIT` haelt JEDEN Block mit TEILEART-Attribut fuer ein Omniflo-Element, deshalb steht in `SSG_LIB_Commands.lsp` ein `GR_*`-Zweig VOR dem Omniflo-Zweig. ARTINR listet jede Sivas-ID so oft, wie Anzahl x `stueckzahl` es vorgeben - erst Basis, dann Befestigung, dann Sonstiges; bei einer benannten Gruppe (`teile`) wird das ganze Set n-mal wiederholt, die Mengen INNERHALB des Sets bleiben dabei erhalten (`geruest-artikelnummern-n`). BEZEICHNUNG nennt Position und Menge je Teil ("Befestigung 4x ...", "sonstiges 1x ...") und verkettet mit `" + "`, NICHT mit Komma - die Artikelbezeichnungen enthalten selbst Kommas ("ROHR R 1\" 33,7 x 2,6"). Zuordnung Menue -> JSON laeuft ueber das ASCII-Feld `id`, weil die aeusseren JSON-Schluessel Umlaute bzw. Anfuehrungszeichen tragen. CSV-/Sivas-Export: `pattern_geruest = GR_*` (cfg/export.cfg), `csv:collect-export-blocks`/`ssg-id-collect-blocks` sammeln GR_-Bloecke wie BTMT eigenstaendig; `*geruest-attrib-defs*` traegt zusaetzlich ein leeres `ID`-ATTDEF (Voraussetzung fuer `ssg-id-check-all`, das nur bestehende ATTRIBs beschreiben kann). ARTINR/BEZEICHNUNG/TEILEART/LAENGE landen in export_csv.py/export_sivas.py in festen Spalten, TEILEFARBE/LAYER (+ ARTINR bei export_csv.py) im Merkmale-/details-JSON. **Attribut-Keys in `geruest.json` sind GROSS** (`LAENGE`, `TEILEFARBE`, ...) = die Block-Attribut-Tags; `ssg-json-get` unterscheidet Gross/Klein. **Rohr-Geruest-Traeger** (`GERUEST_TRAEGER`): Traeger-Baugruppen mit Linien-Logik liegen in einer EIGENEN Datei `data/json/geruest_traeger.json` (gleicher Aufbau wie geruest.json, eigener Lader/Cache `geruest-traeger-daten`, Suche `geruest-baugruppe id daten`; gemeinsamer Lader `geruest-json-laden-cache`) - sie tauchen darum nicht im Bereichs-Dropdown von GERUEST auf; dort kann spaeter auch der Gattertraeger hin. eigener Dialog aus der Vorlage `dcl/geruest_traeger.dcl` (Variante als Radiobuttons, JEDE Variante - auch die mit Muffe - mit eigenem Button, Beschriftung "Name (Artikelnummern)" ueber `geruest-varianten-label`; Varianten mit `"disabled": true` erscheinen in allen drei Geruest-Dialogen ausgegraut und nicht waehlbar (`geruest-variante-gesperrt-p`, `geruest-varianten-sperren` per `mode_tile`; Vorauswahl ueber `geruest-variante-waehlbar`/`-erste-freie-variante`; eine Konfiguration mit gesperrter Variante laesst die Auswahl unveraendert und meldet `gr-konfig-variante-gesperrt`) - bleiben aber in den Daten, damit Konfigurationen und Neubeschriften sie weiter ueber den Namen finden; eine Muffen-Checkbox gab es zwischenzeitlich, sie wurde wieder entfernt, weil die Artikelnummer der Muffen-Variante dann im Dialog nicht sichtbar war; Farbe, je eine Checkbox + Feld fuer `LAENGENABZUGANFANG`/`LAENGENABZUGENDE`, Vorgabe `vorgabe`/`aktiv` aus dem attribute-Block, je Variante ueberschreibbar via `geruest-attr-feld`); danach Einfuege-Schleife bis ESC/Enter: Startpunkt, dann Endpunkt ODER getippte Laenge (+ Richtung). Aktive Abzuege ruecken die Linie beidseitig ein (Strecke 1000, Abzug Anfang 20/Ende 35 -> Start 20 mm hinter dem Klick, Linie 945 mm); `LAENGE` = Netto-Laenge, gegen `LAENGE.min/max` geprueft. KEINE Dummy-DWG: die Geometrie ist eine per `entmake` erzeugte LINE (0,0,0)-(L,0,0) auf dem `layer` der Variante, eingefuegt mit dem Richtungswinkel (ANGBASE/ANGDIR/AUNITS dafuer kurz auf 0). **Querstreben + Muffe** als verschachtelte Dummy-DWGs im selben Block, reine Grafik ohne Export: `querstrebe.dummy` (`data/geruest/dummy_Strebe_30x4.dwg`, Basispunkt Strebenmitte, 30 mm laengs X) an jeder Strebenposition, NUR bei Varianten mit ausdruecklichem `"mit_querstrebe": true` (z.B. nicht beim `Rohr 1"`); fehlt die DWG, Rueckfall auf je eine 25-mm-Querlinie an Strebenanfang/-ende (`laenge`/`querlinie`, Standard 30/25 nur im Code). `muffe.dummy` (`dummy_Muffe_1zoll.dwg`, Basispunkt Muffenmitte) am Linienende, NUR bei Varianten mit ausdruecklichem `"mit_muffe": true` (nicht aus dem Namen geraten; bei "mit 2 Muffen" trotzdem nur eine am Ende); `querstrebe`/`muffe` per Variante ueberschreibbar (`geruest-variante-wert`). Dummys werden ohne Drehung eingefuegt (Traeger laeuft im Block entlang +X), ab dem zweiten Mal per Blockname (`geruest-dummy-einfuegen`). Verteilungs-Konfiguration `querstrebe` (`abstand`/`rand_min`/`rand_max`, Variante vor Baugruppe), Plan `geruest-traeger-streben-plan` -> (rand positionen): der Abstand zwischen zwei Streben ist IMMER genau `abstand`, beide Raender gleich (netto = k*abstand + 2*rand); gewaehlt wird die Strebenzahl, deren Rand am naechsten an `rand_min`..`rand_max` liegt (Gleichstand -> weniger Streben). Mit 500/100..250 geht das nur auf, wenn netto mod 500 = 0 oder in [200, 500) liegt (z.B. 1300 -> 150|500|500|150); sonst (1001..1199, unter 200 mm) liegt der Rand ausserhalb (1100 -> 300|500|300) - `geruest-traeger-rand-pruefen` zeigt dann eine Messagebox (ohne GUI: Konsole), der Traeger wird trotzdem eingefuegt. Schema `*geruest-traeger-attrib-defs*` = `*geruest-attrib-defs*` + die zwei Abzug-Tags; gemeinsamer Block-Schluss mit den anderen Bereichen in `geruest-block-abschliessen`. Reine Berechnung (`geruest-traeger-laenge`/`-start`/`-pruefen`, `geruest-mm-zahl`) in `tests/test_unit.lsp`. **Traeger-Beschriftung** (Checkbox im Dialog, Standard an; z.B. `RT 80/80 L=2650`): EIGENES TEXT-Objekt neben dem Block, abgeleitet NUR aus dem fertigen Block (Einfuegepunkt, DXF 50, Attribute `LAENGE` + `VARIANTE`) - darum nutzen Einfuegen und `GERUEST_TRAEGER_BESCHRIFTEN` dieselbe Funktion `geruest-traeger-beschriften`, und ein von Hand verschobener/gedrehter Traeger wird beim Neubeschriften korrekt erfasst. Verknuepfung Text -> Block per XDATA `SSG_GR_BESCHR` (1005 = Block-Handle): Neubeschriften ersetzt statt verdoppelt, der Sammelbefehl entfernt verwaiste Texte. JSON `beschriftung` (je FELD Variante vor Baugruppe, `geruest-obj-feld`): Inhalt `format` (`%1` Text, `%2` Laenge auf ganze mm) + `text` (fehlt -> Variantenname) und `layer` (je Variante verschieden, darum in JEDER Variante gepflegt - keine Baugruppen-Vorgabe; fehlt er doch, aktueller Layer); Formatierung NUR `stil`/`ausrichtung`/`hoehe` - alles andere regelt der Textstil ausserhalb, es wird kein Stil angelegt (fehlt er: Meldung, aktueller TEXTSTYLE). `ausrichtung` = Codes von TEXT "Ausrichten" (T/M/B + L/C/R), Bezugspunkt auf der Traegerlinie, L/R in LESErichtung. Textwinkel entlang des Traegers, DIN: fuer 90 < w <= 270 Grad um 180 gedreht (`geruest-text-winkel`). **Omniflo-Fahrstrecke** (`OMNI_FAHRSTRECKE`, Daten `data/json/omniflo_fahrstrecke.json`, Vorlage `dcl/fahrstrecke.dcl`): dieselbe Linien-Logik wie der Traeger, Code geteilt - `geruest-linien-starten id daten dcl-datei dlg-name` (Dialog `geruest-traeger-dialog` mit Vorlage + Dialogname als Argument, Einfuegen `geruest-traeger-einfuegen`), Beschriftung `geruest-traeger-beschriften blockEnt bg` mit der Baugruppe als Argument, Sammelbefehle je Typ ueber `geruest-linien-beschriften id daten` (Bloecke `GR__*`; verwaiste Texte werden typunabhaengig entfernt). Unterschiede stehen nur in den Daten: keine Querstreben (kein `mit_querstrebe`), Muffen-Dummy wie beim Traeger ueber den `muffe`-Block der Baugruppe (nur Varianten mit `"mit_muffe": true`), `farbig` nur bei ST/STL, Muffen-Varianten nur fuer ST/STL. Der Dialogstand bleibt je Baugruppe erhalten (`*geruest-tr-id*`; Wechsel Traeger <-> Fahrstrecke setzt ihn zurueck). Meldungstexte `gr-tr-*` nennen den Bauteilnamen aus `titel` als Platzhalter. In der Stueckliste eigene Klasse `fahrstrecke` (`GR_Fahrstrecke_*` vor dem allgemeinen `GR_*`). Noch NICHT enthalten: Edit-Pfad (GERUEST_EDIT) | | `KettenFoerderer.lsp` | KETTENFOERDERER, KF_EDIT, KF_KS_PRUEFEN | Kettenfoerderer/Schraegfoerderer Stahl: baut aus `KF_UM_` -> `KF_LAENGE` -> `KF_AN_` (je KS_AUS auf KS_EIN) plus der Draufsicht `KF_2D` EINEN Block `KF_`. Daten `data/json/kettenfoerderer.json`, Dialog `dcl/kettenfoerderer.dcl`. **Geometrie**: die Bausteine sind in der XY-Ebene gezeichnet (Hoehe = Y), werden aber AUFGERICHTET eingebaut `Rz(basis)*Rx(90)*Rz(eigen)` (`kf-matrix-aufrecht`) - die Hoehe laeuft in **Z**; dafuer `insert-block-ks-matrix` (freie 3x3-Rotation) in ssg_ks_insert.lsp. Die Neigung (26/30 Grad) ist KEIN Rechenparameter: sie steckt in den Varianten-Bloecken, der Einbauwinkel jedes Folgebausteins wird zur Laufzeit aus der RICHTUNG des KS_AUS seines Vorgaengers gemessen (`ks-xy-winkel`/`kf-hz-folge`) - keine gepflegte Winkeltabelle. `KF_LAENGE` wird in X skaliert, die Einbauhoehe H bestimmt seine Laenge ueber die Hoehenbilanz (`kf-laenge-berechnen`). `KF_2D` liegt DECKUNGSGLEICH mit der Kette (KS_EIN/KS_AUS auf denen von Umlenkung/Antrieb), ist flach gezeichnet, nur um die Steigung geneigt und auf die Schraeglaenge skaliert. **Attribut-Schema** `*kf-attrib-defs-liste*` ist EIGENSTAENDIG und bewusst NICHT von `ssg-strecke-attrib-defs` abgeleitet (sonst ~24 geerbte VF-Tags am Block); die Reihenfolge folgt dem Sivas-Merkmalstamm. FOERDERERTYP = Bauart im Klartext, WINKEL = nackte Zahl 26/30 (der Klartext mit Gradzeichen entsteht erst ueber `[kf_typ_anzeige]` in cfg/sivas.cfg, damit Attributwerte ASCII bleiben); kein TEILEART (Festwert `KF_TEILEART` im Export). Alle Auswahllisten stehen mit ihren Sivas-Optionstexten in der JSON. **Das `KF_`-Praefix ist wie `GR_` nicht kosmetisch**: `SSG_BLOCKEDIT` haelt JEDEN Block mit TEILEART-Attribut fuer ein Omniflo-Element, darum steht ein `KF_*`-Zweig VOR dem Omniflo-Zweig (Doppelklick -> KF_EDIT). **Sivas-Export** (`[kettenfoerderer]` in cfg/sivas.cfg, `build_kettenfoerderer_details` in export_sivas.py): baugleiche Foerderer werden zu EINER Zeile zusammengefasst (`kettenfoerderer_signature`), die Gruppengroesse traegt Merkmal 353 (entsteht erst aus der Gruppierung, daher Code); Farbe (354) und Antriebsmotor (355) sind ZWEI Merkmale, und jedes merkmalbildende Attribut steht auch in der Signatur, sonst verschmelzen unterschiedlich ausgefuehrte Foerderer. Reine Kerne in `tests/test_unit.lsp` (`tu-tests-kf`); das Modul wird in der MNL vorgeladen, Laufzeit-Messung ueber den dbg-Schalter `kf-zeit` | diff --git a/Lisp/Jam_Edit.lsp b/Lisp/Jam_Edit.lsp index e3f3e28..696069b 100644 --- a/Lisp/Jam_Edit.lsp +++ b/Lisp/Jam_Edit.lsp @@ -9,6 +9,12 @@ ;; (stabiler Schluessel, nicht aendern) ;; AREA unsichtbar - Kennung der TRO-JSON (J0039) ;; AUTO unsichtbar - von sps_skel abgeleitete Nummer NNNN_k +;; KEY unsichtbar - stabiler Schluessel fuer --read-jams +;; CAPACITY unsichtbar - Kapazitaet (Traegerplaetze), leer = offen; +;; wird nCapacityMax/nCapacitySet und der Wert +;; der Konstante cJam_ im DB_JamArea +;; +;; Alte Zeichnungen ohne CAPACITY: Feld gesperrt, Hinweis - neu beschriften. ;; ;; Aufruf JAM_EDIT: ;; - Doppelklick auf den Staubereich -> ***DOUBLECLICK [INSERT] -> SSG_BLOCKEDIT @@ -18,8 +24,11 @@ ;; "JAM_*" hierher. ;; ;; Der Dialog aendert nur die Zeichnung. In die SCL kommt die Aenderung mit -;; tro_annotate.bat --file --read-jams (-> cfg/_jam_names.ini) +;; tro_annotate.bat --file --read-jams (-> cfg/_jam_names.ini, +;; [jam] und [capacity]) ;; scl_skeleton.bat --json _anlage.json --templates +;; (-> _FB_Main.scl, _DB_JamArea.scl, +;; _JamArea_Konstanten.xlsx) ;; ;; Setzt ssg_core.lsp (ssg-start/ssg-end, ssg-attrib-*) und ssg_lang.lsp voraus. ;; ============================================================ @@ -33,6 +42,26 @@ ) +;; ------------------------------------------------------------ +;; Ein Attribut setzen, auch auf "" (ssg-attrib-set-on laesst leere +;; Werte aus - eine geloeschte Kapazitaet muss aber leer werden) +;; ------------------------------------------------------------ +(defun jam-attrib-setzen (ent tag wert / obj ed fertig) + (setq obj (entnext ent) fertig nil) + (while (and obj (not fertig)) + (setq ed (entget obj)) + (cond + ((= (cdr (assoc 0 ed)) "SEQEND") (setq fertig t)) + ((and (= (cdr (assoc 0 ed)) "ATTRIB") (= (strcase (cdr (assoc 2 ed))) tag)) + (entmod (subst (cons 1 wert) (assoc 1 ed) ed)) + (entupd obj) + (setq fertig t)) + ) + (setq obj (entnext obj)) + ) +) + + ;; ------------------------------------------------------------ ;; Name aus Foerderer und Nummer: "0054" "3" -> "Jam0054_3" ;; ------------------------------------------------------------ @@ -73,6 +102,7 @@ (defun c:JAM_EDIT ( / ss ent ed bname attribs alt-conv alt-nr auto tro entry area neu-conv neu-nr auto-conv auto-nr pos + alt-kap neu-kap hat-kap dcl-pfad dat ergebnis name andere) ;; Implied Selection VOR ssg-start pruefen (ssg-start hebt Selektion auf) @@ -112,7 +142,9 @@ auto (cond ((cdr (assoc "AUTO" attribs))) ("")) tro (cond ((cdr (assoc "TRO" attribs))) ("?")) entry (cond ((cdr (assoc "ENTRY" attribs))) ("?")) - area (cond ((cdr (assoc "AREA" attribs))) ("?"))) + area (cond ((cdr (assoc "AREA" attribs))) ("?")) + hat-kap (assoc "CAPACITY" attribs) + alt-kap (cond ((cdr hat-kap)) (""))) ;; AUTO "0054_3" -> Foerderer "0054", Nummer "3" (setq auto-conv "" auto-nr "") @@ -135,17 +167,21 @@ (set_tile "bereich" (ssg-textf "jam-edit-bereich" (list area tro entry))) (set_tile "auto" (ssg-textf "jam-edit-auto" (list (if (= auto "") "-" (jam-name auto-conv auto-nr))))) - (set_tile "hinweis" (ssg-text "jam-edit-hinweis")) + (set_tile "hinweis" (ssg-text (if hat-kap "jam-edit-hinweis" "jam-edit-ohne-kapazitaet"))) (set_tile "conveyor" alt-conv) (set_tile "number" alt-nr) + (set_tile "capacity" alt-kap) (if (= auto "") (mode_tile "reset" 1)) + ;; alte Zeichnung: Block ohne CAPACITY - nichts, wohin der Wert koennte + (if (not hat-kap) (mode_tile "capacity" 1)) - (setq neu-conv alt-conv neu-nr alt-nr) + (setq neu-conv alt-conv neu-nr alt-nr neu-kap alt-kap) (action_tile "reset" "(set_tile \"conveyor\" auto-conv) (set_tile \"number\" auto-nr)") (action_tile "accept" (strcat "(setq neu-conv (vl-string-trim \" \" (get_tile \"conveyor\"))" - " neu-nr (vl-string-trim \" \" (get_tile \"number\")))" + " neu-nr (vl-string-trim \" \" (get_tile \"number\"))" + " neu-kap (vl-string-trim \" \" (get_tile \"capacity\")))" "(done_dialog 1)")) (action_tile "cancel" "(done_dialog 0)") @@ -159,12 +195,17 @@ (alert (ssg-text "jam-edit-foerderer-ungueltig"))) ((not (and (jam-ziffern-p neu-nr) (> (atoi neu-nr) 0))) (alert (ssg-text "jam-edit-nummer-ungueltig"))) + ((not (or (= neu-kap "") (and (jam-ziffern-p neu-kap) (> (atoi neu-kap) 0)))) + (alert (ssg-text "jam-edit-kapazitaet-ungueltig"))) (t (setq neu-nr (itoa (atoi neu-nr)) name (jam-name neu-conv neu-nr)) (ssg-attrib-set-on ent (list (cons "CONVEYOR" neu-conv) (cons "NUMBER" neu-nr) (cons "NAME" name))) + (if hat-kap + (jam-attrib-setzen ent "CAPACITY" + (if (= neu-kap "") "" (itoa (atoi neu-kap))))) (entupd ent) (princ (ssg-textf "jam-edit-gespeichert" (list name area))) (if (setq andere (jam-name-belegt name ent)) diff --git a/Lisp/README.md b/Lisp/README.md index 55a4dee..f738bcf 100644 --- a/Lisp/README.md +++ b/Lisp/README.md @@ -903,7 +903,7 @@ Staubereiche zeichnet sps_skel (`tro_annotate.py --anlage`) als Block `JAM_AREA` | 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_*`) | +| `c:JAM_EDIT` | Foerderer, laufende Nummer und Kapazitaet (Attribut `CAPACITY`, leer = offen; wird `nCapacityMax`/`nCapacitySet` und Konstante `cJam_` im `DB_JamArea` aus sps_skel) per Dialog (`dcl/jam_edit.dcl`) aendern; Knopf zurueck auf den abgeleiteten Wert, Warnung bei doppeltem Namen. Auch per Doppelklick (`SSG_BLOCKEDIT`, `JAM_*`) | --- diff --git a/dcl/jam_edit.dcl b/dcl/jam_edit.dcl index 3c1ef47..471a935 100644 --- a/dcl/jam_edit.dcl +++ b/dcl/jam_edit.dcl @@ -1,6 +1,6 @@ // ============================================================ // jam_edit.dcl - Staubereich bearbeiten -// Aendert Foerderer und laufende Nummer eines JAM_AREA-Blocks, den die +// Aendert Foerderer, laufende Nummer und Kapazitaet eines JAM_AREA-Blocks, den die // Beschriftung aus sps_skel (lib/tro_annotate.py --anlage) eingefuegt hat. // Aufruf ueber c:JAM_EDIT (Lisp/Jam_Edit.lsp). // ============================================================ @@ -28,6 +28,14 @@ jam_edit : dialog { edit_width = 8; } + // Traegerplaetze: nCapacityMax/nCapacitySet und Konstante cJam_ + // im DB_JamArea (scl_skeleton); leer = noch offen + : edit_box { + key = "capacity"; + label = "Kapazitaet (Traeger):"; + edit_width = 8; + } + : row { : text { key = "auto"; diff --git a/doc/kommandos.md b/doc/kommandos.md index 8d0f1aa..e14bd80 100644 --- a/doc/kommandos.md +++ b/doc/kommandos.md @@ -132,7 +132,7 @@ Gross-/Kleinschreibung spielt an der Kommandozeile keine Rolle. | `TRO_EDIT` | Kennung, Typ und Bauteile je Slot (Separatoren, Weichen, Scanner, Lagerlinien) eines TRO-Markers per Dialog aendern; Bauteile im Plan waehlbar | | `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 | +| `JAM_EDIT` (`Jam_Edit.lsp`) | Staubereich (`JAM_AREA` aus sps_skel) bearbeiten: Foerderer, laufende Nummer und Kapazitaet (fuer `DB_JamArea`); auch per Doppelklick | ### Export und IDs (`export.lsp`, `ssg_id.lsp`, `count_sep_scan.lsp`, `check_hoehen.lsp`) diff --git a/lang/de_DE.json b/lang/de_DE.json index af331b7..6a4cc68 100644 --- a/lang/de_DE.json +++ b/lang/de_DE.json @@ -968,6 +968,8 @@ "jam-edit-nummer-ungueltig": "Die laufende Nummer muss eine ganze Zahl ab 1 sein - nichts geaendert.", "jam-edit-gespeichert": "\nStaubereich gespeichert: %1 (%2)", "jam-edit-doppelt": "\nACHTUNG: %1 gibt es schon in dieser Zeichnung (%2).", + "jam-edit-kapazitaet-ungueltig": "Die Kapazitaet muss leer oder eine ganze Zahl ab 1 sein - nichts geaendert.", + "jam-edit-ohne-kapazitaet": "Zeichnung ohne Feld CAPACITY - mit tro_annotate --anlage neu beschriften.", "vfl-abbruch-gesichert": "\n>>> Linienzug abgebrochen: %1 Objekt(e) als Block gesichert (per Doppelklick editierbar/fortsetzbar).", "vfl-zurueck-glied-verworfen": "\n>>> Zurueck: letztes Kettenglied wird verworfen - bitte neu beantworten.", "vfl-abbruch-nichts-gebaut": "\n>>> Abgebrochen - es wurde noch keine Geometrie erzeugt.", diff --git a/lang/en_GB.json b/lang/en_GB.json index a02ce84..9f60278 100644 --- a/lang/en_GB.json +++ b/lang/en_GB.json @@ -968,6 +968,8 @@ "jam-edit-nummer-ungueltig": "The running number must be a whole number from 1 - nothing changed.", "jam-edit-gespeichert": "\nJam area saved: %1 (%2)", "jam-edit-doppelt": "\nWARNING: %1 already exists in this drawing (%2).", + "jam-edit-kapazitaet-ungueltig": "The capacity must be empty or a whole number from 1 - nothing changed.", + "jam-edit-ohne-kapazitaet": "Drawing has no CAPACITY field - annotate again with tro_annotate --anlage.", "vfl-abbruch-gesichert": "\n>>> Chain cancelled: %1 object(s) saved as a block (editable/resumable via double-click).", "vfl-zurueck-glied-verworfen": "\n>>> Back: discarding the last chain element - please answer it again.", "vfl-abbruch-nichts-gebaut": "\n>>> Cancelled - no geometry was created yet.",