diff --git a/CLAUDE.md b/CLAUDE.md index 46393f6..859235c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -25,6 +25,7 @@ AutoLISP-Makros (SSG_LIB) fuer BricsCAD Pro zur automatisierten Erstellung von F | `data/ils/` | DWG-Bloecke fuer ILS-Kreisel/Eckrad (AN8, SP8, AP-Typen) | | `data/json/` | Komponentendaten (Masse, Sivas-IDs); Geruest: `geruest.json` (GERUEST-Dialog) und `geruest_traeger.json` (Traeger mit Linien-Logik) | | `data/block_libraries/` | DXF Block-Libraries (ils_library.dxf) | +| `cfg/rahmen/` | DIN-Rahmen + Schriftkopf-DWGs (A0-A4, Kopf11 DE/EN/FR/IT), kopiert aus `\\infor-ln\SSG_Tools\ACADSST\KOEPFE`, fuer `DIN_FORMATE` (DinFormate.lsp) | | `dcl/` | DCL-Dialogdefinitionen | | `doc/` | Dokumentation, Entwicklungsplan | | `lib/` | Python-Skripte (DXF-Bearbeitung, Export) | @@ -78,7 +79,7 @@ Die `start_briscad.bat` ruft `setenv.bat` auf und startet BricsCAD. | Geruest | `GeruestInsert` | GERUEST_SAEULEN, GERUEST_ROHRABHAENGER, GERUEST_WANDBEFESTIGUNG (derselbe Dialog, im jeweiligen Bereich geoeffnet), GERUEST_TRAEGER (eigener Dialog), GERUEST_TRAEGER_BESCHRIFTEN (Untermenue Geruest -> Funktionen -> Traeger beschriften; alle Traeger der Zeichnung neu beschriften); Gattertraeger noch Platzhalter auf GERUEST | | Connections | `Connection_Edit` + `SSG_LIB_Commands` | CONNECTION_INSERT, CONNECTION_EDIT, ILS_EINGANG_INSERT, ILS_AUSGANG_INSERT | | Export | `export` | EXPORTSIVAS, EXPORTCSV, CALLPYTHON | -| Werkzeuge | `ssg_blocktools`, `ssg_texttools` | SSG_BLOCK_COUNT, SSG_BLOCK_DELETE, SSG_ATTR_ERSETZEN, SSG_TEXT_ERSETZEN, SSG_TEXT_PARALLEL, SSG_TEXT_HOEHE, SSG_TEXT_STIL | +| Werkzeuge | `ssg_blocktools`, `ssg_texttools`, `ssg_stueckliste`, `DinFormate` | SSG_BLOCK_COUNT, SSG_BLOCK_DELETE, SSG_ATTR_ERSETZEN, SSG_TEXT_ERSETZEN, SSG_TEXT_PARALLEL, SSG_TEXT_HOEHE, SSG_TEXT_STIL, SSG_FAEHNCHEN_STUECKLISTE, DIN_FORMATE | | Konfiguration | `SSG_LIB_Commands` + `DrawPlanquadrate` | SSG_DIM_SWITCH, SSG_SPRACHE, PLANQUADRATE_TOGGLE (DRAW_PLANQUADRATE/DELETE_PLANQUADRATE) | | Doppelklick/Kontextmenue | `SSG_LIB_Commands` | SSG_BLOCKEDIT (dispatcht Kreisel->KreiselEdit, Omniflo->OMNI_EDIT, GF_*->GEFAELLESTRECKE_EDIT, VF_*->VARIOFOERDERER_EDIT) | @@ -103,6 +104,7 @@ Detaillierte Dokumentation aller Funktionen und Befehle: siehe `Lisp/README.md`. | `ssg_input.lsp` | - | Generische Eingabe-Wrapper `ssg-in-real/-int/-string/-point/-dist/-keyword/-yesno` (Vorgabe in `<..>`, Enter = Vorgabe, optionaler Hook `*ssg-in-hook*` fuer Journale). Steht NEBEN den VF-spezifischen `vfl-in-*` (diese bleiben unveraendert). `ssg-in-yesno` liefert T bei Ja (anders als `ssg-ques`, das T fuer die nicht vorgegebene Antwort liefert); Schluesselwoerter aus `ssg-text "in-yesno-keys"` | | `ssg_blocktools.lsp` | SSG_BLOCK_COUNT, SSG_BLOCK_DELETE, SSG_ATTR_ERSETZEN | Block-Werkzeuge fuer das aktuelle Layout (Ursprung ACADSST `TOOLS.LSP`/`ssg.lsp`): Einfuegungen zaehlen (Pick, wcmatch-Muster oder Statistik aller Bloecke), alle Einfuegungen loeschen (Rueckfrage, gesperrte Layer bleiben), Attributwerte zeichnungsweit/in Auswahl suchen+ersetzen (Vorschau mit Anzahl, Teilstring oder Gesamtwert). Wirksamer Blockname (dynamische Bloecke). Reine Kerne `ssg-bt-name-passt-p`, `ssg-bt-zaehle-namen`, `ssg-bt-wert-neu` in `tests/test_unit.lsp` getestet | | `ssg_texttools.lsp` | SSG_TEXT_ERSETZEN, SSG_TEXT_PARALLEL, SSG_TEXT_HOEHE, SSG_TEXT_STIL | Text-Werkzeuge (Ursprung ACADSST `CHGTEXT`/`PARTEXT`/`ALTHOEHE`/`ALTSTIL`): Suchen/Ersetzen in TEXT, MTEXT und Block-Attributen (nutzt `ssg-bt-*`, daher NACH `ssg_blocktools` laden), Text parallel zu Linie/Polylinie/Bogen (lesbar ausgerichtet, Abstand), Hoehe/Stil aendern. Arbeitet in der XY-Ebene des Welt-KS. Reine Kerne `ssg-tt-lesbarer-winkel`, `ssg-tt-versetzt` getestet | +| `ssg_stueckliste.lsp` | SSG_FAEHNCHEN_STUECKLISTE | Positions-Faehnchen + Stuecklistentabelle, komplett AUS DER ZEICHNUNG - es wird keine Datei eingelesen. Der Benutzer waehlt die Elemente aus (`ssg-sl-erkannte-elemente`: `ssget`-Auswahl, Enter ohne Auswahl = alle erkannten im aktuellen Layout; der reine Filter `ssg-sl-elemente-aus-ss` laesst nicht erkannte Objekte still wegfallen, man darf also grosszuegig ein Fenster aufziehen). `ssg-sl-klasse` klassifiziert Blocknamen (`KREISEL_*`/`ECKRAD_*` -> "ILS Kreisel/Eckrad", `VF_*`/`GF_*` -> "ILS Streckengruppe", `GR_*` -> "Rohrgeruest", `AP60*`/`AP110*`/`AP_110*`/`APG110*` -> je eigene Omniflo-Geraden-Gruppe; wirksamer Blockname ueber `ssg-bt-effname`, also auch dynamische Bloecke). Jedes einzelne Element bekommt ein Faehnchen (`ssg-sl-faehnchen`, Rechteck/Kreis/Automation-Rahmen + Text) an der unteren linken Ecke seiner Bounding-Box (aus `csv:get-bbox` - liefert Zentrum+Abmessungen, NICHT Eckpunkte, die Ecke wird im Code daraus berechnet); die Tabelle (`ssg-sl-tabelle-zeichnen`) gruppiert GROB je Elementklasse (keine Sivas-Artikelaufloesung wie `export_sivas.py`) zu einer Zeile mit Anzahl + Laengensumme aus dem `LAENGE`-Attribut (`ssg-sl-gruppieren`/reiner Kern `ssg-sl-gruppieren-werte`), mehrere gleichartige Elemente tragen daher dieselbe Positionsnummer. **Bewusst KEIN Datei-Import wie bei Walz/Bihler**: dort vergab ein externes System die Positionsnummern und lieferte sie als Datei zurueck, die das CAD nur abzeichnete - bei Walz (`MENU/POSITION.LSP`) eine `.pos`/`.zei` aus einem Clipper-Warenwirtschaftssystem mit Koordinaten-Zuordnung, bei Bihler ITB (`Walz_und_Bihler/SBCADBib/ITB-Module_ori.lsp`, `c:bea_pos`) eine `.pos` mit Zuordnung ueber den Entity-Handle. Diese Umwege sind hier nicht nachgebaut (Entscheidung 2026-10): Nummern und Mengen entstehen in dieser Funktion, die Stuecklisten-AUSGABE liefern EXPORTSIVAS/EXPORTCSV aus denselben Block-Attributen. Der alte `c:stueckl` (Laengen-Summierung ueber hartcodierte Walz-Profillayer wie `L-2`=ST, `A-7`=AP110) hat ebenfalls kein Aequivalent im dxfmakros-Datenmodell (Block-Attribute statt Linien-Layer). Braucht `csv:get-bbox`/`csv:get-attrib` aus `export.lsp` und `ssg-bt-effname` aus `ssg_blocktools.lsp` - muss daher NACH beiden geladen werden (siehe `ssg-ensure`-Reihenfolge in `SSG_LIB.mnl`/`ssg_load.lsp`). Reine Kerne `ssg-sl-klasse`, `ssg-sl-gruppieren-werte` in `tests/test_unit.lsp` getestet | | `KreiselInsert.lsp` | KreiselInsert, KreiselConnect, KreiselRedraw, KreiselQuick, KreiselEdit, KreiselParams, KreiselLabelSetup, KreiselLabelPos, KreiselLabelHoehe, ILS_Eckrad | ILS Kreisel und Eckrad komplett in AutoLISP | | `VarioFoerderer.lsp` (Wrapper fuer `vf_core.lsp`/`vf_standard.lsp`/`vf_etage.lsp`/`vf_linienzug.lsp`) | FOERDERANLAGE, VARIOFOERDERER_EDIT, VARIOFOERDERER_NACHRUESTEN, Vario_Kette_Merge, VF_SEKTION_RESTORE, VF_WIZARD_AN, VF_WIZARD_AUS | Vario-Foerderanlagen Generator (Typen Standard/Etage/Linienzug); Standard- UND Etage-Typ: Werteingabe per DCL-Dialog, inkl. der vorgelagerten Eingabemodus-Wahl 3D-Linie/Werte manuell (`vfc_eingabemodus`, `vfc-dialog-eingabemodus-waehlen`) - beide Modi laufen seitdem in denselben Basis-/Winkel-Dialog, der Konsolen-Pfad ist nur noch Rueckfall bei abgeschalteter GUI/anderer Sprache. Der Dialog-Ablauf ist zentral in vf_core (`vf-dialog-ablauf`/`vf-dialog-berechnen-einfuegen`, parametrisiert ueber Typ-Registry `*vf-typ-registry*` + Flag `horizontal-p`); `vfs-standard-dialog-ablauf`/`vfe-etage-dialog-ablauf` sind nur noch duenne Wrapper darauf. Beide nutzen dieselben Dialoge `vfs-dialog-eingabe-basis`/`vfs-dialog-winkel-verteilung` und den gemeinsamen L_GF/L_VF-Solve `vf-winkel-solve` (vf_core; berechne-alle-winkel/berechne-winkel-etage teilen ihn); Doppelklick auf VF_n-Block ruft VARIOFOERDERER_EDIT, das per SSG_VF_EDIT-XDATA-Marker ("standard"/"etage"/"linienzug") in den passenden Neuaufbau-Zweig dispatcht (`vfe-edit-ent` fuer Etage, `vfl-edit-ent` fuer Linienzug); Altbestand-Bloecke ohne Marker werden abgewiesen. Linienzug (Modus 1, `vf-linienzug-modus`) zeichnet jede interaktive Eingabe in einem Journal auf (`vfl-in-point`/`-string`/`-real`/`-int`) und schreibt es als XDATA auf den fertigen `VF_n`-Block; ein Abbruch (ESC) loescht dadurch nichts mehr, sondern wickelt die bis dahin gebaute Teil-Geometrie ebenso zu einem Block (`vfl-modus-abbruch-sichern`) - sie bleibt stehen und ist sofort per Doppelklick weiter editierbar/fortsetzbar. Der komplette Linienzug-Hauptstrang (Menue-Fragen von AS-Element bis Kettenende, inkl. GF-Bogen/Vario-Kurve/VF-Einheit-Fortsetzung) laeuft per Default ueber DCL-Dialoge statt Konsole (`*vfl-wizard-mode*`, Befehle VF_WIZARD_AN/VF_WIZARD_AUS): `vfl-in-string`/`-int`/`-real` zeigen bei aktivem Wizard-Modus generische Dialoge aus `dcl/vf_linienzug_wizard.dcl` (Zahl-Eingabe bzw. Mehrfachauswahl aus `vfl-menu`/`vfl-menu-int`) statt `getstring`/`getint`/`getreal` aufzurufen; die ORIGINALEN Konsolen-Fragen (princ + get*, de/en ueber ssg-text) bleiben unveraendert im Code (Fallback bei Fehlern via `vl-catch-all-apply`, siehe `doc/variofoerderer.md`). `vfl-edit-ent` liest das Journal, zeigt die Sektionen ueber einen DCL-Dialog (`vfl-dlg-position`, `dcl/vfl_edit.dcl`) an, kuerzt bei Bedarf auf eine gewaehlte Sektion (stummer Replay der behaltenen Eingaben, umgeht den Wizard-Zweig komplett) und baut danach interaktiv weiter. Linienzug Modus 2 (Pfad+Zielhoehe-Solver, `vf-linienzug-modus2`) nutzt dieselben Wrapper PLUS die neue Objektauswahl-Wrapper-Funktion `vfl-in-selection` (Pfad-Objekte als stabile Entity-Handles journalisiert, neue Journal-Art `"OBJS"`) und schreibt sein Journal unter dem eigenen XDATA-Marker `"linienzug2"`; Doppelklick baut hier NICHT abschnittsweise, sondern per vollem Reset 1:1 aus dem Journal neu auf (`vfl-edit-ent2`, dispatcht aus `vfl-edit-ent` per Marker) - Modus 3 (Vorwaerts-Nachbau) bleibt bewusst reine Konsole (im Code selbst als Legacy/"wird umgebaut" markiert). `Vario_Kette_Merge` (in vf_linienzug.lsp) fuehrt mehrere einzeln gebaute VF_n-Bloecke ab einem gewaehlten Start-Baustein ueber die reale KS_AUS->KS_EIN-Nachbarschaft zu einem Gesamt-Block zusammen (aggregierte Attribute, Luecken-Erkennung). Die interaktiven Editier-Pfade (`vfl-edit-ent` Sektions-Zweig, `vfl-edit-ent2`) rufen den Neuaufbau BEWUSST direkt auf, NICHT ueber `vl-catch-all-apply`: der alte Block ist beim Neuaufbau schon per `entdel` weg, und ein Catch faengt den Abbruch VOR `*error*` ab - der Abbruch-Wickler `vfl-modus-abbruch-sichern` kaeme nie zum Zug und die ganze Kette bliebe als lose Einzelteile ohne Block liegen (Fehlerbild "VF-Block aufgebrochen"). Nur der nicht-interaktive Batch-Konverter `vfl-konvertiere-ent` behaelt den Catch (die Batch-Schleife muss weiterlaufen) und meldet den betroffenen Block. Die Abbruch-Handler setzen zusaetzlich `*ssg-ils-dim*` zurueck, weil der Aufrufer, der das sonst tut, nach einem Abbruch nicht mehr erreicht wird. Recovery-Pfad fuer bereits aufgebrochene Ketten: `VF_SEKTION_RESTORE` (vf_linienzug.lsp) setzt das Ketten-Journal aus der XDATA der losen Objekte zusammen - `SSG_VF_EDIT_SEG` traegt pro Entity den Journal-Abschnitt DER ITERATION, in der es entstand (indiziert mit dem ersten Glied-Index darin; eine VF-Einheit mit eingebetteten Vario-Kurven erzeugt mehrere Glieder in einer Iteration), `SSG_VF_EDIT_PRE` auf den Entities des ersten Gliedes die Praeambel (Startpunkt/Starthoehe/AS). Die `.dbg`-Dateien sind reine AUSGABE und werden von keinem Befehl gelesen (dbgopen legt sie bei jedem Lauf neu an) - Wiederherstellungs-Daten gehoeren in die XDATA. `vf_konstanten.lsp` (von vf_core.lsp vor den drei Submodulen geladen) sammelt alle Laengen-/Winkel-/Toleranz-Magic-Numbers aus dem VarioFoerderer-Cluster als dokumentierte `*vfk-*`-Konstanten. Die Migration ist abgeschlossen: vf_core/vf_standard/vf_etage/vf_linienzug referenzieren durchgaengig die zentralen Konstanten statt roher Literale (Winkel, Stations-/Separator-Laengen, Mindestlaengen, AS/ES-Fallback-Versaetze, Text-/Label-Masse) - Ausnahmen sind in `vf_konstanten.lsp` selbst dokumentiert (Werte mit fuehrender Config-Anbindung via `ssg-cfg-or`, itoa-/Integer-Kontexte, Blocknamen-Strings, die 2000.0-mm/m-Umrechnung). `*vfk-gf-bogen-winkel*` (30/60/90, GF-Bogen + Vario-Kurve) und `*vfk-as-es-winkel*` ("30"/"90", AS/ES; bewusst STRING, da 2-wertig und im Journal als STR gefuehrt) sind Beispiele; vf_linienzug hat fuer beide einen Fallback, falls vf_konstanten nicht geladen wurde. **Nicht-interaktiver Betrieb**: `*vfl-headless*` (+ `vfl-headless-p`/`-abbruch`/`-notausgang`, Diagnose `*vfl-headless-fehler*`, optionaler Antwort-Hook `*vfl-headless-antwort-fn*`) verbietet jede Live-Eingabe - eine erschoepfte Replay-Queue ist damit ein harter Abbruch MIT Fundstelle (Art der Eingabe, Glied- und Eingabe-Nummer) statt eines stillen Rueckfalls auf `getpoint`/`getreal`; eingebaut in `vfl-in-value`/`-value-p`/`-selection`/`-abstand`. Die Bau-Pfade melden abgewiesene Sektionen ueber `vfl-meldung` (sammelt nach `*vfl-meldungen*` + `dbgmsg`, `alert` nur bei erlaubter GUI, sonst `princ`) statt per blockierendem `alert`; reine Interaktiv-Alerts (fehlendes DCL, "nicht editierbar", "kein Journal") bleiben `alert`. Genutzt von `tests/test_hm_recformat.lsp` (Replay der echten Aufzeichnungen) und von `vf_spec.lsp`; Fahrplan in `doc/todo/plan-vf-interactive.md`. Details/Entscheidungsbaum: `doc/variofoerderer.md` | | `vf_spec.lsp` (von vf_core.lsp NACH vf_linienzug.lsp geladen) | VF_SPEC_BAU | Linienzug-Ketten aus **Eingabedaten** bauen, ohne Dialog und ohne Konsolenfrage (Stufe 1 aus `doc/todo/plan-vf-interactive.md`). Eine **Spec** beschreibt eine Kette in Domaenenwerten (`"links"`, `"winkel"`, `"aussen"`, ja/nein) statt in Menue-Codes; `vsp-journal` uebersetzt sie in ein Eingabe-Journal, `vsp-bau-aus-spec` spielt es per `vfl-journal-replay-start` durch den UNVERAENDERTEN `vf-linienzug-modus` (Replay-Kern `vsp-bau-journal` - nimmt auch ein unveraendert uebernommenes, aufgezeichnetes Journal, z.B. aus `dxf_anlage_export.py`). Damit traegt der fertige Block dasselbe `SSG_VF_EDIT`-Journal wie eine handgebaute Kette und bleibt per Doppelklick editier- und 2D/3D-konvertierbar - kein Journal-Konsument muss etwas von Specs wissen. Wichtige Regeln, die der Uebersetzer kennt: der Menue-Code haengt am Frame (erste Sektion 4 Optionen ohne GF-Bogen, danach 5), `hz` steht nur beim ERSTEN Segment im Journal, und `erst-hor` unterscheidet den horizontalen Erstkoerper einer VF-Einheit (Separator-/Endpunktfragen vorab) vom gewinkelten (keine Frage). Fehlerverhalten: fail fast - `vsp-pruefen` sammelt ALLE Spec-Fehler, gebaut wird dann nichts (nichts wird geraten). Ergebnis-Record je Kette mit `status` (`executed`/`warnung`/`desync`/`abbruch`/`spec-fehler`), Block/Handle/Einfuegepunkt/Attributen, `prompts` (muss 0 sein), `glieder_soll` vs. `glieder_ist` (Desync-Detektor, der auch bei aufgehender Queue greift) und den gesammelten `meldungen`. Headless-Rahmen `vsp-headless-an`/`-aus` (Save/Restore von `*vfl-headless*`, `*vfl-wizard-mode*`, `*ssg-gui-aus*` + zaehlende Eingabe-Stubs). Spec-Datei flach als JSON (`ssg-load-json` liest zeilenweise), erzeugt von `lib/vf_spec_export.py`. Gegenstueck/Referenz in Python: derselbe Emitter, gegen die 5 echten HundM-Ketten rundlaufgeprueft | @@ -113,6 +115,7 @@ Detaillierte Dokumentation aller Funktionen und Befehle: siehe `Lisp/README.md`. | `Tro_Edit.lsp` | TRO_INSERT, TRO_EDIT | TRO-Marker (Block `TRO_SYM_`) fuer sps_skel (lib/tro_annotate.py): TRO_INSERT fuegt eine bestehende Blockdefinition an einem gewaehlten Punkt ein und setzt ID/TYPE (bricht ab, wenn der Typ noch keine Blockdefinition in der Zeichnung hat - die entsteht nur ueber tro_annotate.py); TRO_EDIT aendert ID/TYPE eines bestehenden Markers per Dialog. Typliste aus `tro_types.lsp` (von `tro_annotate.py --emit-lisp` nach DXFM_LISP geschrieben). Der Dispatcher SSG_BLOCKEDIT leitet Blocknamen `TRO_*` zu TRO_EDIT. | | `GeruestInsert.lsp` | GERUEST, GERUEST_SAEULEN, GERUEST_ROHRABHAENGER, GERUEST_WANDBEFESTIGUNG, GERUEST_TRAEGER, GERUEST_TRAEGER_BESCHRIFTEN | Geruest-Baugruppen aus `data/json/geruest.json` konfigurieren und einfuegen. **Ein Dialog fuer alle Bereiche**: oben ein Dropdown `bereich` (Rohrabhaenger / Saeulen / Wandbefestigung, Reihenfolge = Dateireihenfolge, Anzeigename aus dem ASCII-Feld `titel`). DCL hat **kein Reiter-Tile**, und da sich die Teilezeilen je Bereich unterscheiden, schliesst ein Bereichswechsel den Dialog (`done_dialog 4`) und die Schleife in `c:GERUEST` baut ihn neu auf; der Stand jedes Bereichs bleibt in `*geruest-zustand*` erhalten, ein versehentlicher Wechsel verwirft also nichts. 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. **Die Dialogdefinition wird zur Laufzeit erzeugt** (`geruest-dcl-schreiben` -> temporaere Datei per `vl-filename-mktemp`, nach `unload_dialog` wieder geloescht) - es gibt KEINE `dcl/geruest.dcl`. Grund: je Anbauteil wird ein eigenes Mengenfeld gebraucht, und eine DCL-Liste (`list_box`) kann keine Eingabefelder enthalten; DCL kann weder Dateien einbinden noch Tiles zur Laufzeit erzeugen. Inhalt: Basis-Variante aus `geometrie_varianten` (Dropdown), Laenge (gegen `attribute.Laenge` min/max geprueft, Retry-Schleife), Farbe (`attribute.Teilefarbe`, Freitext bei `frei_option`) und **zwei Befestigungslisten** ("oben"/"unten"), die BEIDE alle `anbaugruppen` enthalten - dasselbe Teil kann oben, unten oder gleichzeitig an beiden Positionen sitzen, je mit eigener Anzahl. **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 (`oben`/`unten`) heisst der gespeicherte Dialogwert `anzahl`. 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. 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 oben, dann unten; 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 ("oben 2x ...") 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 fester Dialog `dcl/geruest_traeger.dcl` (Variante, 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; 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_max`/`rand_min`/`rand_max`, Variante vor Baugruppe), Verteilung `geruest-traeger-streben`: so wenige Streben wie moeglich, beide Raender gleich; Abstand GENAU `abstand_max`, solange der Rand in `rand_min`..`rand_max` bleibt (1300 -> 150|500|500|150), sonst Rand = `rand_min` und Abstand etwas kleiner (1100 -> 100|450|450|100, mit fest 500 geht die Laenge nicht auf); Netto <= 2*rand_max -> eine Strebe mittig, < 2*rand_min -> keine. 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`). Noch NICHT enthalten: Edit-Pfad (GERUEST_EDIT) | | `menu-inventory.lsp` | MenuInventory | BricsCAD Diagnostik (Menuegruppen, Plugins, Startdateien) | +| `DinFormate.lsp` | DIN_FORMATE | Ersatz fuer das alte ACADSST-Makro `DINFORM.LSP`/`.DCL` (SSG2-Menue "DIN-FORMATE..."): fuegt einen DIN-Rahmen (A0-A3, A4 quer/hoch) und optional einen Schriftkopf (KOPF11, Sprachen DE/EN/FR/IT) per Dialog (`dcl/dinformate.dcl`) ein. Block-DWGs liegen flach in `cfg/rahmen/` (kopiert aus `\\infor-ln\SSG_Tools\ACADSST\KOEPFE` - nur die von DINFORM.LSP tatsaechlich referenzierten Dateien: `A0`/`A1`/`A2`/`A3`/`A4Q`/`A4H.DWG` + `Kopf11`/`Kopf11e`/`Kopf11f`/`Kopf11i.dwg`). Rahmen wird im Zeichenmassstab-Faktor eingefuegt, der Kopf im Faktor/100 (Kopf-DWG ist 100x groesser als die Rahmen-DWGs angelegt) - unveraendert aus dem Original-Massstabsschema uebernommen. Blockdefinitionen werden einmalig per `_.-INSERT ... _X 0` nachgeladen (`dinformate-block-laden`), falls noch nicht in der Zeichnung vorhanden. Lazy geladen ueber `(ssg-ensure "DinFormate")`, Menue: Werkzeuge > Din Formate. | | `DrawPlanquadrate.lsp` | DRAW_PLANQUADRATE, DELETE_PLANQUADRATE, PLANQUADRATE_TOGGLE | Zeichnet auf Z=0 ein Planquadrat-Linienraster (senkrecht/waagerecht), im Abstand/Zaehlschema der aktiven `[Planquadrate]`-Konfiguration aus `cfg/export.cfg` (dieselbe Quelle wie `lib/export_planquadrat.py` fuer den CSV-Export). Bereich kommt NICHT aus den Zeichnungs-Extents, sondern aus derselben Blockmenge wie EXPORTCSV (`csv:collect-export-blocks`, export.lsp; siehe `plq-export-bbox`): Ursprung (Index 1) UND obere Grenze kommen BEIDE aus der tatsaechlichen Bounding-Box jedes Blocks (`csv:get-bbox`, wie `bbox_columns()`/`planquadrat_column()`/`_bbox_min()` in `lib/export_csv.py` bzw. `lib/export_planquadrat.py`), NICHT aus dem reinen Einfuegepunkt - bei einem gedrehten/exzentrisch eingefuegten Block (z.B. ein um 90 Grad gedrehter Kreisel) kann das Bounding-Box-Zentrum weit vom Einfuegepunkt abweichen; Ursprung und Zellzuordnung muessen auf derselben Referenz beruhen, sonst driften sie auseinander (realer Bug, behoben). Reine Hilfsgeometrie (Kreisel-Umfahrungsboegen als eigene Linien, Texte) zaehlt bewusst nicht mit, sonst weicht das Raster vom CSV-Export ab. `x_origin`/`y_origin` ueberschreiben den Ursprung, Fallback auf EXTMIN/EXTMAX falls keine Export-Bloecke vorhanden sind bzw. `csv:get-bbox` fuer einen Block scheitert. Spalten-/Zeilenzahl wird IMMER aufgerundet auf volle Rasterschritte, damit alle senkrechten Linien auf der letzten waagerechten enden und umgekehrt - das Raster bildet immer ein geschlossenes Rechteck. Zaehlung (alphabetisch/numerisch je Achse) als Text am linken/unteren Rand. Das fertige Raster (Linien+Texte) wird per `_.-BLOCK`/`_.INSERT` zu einem einzigen Block `ZZ_PLANQUADRATE` bei (0,0,0) zusammengefasst. Layer aus `cfg/layer.cfg` (`[allgemein]` Key `planquadrate`, Fallback `ZZ_Planquadrate`). DRAW_PLANQUADRATE entfernt vor dem Neuaufbau zuerst einen evtl. vorhandenen Block (`plq-block-entfernen`: INSERTs loeschen + `_-PURGE _B`), DELETE_PLANQUADRATE ruft nur diese Entfernung auf. PLANQUADRATE_TOGGLE ("Planquadrate an/aus", Menue: Konfiguration) prueft per `tblsearch`/`ssget "X"`, ob der Block existiert, und dispatcht auf Zeichnen bzw. Loeschen. Lazy geladen ueber `(ssg-ensure "DrawPlanquadrate")`, nicht in der Core-Ladereihenfolge. Die Planquadrat-SPALTE im CSV-Export (`export_csv.py::planquadrat_column`/`resolve_origins`, `lib/export_planquadrat.py::compute_planquadrat`/`_bbox_min`) rechnet ebenfalls durchgaengig auf Bounding-Box-Basis (nicht nur Einfuegepunkt) und liefert eine SPANNE ("A/1-J/1") statt nur einer Zelle, wenn ein Element mehr als eine Zelle ueberdeckt (Kreisel, lange VF-/GF-Ketten). | ## DCL-Dialoge @@ -129,6 +132,7 @@ Detaillierte Dokumentation aller Funktionen und Befehle: siehe `Lisp/README.md`. | `tro_insert.dcl` | TRO_INSERT (Tro_Edit.lsp) | | `tro_edit.dcl` | TRO_EDIT (Tro_Edit.lsp) | | `geruest_traeger.dcl` | GERUEST_TRAEGER (GeruestInsert.lsp, `geruest-traeger-dialog`) | +| `dinformate.dcl` | DIN_FORMATE (DinFormate.lsp) | | `vfl_edit.dcl` | Linienzug-Editieren/Fortsetzen (vf_linienzug.lsp, `vfl-dlg-position`, aufgerufen aus `vfl-edit-ent`) | | `vf_linienzug_wizard.dcl` | Linienzug-Assistent (Modus 1, 2 UND 3): zwei generische Einzel-Dialoge (Zahl-Eingabe, Mehrfachauswahl; `vflw-zahl`/`vflw-wahl`, aufgerufen aus `vfl-in-real`/`vfl-in-string`/`vfl-in-int` bei aktivem `*vfl-wizard-mode*`) PLUS sieben Gruppen-Dialoge, die mehrere immer unmittelbar aufeinanderfolgende Fragen in einem Bildschirm zusammenfassen (Kettenstart, AS-Element, GF-Bogen, ES-Element, Vario-Kurve, Gefaelle festlegen, Ziel-Hoehe, Horizontales Stueck - inkl. Punktwahl-Button mit X/Y/Z-Anzeige; `vflw-gruppe-*-impl` in vf_linienzug.lsp fuellen dafuer vorab eine kleine Pending-Queue `*vflw-pending*`, die einzelnen `vfl-in-*`-Aufrufe bleiben dabei unveraendert) PLUS drei Segment-Gruppen-Dialoge fuer die segmentweise Klassifizierung in Modus 2/3 (`vflw_seg_linie_m2` = Typ+GF-Neigung, `vflw_seg_linie_m3` = 4-fach-Typ+kontextabh. Wertfeld, `vflw_seg_bogen` = Typ+Variante; `vflw-seg-*-impl`). Beide Modi heben vor der Frage das aktuelle Pfad-Segment (LINE/ARC) per `vfl-seg-highlight` (`redraw`) in der Zeichnung hervor und zeigen "Segment i/n ..." im Dialogkopf. Details: `doc/variofoerderer.md` | diff --git a/Lisp/DinFormate.lsp b/Lisp/DinFormate.lsp new file mode 100644 index 0000000..3d233ae --- /dev/null +++ b/Lisp/DinFormate.lsp @@ -0,0 +1,206 @@ +;; ============================================================ +;; DinFormate.lsp - Zeichnungsrahmen + Schriftkopf einfuegen +;; +;; Ersatz fuer das alte ACADSST-Makro DINFORM.LSP/.DCL (SSG2-Menue +;; "DIN-FORMATE..."): fuegt einen DIN-Rahmen (A0-A4, A4 quer/hoch) und +;; optional einen Schriftkopf (KOPF11, vier Sprachen) ein. Die Block-DWGs +;; liegen flach in cfg/rahmen/ (kopiert aus \\infor-ln\SSG_Tools\ACADSST\KOEPFE, +;; nur die tatsaechlich von DINFORM.LSP referenzierten Dateien): +;; A0.DWG, A1.DWG, A2.DWG, A3.DWG, A4Q.DWG, A4H.DWG +;; Kopf11.dwg, Kopf11e.dwg, Kopf11f.dwg, Kopf11i.dwg (DE/EN/FR/IT) +;; +;; Aufruf: Menue SSG_LIB > Werkzeuge > Din Formate, oder direkt DIN_FORMATE. +;; +;; Rahmen wird im Massstabsfaktor eingefuegt (Skalierung = Zeichenmassstab, +;; wie im Original), der Kopf im Faktor/100 (Rahmen-DWGs sind im Format +;; 1:1 bei realer Papiergroesse gezeichnet, der Kopf 100x groesser angelegt - +;; unveraendert aus DINFORM.LSP uebernommen). +;; +;; Setzt ssg_core.lsp (ssg-start/ssg-end) und ssg_lang.lsp (ssg-text/-textf) +;; voraus, die ssg-ensure als Kern-Abhaengigkeit laedt. +;; ============================================================ + +(setq *dinformate-rahmen-liste* + (list + (cons "A0" "A0") + (cons "A1" "A1") + (cons "A2" "A2") + (cons "A3" "A3") + (cons "A4 Quer" "A4Q") + (cons "A4 Hoch" "A4H") + ) +) + +(setq *dinformate-sprachen-liste* + (list + (cons (ssg-text "dinformate-sprache-de") "Kopf11") + (cons (ssg-text "dinformate-sprache-en") "Kopf11e") + (cons (ssg-text "dinformate-sprache-fr") "Kopf11f") + (cons (ssg-text "dinformate-sprache-it") "Kopf11i") + ) +) + +(setq *dinformate-massstab-liste* + (list + (cons "1:1" 1.0) + (cons "1:10" 10.0) + (cons "1:20" 20.0) + (cons "1:25" 25.0) + (cons "1:50" 50.0) + (cons "1:75" 75.0) + (cons "1:100" 100.0) + (cons "1:200" 200.0) + (cons "1:500" 500.0) + (cons "1:1000" 1000.0) + ) +) + + +;; ------------------------------------------------------------ +;; Verzeichnis der Rahmen-/Kopf-DWGs (cfg/rahmen) +;; ------------------------------------------------------------ +(defun dinformate-verzeichnis ( / cfg) + (setq cfg (getenv "DXFM_CFG")) + (if cfg + (strcat (vl-string-translate "\\" "/" cfg) "/rahmen") + "rahmen" + ) +) + + +;; ------------------------------------------------------------ +;; Block aus cfg/rahmen laden (falls nicht schon in der Zeichnung). +;; Laedt die Definition ohne Interaktion/Prompts ueber vla-InsertBlock am +;; Ursprung + sofortiges vla-Delete (COM-Weg, wie ssg-ils-block-laden-dim in +;; ssg_core.lsp) - ein command-basiertes "_.-INSERT ... _X" bleibt sonst in +;; der interaktiven Befehlskette haengen und blockiert nachfolgende getpoint- +;; Aufrufe. +;; ------------------------------------------------------------ +(defun dinformate-block-laden (name / pfad temp-obj ms) + (if (not (tblsearch "BLOCK" name)) + (progn + (setq pfad (strcat (dinformate-verzeichnis) "/" name ".dwg")) + (if (findfile pfad) + (progn + (setq ms (vla-get-ModelSpace + (vla-get-ActiveDocument (vlax-get-acad-object)))) + (setq temp-obj (vla-InsertBlock ms + (vlax-3D-point '(0 0 0)) pfad 1.0 1.0 1.0 0)) + (vla-Delete temp-obj) + ) + (alert (ssg-textf "dinformate-datei-fehlt" (list pfad))) + ) + ) + ) +) + + +;; ------------------------------------------------------------ +;; C:DIN_FORMATE - Dialog + Einfuegen von Rahmen und Schriftkopf +;; ------------------------------------------------------------ +(defun c:DIN_FORMATE ( / dcl-pfad dat ergebnis + rahmen-idx rahmen-key + sprache-idx sprache-key + massstab-idx massstab-key faktor + mit-kopf pt1 pt2 oldcmdecho oldblipmode oldlimcheck) + + (ssg-start "DIN_FORMATE" nil) + + (setq dcl-pfad (strcat (getenv "DXFM_DCL") "/dinformate.dcl")) + (setq dat (load_dialog dcl-pfad)) + (if (not (new_dialog "dinformate" dat)) + (progn + (alert (ssg-textf "dinformate-dialog-fehlt" (list dcl-pfad))) + (ssg-end) + (exit) + ) + ) + + (start_list "rahmen") + (foreach eintrag *dinformate-rahmen-liste* (add_list (car eintrag))) + (end_list) + (set_tile "rahmen" "0") + + (start_list "massstab") + (foreach eintrag *dinformate-massstab-liste* (add_list (car eintrag))) + (end_list) + (set_tile "massstab" "6") ; Vorgabe 1:100 + + (start_list "sprache") + (foreach eintrag *dinformate-sprachen-liste* (add_list (car eintrag))) + (end_list) + (set_tile "sprache" "0") ; Vorgabe Deutsch + + (setq rahmen-idx 0 massstab-idx 6 sprache-idx 0 mit-kopf "1") + + (action_tile "rahmen" "(setq rahmen-idx (atoi $value))") + (action_tile "massstab" "(setq massstab-idx (atoi $value))") + (action_tile "sprache" "(setq sprache-idx (atoi $value))") + (action_tile "kopf" "(setq mit-kopf $value)") + (action_tile "accept" + (strcat + "(setq rahmen-idx (atoi (get_tile \"rahmen\"))" + " massstab-idx (atoi (get_tile \"massstab\"))" + " sprache-idx (atoi (get_tile \"sprache\"))" + " mit-kopf (get_tile \"kopf\"))" + "(done_dialog 1)")) + (action_tile "cancel" "(done_dialog 0)") + + (setq ergebnis (start_dialog)) + (unload_dialog dat) + + (if (/= ergebnis 1) + (progn (ssg-end) (exit)) + ) + + (setq rahmen-key (cdr (nth rahmen-idx *dinformate-rahmen-liste*)) + massstab-key (cdr (nth massstab-idx *dinformate-massstab-liste*)) + sprache-key (cdr (nth sprache-idx *dinformate-sprachen-liste*)) + faktor massstab-key) + + ;; --- Umgebung sichern ----------------------------------------------- + (setq oldcmdecho (getvar "CMDECHO") + oldblipmode (getvar "BLIPMODE") + oldlimcheck (getvar "LIMCHECK")) + (setvar "CMDECHO" 0) + (setvar "BLIPMODE" 0) + (setvar "LIMCHECK" 0) + + ;; --- Rahmen einfuegen -------------------------------------------------- + (dinformate-block-laden rahmen-key) + (setq pt1 (getpoint (ssg-text "dinformate-prompt-rahmen"))) + (if (null pt1) + (progn + (setvar "CMDECHO" oldcmdecho) + (setvar "BLIPMODE" oldblipmode) + (setvar "LIMCHECK" oldlimcheck) + (ssg-end) + (exit) + ) + ) + (command "_.INSERT" rahmen-key pt1 faktor "" 0) + + ;; --- Schriftkopf einfuegen (optional) ----------------------------------- + (if (= mit-kopf "1") + (progn + (dinformate-block-laden sprache-key) + (setq pt2 (getpoint (ssg-text "dinformate-prompt-kopf"))) + (if pt2 + (command "_.INSERT" sprache-key pt2 (/ faktor 100.0) "" 0) + ) + ) + ) + + ;; --- Umgebung wiederherstellen ------------------------------------------ + (setvar "CMDECHO" oldcmdecho) + (setvar "BLIPMODE" oldblipmode) + (setvar "LIMCHECK" oldlimcheck) + + (princ (ssg-textf "dinformate-eingefuegt" (list rahmen-key))) + (ssg-end) + (princ) +) + + +(prompt "\nDinFormate.lsp geladen - Befehl: DIN_FORMATE") +(princ) diff --git a/cfg/rahmen/A0.DWG b/cfg/rahmen/A0.DWG new file mode 100644 index 0000000..cb4a739 Binary files /dev/null and b/cfg/rahmen/A0.DWG differ diff --git a/cfg/rahmen/A1.DWG b/cfg/rahmen/A1.DWG new file mode 100644 index 0000000..743ea28 Binary files /dev/null and b/cfg/rahmen/A1.DWG differ diff --git a/cfg/rahmen/A2.DWG b/cfg/rahmen/A2.DWG new file mode 100644 index 0000000..ebd956a Binary files /dev/null and b/cfg/rahmen/A2.DWG differ diff --git a/cfg/rahmen/A3.DWG b/cfg/rahmen/A3.DWG new file mode 100644 index 0000000..a3515a2 Binary files /dev/null and b/cfg/rahmen/A3.DWG differ diff --git a/cfg/rahmen/A4H.DWG b/cfg/rahmen/A4H.DWG new file mode 100644 index 0000000..e8ce64b Binary files /dev/null and b/cfg/rahmen/A4H.DWG differ diff --git a/cfg/rahmen/A4Q.DWG b/cfg/rahmen/A4Q.DWG new file mode 100644 index 0000000..7aa3c97 Binary files /dev/null and b/cfg/rahmen/A4Q.DWG differ diff --git a/cfg/rahmen/Kopf11.dwg b/cfg/rahmen/Kopf11.dwg new file mode 100644 index 0000000..243b4ac Binary files /dev/null and b/cfg/rahmen/Kopf11.dwg differ diff --git a/cfg/rahmen/Kopf11e.dwg b/cfg/rahmen/Kopf11e.dwg new file mode 100644 index 0000000..2ab4047 Binary files /dev/null and b/cfg/rahmen/Kopf11e.dwg differ diff --git a/cfg/rahmen/Kopf11f.dwg b/cfg/rahmen/Kopf11f.dwg new file mode 100644 index 0000000..3029ac8 Binary files /dev/null and b/cfg/rahmen/Kopf11f.dwg differ diff --git a/cfg/rahmen/Kopf11i.dwg b/cfg/rahmen/Kopf11i.dwg new file mode 100644 index 0000000..0cbbbb4 Binary files /dev/null and b/cfg/rahmen/Kopf11i.dwg differ diff --git a/dcl/dinformate.dcl b/dcl/dinformate.dcl new file mode 100644 index 0000000..a0d9963 --- /dev/null +++ b/dcl/dinformate.dcl @@ -0,0 +1,38 @@ +// ============================================================ +// dinformate.dcl - Zeichnungsrahmen + Schriftkopf einfuegen +// Aufruf ueber c:DIN_FORMATE (Lisp/DinFormate.lsp). +// ============================================================ + +dinformate : dialog { + label = "DIN-Format"; + + : column { + + : popup_list { + key = "rahmen"; + label = "Rahmen:"; + width = 30; + } + + : popup_list { + key = "massstab"; + label = "Massstab:"; + width = 30; + } + + : toggle { + key = "kopf"; + label = "Schriftkopf einfuegen"; + value = "1"; + } + + : popup_list { + key = "sprache"; + label = "Sprache Schriftkopf:"; + width = 30; + } + + } + + ok_cancel; +} diff --git a/lang/de_DE.json b/lang/de_DE.json index 21e5686..a7092e5 100644 --- a/lang/de_DE.json +++ b/lang/de_DE.json @@ -1063,6 +1063,15 @@ "tt-geaendert": "\n%1 Text(e) geaendert.", "tt-stil": "\nTextstil", "tt-stil-fehlt": "\nTextstil %1 existiert nicht in der Zeichnung.", - "tt-stil-titel": "Textstil aendern" + "tt-stil-titel": "Textstil aendern", + "dinformate-dialog-fehlt": "DIN-Formate-Dialog nicht gefunden: %1", + "dinformate-datei-fehlt": "DIN-Formate: Datei nicht gefunden: %1", + "dinformate-prompt-rahmen": "\nEinfuegepunkt Rahmen (untere linke Ecke): ", + "dinformate-prompt-kopf": "\nEinfuegepunkt Schriftkopf (untere rechte Ecke): ", + "dinformate-eingefuegt": "\nDIN-Format eingefuegt: %1", + "dinformate-sprache-de": "Deutsch", + "dinformate-sprache-en": "Englisch", + "dinformate-sprache-fr": "Franzoesisch", + "dinformate-sprache-it": "Italienisch" } } diff --git a/lang/en_GB.json b/lang/en_GB.json index 87733d4..3ade428 100644 --- a/lang/en_GB.json +++ b/lang/en_GB.json @@ -1063,6 +1063,15 @@ "tt-geaendert": "\n%1 text(s) changed.", "tt-stil": "\nText style", "tt-stil-fehlt": "\nText style %1 does not exist in the drawing.", - "tt-stil-titel": "Change text style" + "tt-stil-titel": "Change text style", + "dinformate-dialog-fehlt": "DIN formats dialog not found: %1", + "dinformate-datei-fehlt": "DIN formats: file not found: %1", + "dinformate-prompt-rahmen": "\nBorder insertion point (lower left corner): ", + "dinformate-prompt-kopf": "\nHeader insertion point (lower right corner): ", + "dinformate-eingefuegt": "\nDIN format inserted: %1", + "dinformate-sprache-de": "German", + "dinformate-sprache-en": "English", + "dinformate-sprache-fr": "French", + "dinformate-sprache-it": "Italian" } } diff --git a/menu/SSG_LIB.mnu b/menu/SSG_LIB.mnu index 19be501..6f03637 100644 --- a/menu/SSG_LIB.mnu +++ b/menu/SSG_LIB.mnu @@ -32,7 +32,7 @@ [aus 3D-Linie]^C^C(ssg-ensure "Gefaellestrecke") GEFAELLESTRECKE_3DLINIE [aus Linienzug (LINE + ARC)]^C^C(ssg-ensure "Gefaellestrecke") GEFAELLESTRECKE_LINIENZUG [QC Linie mit GF (automatische Auf-Ab-Berechnung)]^C^C(ssg-ensure "VarioFoerderer") QcLinieMitGf -[<-QC Linie mit GF und U-Form]^C^C(ssg-ensure "VarioFoerderer") QcLinieMitGfUForm +[<-<-QC Linie mit GF und U-Form]^C^C(ssg-ensure "VarioFoerderer") QcLinieMitGfUForm [->Omniflo] [->Boegen APB110] [90]^C^C(ssg-ensure "OmniModulInsert") OMNI_APB_630_90 @@ -154,7 +154,10 @@ [Text ersetzen]^C^C(ssg-ensure "ssg_texttools") SSG_TEXT_ERSETZEN [Text parallel beschriften]^C^C(ssg-ensure "ssg_texttools") SSG_TEXT_PARALLEL [Texthoehe aendern]^C^C(ssg-ensure "ssg_texttools") SSG_TEXT_HOEHE -[<-Textstil aendern]^C^C(ssg-ensure "ssg_texttools") SSG_TEXT_STIL +[Textstil aendern]^C^C(ssg-ensure "ssg_texttools") SSG_TEXT_STIL +[--] +[Faehnchen + Stueckliste aus Zeichnung]^C^C(ssg-ensure "ssg_stueckliste") SSG_FAEHNCHEN_STUECKLISTE +[<-Din Formate]^C^C(ssg-ensure "DinFormate") DIN_FORMATE [->Tests] [alle Tests ausfuehren und exportieren]^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_run_all.lsp")) (c:SSG_RUN_ALL_TESTS_EXPORT) [Tests ausfuehren und stehen lassen]^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_run_all.lsp")) (c:SSG_RUN_ALL_TESTS_OFFEN)