[ADD] Lager: Darstellung Gitterrost/Gitterkorb unter Regalreihen, Farben aus lager.json, LG_DARSTELLUNG

[FIX] Lager: manuelle Gaenge/Randgaenge nicht mehr ueberschreiben, Bereich-Edit uebertraegt statt neu zu berechnen
This commit is contained in:
Simon Hensch committed 2026-11-04 09:14:13 +01:00
1 parent a887ae8152
commit 4a5a3da88a
8 files changed
+199 -24

No files matched your search

+1 -1
View File
@@ -126,7 +126,7 @@ Detaillierte Dokumentation aller Funktionen und Befehle: siehe `Lisp/README.md`.
| `KettenFoerderer.lsp` | KETTENFOERDERER, KF_EDIT, KF_KS_PRUEFEN | Kettenfoerderer/Schraegfoerderer Stahl: baut aus `KF_UM_<winkel>` -> `KF_LAENGE` -> `KF_AN_<winkel>` (je KS_AUS auf KS_EIN) plus der Draufsicht `KF_2D` EINEN Block `KF_<n>`. Daten `data/json/kettenfoerderer.json`, Dialog `dcl/kettenfoerderer.dcl`. **Geometrie**: SEITENANSICHT in der XY-Ebene (Hoehe = Y), ungedreht und nicht aufgerichtet, Einfuegepunkt = KS_EIN der Umlenkung; jeder Baustein bekommt nur den aus den KS gemessenen Verkettungswinkel (`insert-block-by-ks`/`insert-block-ks-skaliert`). 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`). **Hauptblock + Hilfsblock**: `KF_<n>` traegt Beschriftung (`KF_1 26 Grad H=..mm L_horizontal=..mm`, Layer `kettenfoerderer_beschriftung`) und ein Hoehenmass (ActiveX `AddDimRotated`, scheitert es, wird ohne Mass gebaut) und ist der EINZIGE exportierte Block. Die Draufsicht `KF_2D` ist ein getrennter Hilfsblock `KF2D_<n>` (kein Objekt, nur zum Anschliessen von Schienen): flach, auf die PROJIZIERTE Laenge skaliert (`kf-waagerecht-laenge`), beim ersten Einfuegen `ansicht_2d.versatz_y` (-1000) mm unter dem Hauptblock, danach frei verschieb- und loeschbar, gleiche Beschriftung. Beide Bloecke tragen denselben Schluessel als XDATA `SSG_KF_EDIT` (`kf-xdata-key`); KF_EDIT findet damit den - auch verschobenen - Hilfsblock (`kf-hilfsblock-finden`), behaelt dessen Lage und erzeugt ihn bei jedem Edit neu (auch wenn er geloescht war). Der Hilfsblock passt nicht aufs Export-Muster `KF_*`; `export_sivas.py` nimmt ausserdem nur `KF_<Ziffern>`. Eine von Hand gesetzte Drehung des Hauptblocks (DXF 50) wird beim Edit wieder aufgesetzt. **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). `L_KF_mm` ist die WAAGERECHTE Laenge des ganzen Foerderers (der Draufsicht `KF_2D`, `kf-waagerecht-laenge`), nicht die Laenge des schraegen Mittelstuecks; sie geht NICHT in die Sivas-Zeile (Spalte Laenge bleibt leer) - Sivas berechnet ZL, EL und Kettenlaenge selbst, uebernommen wird nur die Hoehe (360). 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, der die vorgewaehlte Auswahl nutzt und nur echte `KF_<n>` zulaesst - die Bausteine `KF_UM_26`, `KF_2D` usw. tragen dasselbe Praefix). **Die Blocknummer wird ueber die Blocktabelle vergeben** (`kf-naechste-nummer` ueberspringt jede Nummer mit vorhandener Block-DEFINITION, wie bei `GF_n`/`VF_n`): nur ueber die Referenzen im Modell zu zaehlen war ein realer Fehler - `KF_EDIT` loescht den alten Block, die Definition lebt aber weiter, `_.-BLOCK` traf auf den vorhandenen Namen, die "Neu definieren?"-Abfrage verschluckte die Folge-Eingaben, und die Einzelteile blieben lose liegen ("Block aufgeloest"). **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` | | `KettenFoerderer.lsp` | KETTENFOERDERER, KF_EDIT, KF_KS_PRUEFEN | Kettenfoerderer/Schraegfoerderer Stahl: baut aus `KF_UM_<winkel>` -> `KF_LAENGE` -> `KF_AN_<winkel>` (je KS_AUS auf KS_EIN) plus der Draufsicht `KF_2D` EINEN Block `KF_<n>`. Daten `data/json/kettenfoerderer.json`, Dialog `dcl/kettenfoerderer.dcl`. **Geometrie**: SEITENANSICHT in der XY-Ebene (Hoehe = Y), ungedreht und nicht aufgerichtet, Einfuegepunkt = KS_EIN der Umlenkung; jeder Baustein bekommt nur den aus den KS gemessenen Verkettungswinkel (`insert-block-by-ks`/`insert-block-ks-skaliert`). 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`). **Hauptblock + Hilfsblock**: `KF_<n>` traegt Beschriftung (`KF_1 26 Grad H=..mm L_horizontal=..mm`, Layer `kettenfoerderer_beschriftung`) und ein Hoehenmass (ActiveX `AddDimRotated`, scheitert es, wird ohne Mass gebaut) und ist der EINZIGE exportierte Block. Die Draufsicht `KF_2D` ist ein getrennter Hilfsblock `KF2D_<n>` (kein Objekt, nur zum Anschliessen von Schienen): flach, auf die PROJIZIERTE Laenge skaliert (`kf-waagerecht-laenge`), beim ersten Einfuegen `ansicht_2d.versatz_y` (-1000) mm unter dem Hauptblock, danach frei verschieb- und loeschbar, gleiche Beschriftung. Beide Bloecke tragen denselben Schluessel als XDATA `SSG_KF_EDIT` (`kf-xdata-key`); KF_EDIT findet damit den - auch verschobenen - Hilfsblock (`kf-hilfsblock-finden`), behaelt dessen Lage und erzeugt ihn bei jedem Edit neu (auch wenn er geloescht war). Der Hilfsblock passt nicht aufs Export-Muster `KF_*`; `export_sivas.py` nimmt ausserdem nur `KF_<Ziffern>`. Eine von Hand gesetzte Drehung des Hauptblocks (DXF 50) wird beim Edit wieder aufgesetzt. **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). `L_KF_mm` ist die WAAGERECHTE Laenge des ganzen Foerderers (der Draufsicht `KF_2D`, `kf-waagerecht-laenge`), nicht die Laenge des schraegen Mittelstuecks; sie geht NICHT in die Sivas-Zeile (Spalte Laenge bleibt leer) - Sivas berechnet ZL, EL und Kettenlaenge selbst, uebernommen wird nur die Hoehe (360). 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, der die vorgewaehlte Auswahl nutzt und nur echte `KF_<n>` zulaesst - die Bausteine `KF_UM_26`, `KF_2D` usw. tragen dasselbe Praefix). **Die Blocknummer wird ueber die Blocktabelle vergeben** (`kf-naechste-nummer` ueberspringt jede Nummer mit vorhandener Block-DEFINITION, wie bei `GF_n`/`VF_n`): nur ueber die Referenzen im Modell zu zaehlen war ein realer Fehler - `KF_EDIT` loescht den alten Block, die Definition lebt aber weiter, `_.-BLOCK` traf auf den vorhandenen Namen, die "Neu definieren?"-Abfrage verschluckte die Folge-Eingaben, und die Einzelteile blieben lose liegen ("Block aufgeloest"). **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` |
| `HwPlanung.lsp` | HW_MATERIALFLUSS, HW_SYMBOLE, HW_SYM_VENTILE, HW_SYM_SENSOREN, HW_SYM_MOTOREN, HW_SYM_MOTORSCHUTZ, HW_SYM_ENCODER, HW_SYM_SCANNER, HW_SYM_LOESCHEN, HW_NUMMERIEREN | Menue "HW Planung" (zwischen Lager und SPS), Ablauf und Renamer-Regeln in `doc/hw_planung.md`. **Ausgabeziel per Dialog** `dcl/hw_ausgabe.dcl` vor jedem Erzeugungsbefehl (`hw-ausgabe-waehlen`, letzte Wahl je Sitzung in `*hw-ausgabe-letzt*`, ohne GUI Standarddatei `<dwg>_HW.dxf`): **aktuelle Zeichnung** (Python schreibt eine EINHEITENLOSE Zwischendatei `<dwg>_HW_tmp.dxf` (`--einheitenlos`, sonst skaliert BricsCAD beim Einfuegen), `hw-in-aktuelle-zeichnung` fuegt sie per `vla-InsertBlock` bei 0,0 ein, loest sie per `vla-Explode` auf und loescht ERST DANACH die fruehere Ausgabe - `hw-alte-ausgabe` ueber XDATA `SSG_HW_MF` (Materialfluss) bzw. `SSG_HW_SYM` je Praefix), **bestehende Datei ergaenzen** (getfiled ueber `done_dialog 2`, da getfiled aus einem action_tile nicht geht) oder **neue Datei** (Name, Ordner DXFM_RESULTS; existiert sie, bleibt der Dialog mit Hinweis offen). Reine Kerne `hw-name-ohne-dxf`/`hw-name-gueltig-p`/`hw-neu-pfad`/`hw-ausgabe-pruefen` getestet. In einer Datei ersetzt jeder Befehl nur seinen eigenen Anteil (Materialfluss = XDATA `SSG_HW_MF` bzw. HW_*-Layer, Symbole = XDATA `SSG_HW_SYM` je Praefix) - vom Anwender Gezeichnetes (Renamer-Bereiche) bleibt; die Ursprungsdatei auf der Platte wird nie geaendert. Python-Aufrufe zentral ueber `hw-python` (Log je Befehl in DXFM_LOG, `ok-codes` fuer create_numbers' Exit 1 bei Planungsfehlern). HW_MATERIALFLUSS: EXPORTCSV (alte CSV vorher geloescht) -> `lib/hw_materialfluss.py`. **Symbole**: Regelwerk `cfg/io_regeln.json` (reduzierte Kopie aus kabellaengen: Rollen mit Praefix/Symbolblock, Bauteile, `io_vorlage`; Erkennungs-Regex/Radien/Nummernpaare/altZuNeu entfernt). **Aussehen und Attribute der Symbole stehen in `cfg/hw_symbole.json`** (Vorlagen mit Rahmen/Schraffur + Attribut-Lage/-Hoehe/-Stil, je Symbol Layer/Farbe/`versatz`/Abweichungen je Tag/Werte) - es gibt KEINE Symbol-Bibliothek als Referenzdokument. Die Symbole tragen DIESELBEN Blocknamen wie die ILS-Katalogsymbole in kabellaengen und sind ihnen exakt nachgebaut (inkl. Einfuegepunkt: Eingaenge/Motoren haengen nach unten) - `test_symbole_gleichen_dem_katalog` prueft das gegen `kabellaengen/doc/Symbole/ILS-Symbole.dxf`; aendert sich dort ein Symbol, faellt der Test und die Konfiguration wird nachgezogen. `hw-sym-bauteile-sammeln` findet die Mechanik-Bloecke der Ursprungszeichnung top-level UND verschachtelt in VF_n/GF_n/KREISEL_n (Weltlage ueber `csv:wrapper-welt-records`), `hw-sym-plan` legt je Rolle Symbolblock, flachen ZIELPUNKT (Bauteil-Einfuegepunkt, `hw-sym-ziel`) und ID-VORLAGE (`hw-sym-io-vorlage`, z.B. `MB1@@@`) fest; bei Alternativen in `benoetigt` die erste. `hw-sym-plan->json` (Zahlen ueber `hw-json-zahl`, DIMZIN-unabhaengig) -> `<dwg>_hw_symbole.json` -> `lib/hw_symbole.py`; der Plan ist IMMER vollstaendig (alle Praefixe), `praefixe` sagt nur, was eingefuegt wird - so haengt die Lage nicht vom Einzelbefehl ab. Die LAGE rechnet Python (kennt die Symbolgeometrie), nicht LISP. Die Nummern vergibt NICHT das Erzeugen, sondern HW_NUMMERIEREN in der geoeffneten _HW.dxf: QSAVE, `lib/create_numbers.py --dryrun --info`, dann `hw-num-anwenden` (Zuordnung je Attribut mit `@` ueber Wert + Einfuegepunkt, `hw-num-eintrag-p`) in die offene Zeichnung. Reine Kerne in `tu-tests-hw` | | `HwPlanung.lsp` | HW_MATERIALFLUSS, HW_SYMBOLE, HW_SYM_VENTILE, HW_SYM_SENSOREN, HW_SYM_MOTOREN, HW_SYM_MOTORSCHUTZ, HW_SYM_ENCODER, HW_SYM_SCANNER, HW_SYM_LOESCHEN, HW_NUMMERIEREN | Menue "HW Planung" (zwischen Lager und SPS), Ablauf und Renamer-Regeln in `doc/hw_planung.md`. **Ausgabeziel per Dialog** `dcl/hw_ausgabe.dcl` vor jedem Erzeugungsbefehl (`hw-ausgabe-waehlen`, letzte Wahl je Sitzung in `*hw-ausgabe-letzt*`, ohne GUI Standarddatei `<dwg>_HW.dxf`): **aktuelle Zeichnung** (Python schreibt eine EINHEITENLOSE Zwischendatei `<dwg>_HW_tmp.dxf` (`--einheitenlos`, sonst skaliert BricsCAD beim Einfuegen), `hw-in-aktuelle-zeichnung` fuegt sie per `vla-InsertBlock` bei 0,0 ein, loest sie per `vla-Explode` auf und loescht ERST DANACH die fruehere Ausgabe - `hw-alte-ausgabe` ueber XDATA `SSG_HW_MF` (Materialfluss) bzw. `SSG_HW_SYM` je Praefix), **bestehende Datei ergaenzen** (getfiled ueber `done_dialog 2`, da getfiled aus einem action_tile nicht geht) oder **neue Datei** (Name, Ordner DXFM_RESULTS; existiert sie, bleibt der Dialog mit Hinweis offen). Reine Kerne `hw-name-ohne-dxf`/`hw-name-gueltig-p`/`hw-neu-pfad`/`hw-ausgabe-pruefen` getestet. In einer Datei ersetzt jeder Befehl nur seinen eigenen Anteil (Materialfluss = XDATA `SSG_HW_MF` bzw. HW_*-Layer, Symbole = XDATA `SSG_HW_SYM` je Praefix) - vom Anwender Gezeichnetes (Renamer-Bereiche) bleibt; die Ursprungsdatei auf der Platte wird nie geaendert. Python-Aufrufe zentral ueber `hw-python` (Log je Befehl in DXFM_LOG, `ok-codes` fuer create_numbers' Exit 1 bei Planungsfehlern). HW_MATERIALFLUSS: EXPORTCSV (alte CSV vorher geloescht) -> `lib/hw_materialfluss.py`. **Symbole**: Regelwerk `cfg/io_regeln.json` (reduzierte Kopie aus kabellaengen: Rollen mit Praefix/Symbolblock, Bauteile, `io_vorlage`; Erkennungs-Regex/Radien/Nummernpaare/altZuNeu entfernt). **Aussehen und Attribute der Symbole stehen in `cfg/hw_symbole.json`** (Vorlagen mit Rahmen/Schraffur + Attribut-Lage/-Hoehe/-Stil, je Symbol Layer/Farbe/`versatz`/Abweichungen je Tag/Werte) - es gibt KEINE Symbol-Bibliothek als Referenzdokument. Die Symbole tragen DIESELBEN Blocknamen wie die ILS-Katalogsymbole in kabellaengen und sind ihnen exakt nachgebaut (inkl. Einfuegepunkt: Eingaenge/Motoren haengen nach unten) - `test_symbole_gleichen_dem_katalog` prueft das gegen `kabellaengen/doc/Symbole/ILS-Symbole.dxf`; aendert sich dort ein Symbol, faellt der Test und die Konfiguration wird nachgezogen. `hw-sym-bauteile-sammeln` findet die Mechanik-Bloecke der Ursprungszeichnung top-level UND verschachtelt in VF_n/GF_n/KREISEL_n (Weltlage ueber `csv:wrapper-welt-records`), `hw-sym-plan` legt je Rolle Symbolblock, flachen ZIELPUNKT (Bauteil-Einfuegepunkt, `hw-sym-ziel`) und ID-VORLAGE (`hw-sym-io-vorlage`, z.B. `MB1@@@`) fest; bei Alternativen in `benoetigt` die erste. `hw-sym-plan->json` (Zahlen ueber `hw-json-zahl`, DIMZIN-unabhaengig) -> `<dwg>_hw_symbole.json` -> `lib/hw_symbole.py`; der Plan ist IMMER vollstaendig (alle Praefixe), `praefixe` sagt nur, was eingefuegt wird - so haengt die Lage nicht vom Einzelbefehl ab. Die LAGE rechnet Python (kennt die Symbolgeometrie), nicht LISP. Die Nummern vergibt NICHT das Erzeugen, sondern HW_NUMMERIEREN in der geoeffneten _HW.dxf: QSAVE, `lib/create_numbers.py --dryrun --info`, dann `hw-num-anwenden` (Zuordnung je Attribut mit `@` ueber Wert + Einfuegepunkt, `hw-num-eintrag-p`) in die offene Zeichnung. Reine Kerne in `tu-tests-hw` |
| `menu-inventory.lsp` | MenuInventory | BricsCAD Diagnostik (Menuegruppen, Plugins, Startdateien) | | `menu-inventory.lsp` | MenuInventory | BricsCAD Diagnostik (Menuegruppen, Plugins, Startdateien) |
| `LagerInsert.lsp` | LG_GESCHOSS, LG_GESCHOSS_AKTIV, LG_GESCHOSS_KOPIEREN, LG_BEREICH, LG_REIHE, LG_GANG, LG_EDIT, LG_REGALE, LG_DARSTELLUNG, LAGER_EXPORT | Lagerplanung GOH-Buehnenlager -> technische Daten als JSON fuer die RFQ-Dokumentation (Phase 0+1: Mengen, 2D; Konzept/Schema/Kennwerte in `doc/plan/lager_rfq.md`). Bloecke `LG_GESCHOSS` (Kopfsymbol, XDATA `SSG_LG` `kontur` -> Belagskontur), `LG_BEREICH` (Kontur + Parameter, fuellt sich selbst), `LG_REIHE_<L>_<T>`/`LG_GANG_<L>_<B>_<BELAG>` (Definition je Geometrie wiederverwendet, Werte in den Attributen der Referenz; Kinder tragen XDATA `bereich`; der Belag steht im Gang-Blocknamen, weil die Definition seine Schraffur enthaelt - Muster aus `lager.json belag_schraffur`, per `vla-AddHatch` auf Layer 0/VONBLOCK, `hallenboden` ohne; BricsCAD-`iso.pat` kennt kein `NET`, Gitterrost = `GRID`). Alle tragen `ID`, `GESCHOSS`, `LAYER`. Blockdefinitionen per `entmake` (BLOCK...ENDBLK), Einfuegen per `vla-InsertBlock` in WCS - kein `_.-BLOCK`/`_.INSERT`. **Attribut-Tags haben gemischte Schreibweise** (`HOEHE_BELAG_mm`) - beim Setzen ueber `vla-get-TagString` daher case-insensitiv zuordnen (`lg-wert-fuer-tag`), sonst bleiben diese Attribute still leer (realer Fehler beim Bau). Layer je Geschoss = Basis aus `cfg/layer.cfg [lager]` + `_G<nr>`; `LG_GESCHOSS_AKTIV` friert die uebrigen (2D-Grundrisse liegen uebereinander), aktives Geschoss als `vlax-ldata` (Dictionary `SSG_LAGER`). Geschosszuordnung `lg-geschoss-fuer-punkt-kern`: eine Kontur -> eindeutig, mehrere nur ueber Z unterscheidbar, wenn die Konturen auf verschiedenen Hoehen liegen (3D), sonst nil. Jede Kontur gehoert genau einem Block (vergebene Kontur wird kopiert). Auto-Fuellung `lg-fuellung-berechnen` (reiner Kern, Muster Reihe|Gang|Reihe Ruecken an Ruecken bzw. Reihe|Gang, nur volle Module, Streifen an Unter-/Mittel-/Oberkante gegen die Kontur geschnitten, Quergaenge ausgerichtet und nicht am Reihenende); Bereichs-Edit = Neuaufbau aller Kinder. **Randgaenge** `RANDGANG_N/O/S/W_mm` (Nord = +Y Welt) laufen entlang der echten Konturkanten (`lg-randgang-streifen`, Himmelsrichtung der Aussennormale ueber `lg-kompass`, auch L-Form; Ecken: N/S besitzen sie - konvex O/W kuerzen, einspringend N/S verlaengern) und werden wie manuelle Gaenge (`LG_GANG`, `QUELLE=manuell`, Kern `lg-gang-einfuegen`; per Linie oder Option `Rechteck` = Flaeche mit dem echten BricsCAD-Befehl RECHTECK gezeichnet, inkl. aller seiner Optionen (`lg-rechteck-zeichnen`: `_.RECTANG` + `(command pause)`-Schleife bei CMDECHO 1, Polylinie danach ueber `lg-rechteck-ecken-aus-poly` gelesen und geloescht; nur 4 Ecken ohne Boegen, sonst Meldung), Breite/Lage aus dem Rechteck ueber `lg-gang-aus-ecken`, Schleife `lg-linien-schleife` mit `rechteck-fn`) als **Sperrflaechen** aus Reihen/Haupt-/Quergaengen ausgeschnitten (`ssg-poly-band-x`). **Von Hand Gesetztes loest KEINE Neuberechnung aus**: `LG_REIHE`/`LG_GANG` (`lg-manuell-einfuegen`) und das Bearbeiten einer Reihe/eines Gangs (`lg-linie-neu-aufbauen-sperre`) schneiden nur die eigene Flaeche aus den rangniedrigeren Objekten heraus (`lg-sperre-anwenden`, reiner Kern `lg-linie-zuschnitt`; Rang `lg-quelle-rang`: auto < auto_geaendert < manuell) - frueher fuellte ein manueller Gang den ganzen Bereich neu, dabei kamen geloeschte Objekte zurueck und geaenderte wurden ersetzt. Die ausdrueckliche Neuberechnung (`lg-bereich-fuellen`, Bereich bearbeiten) entfernt nur `QUELLE=auto`; `manuell`/`auto_geaendert`-Kinder und unverknuepfte manuelle Objekte in der Kontur (`lg-manuelle-in-kontur`) bleiben und sperren ihre Flaeche. `lg-blockdef` ergaenzt bei Altbestand fehlende ATTDEFs (Neudefinition + `_.ATTSYNC`). `LAGER_EXPORT` schreibt NUR `<dwg>_lager.json` nach `DXFM_RESULTS` (Format `ssg-lager` Version 2, kein Python-Schritt; das RFQ-Projekt uebernimmt Mapping und Hand-Abgleich): alle Geschosse, Bereiche, Reihen und Gaenge mit Attributen und voller Geometrie (Konturpunkte, Start/Ende/Mitte, 4 Ecken) plus `kennwerte` je Geschoss und `lager` gesamt (lichte Hoehe, Regal-/Schienenlaenge, Haengeebenen, Gaenge je Art und Breite, Belags-/Gitterrostflaeche, Gitterkorb, Regalrohr = Laenge x Haengeebenen), je Geschoss-Kennwert `herkunft` (Formel + Quelle). **`null` = fehlt (offener Punkt), nicht Zutreffendes wird weggelassen** (Marker `'ENTFAELLT`, `lg-json-ohne-entfallend`). Plausibilitaetswarnungen je Geschoss (`lg-plausibilitaet`, Grenzwerte aus dem Regelprofil). Das Reihen-Attribut `SCHIENEN` ist entfallen; `SCHIENEN_JE_GANG` am Bereich (Trolley) wird noch nicht ausgewertet. Eigener JSON-Schreiber `lg-json-*` ueber getaggte Werte `(OBJ ...)`/`(ARR ...)` (`lg-json-text` rueckt ein, Nicht-ASCII als `\uXXXX`), Kennwerte in reinen Kernen (`lg-kennwerte-geschoss`/`-lager`, `lg-haengeebenen-summen`, `lg-gaenge-je-art`, `lg-reihen-offene-kanten`, `lg-reihen-gitterkorb-berechnen`). **Absturzsicherung unter den Reihen** je Bereich (`UNTER_REIHE` = `gitterrost`/`gitterkorb`/`keine`, Vorgabe `lager.json bereich.unter_reihe`, nur auf BLine truncated | `LagerInsert.lsp` | LG_GESCHOSS, LG_GESCHOSS_AKTIV, LG_GESCHOSS_KOPIEREN, LG_BEREICH, LG_REIHE, LG_GANG, LG_EDIT, LG_REGALE, LG_DARSTELLUNG, LAGER_EXPORT | Lagerplanung GOH-Buehnenlager -> technische Daten als JSON fuer die RFQ-Dokumentation (Phase 0+1: Mengen, 2D; Konzept/Schema/Kennwerte in `doc/plan/lager_rfq.md`). Bloecke `LG_GESCHOSS` (Kopfsymbol, XDATA `SSG_LG` `kontur` -> Belagskontur), `LG_BEREICH` (Kontur + Parameter, fuellt sich selbst), `LG_REIHE_<L>_<T>`/`LG_GANG_<L>_<B>_<BELAG>` (Definition je Geometrie wiederverwendet, Werte in den Attributen der Referenz; Kinder tragen XDATA `bereich`; der Belag steht im Gang-Blocknamen, weil die Definition seine Schraffur enthaelt - Muster aus `lager.json belag_schraffur`, per `vla-AddHatch` auf Layer 0/VONBLOCK, `hallenboden` ohne; BricsCAD-`iso.pat` kennt kein `NET`, Gitterrost = `GRID`). Alle tragen `ID`, `GESCHOSS`, `LAYER`. Blockdefinitionen per `entmake` (BLOCK...ENDBLK), Einfuegen per `vla-InsertBlock` in WCS - kein `_.-BLOCK`/`_.INSERT`. **Attribut-Tags haben gemischte Schreibweise** (`HOEHE_BELAG_mm`) - beim Setzen ueber `vla-get-TagString` daher case-insensitiv zuordnen (`lg-wert-fuer-tag`), sonst bleiben diese Attribute still leer (realer Fehler beim Bau). Layer je Geschoss = Basis aus `cfg/layer.cfg [lager]` + `_G<nr>`; `LG_GESCHOSS_AKTIV` friert die uebrigen (2D-Grundrisse liegen uebereinander), aktives Geschoss als `vlax-ldata` (Dictionary `SSG_LAGER`). Geschosszuordnung `lg-geschoss-fuer-punkt-kern`: eine Kontur -> eindeutig, mehrere nur ueber Z unterscheidbar, wenn die Konturen auf verschiedenen Hoehen liegen (3D), sonst nil. Jede Kontur gehoert genau einem Block (vergebene Kontur wird kopiert). Auto-Fuellung `lg-fuellung-berechnen` (reiner Kern, Muster Reihe|Gang|Reihe Ruecken an Ruecken bzw. Reihe|Gang, nur volle Module, Streifen an Unter-/Mittel-/Oberkante gegen die Kontur geschnitten, Quergaenge ausgerichtet und nicht am Reihenende); Bereichs-Edit = Neuaufbau aller Kinder. **Randgaenge** `RANDGANG_N/O/S/W_mm` (Nord = +Y Welt) laufen entlang der echten Konturkanten (`lg-randgang-streifen`, Himmelsrichtung der Aussennormale ueber `lg-kompass`, auch L-Form; Ecken: N/S besitzen sie - konvex O/W kuerzen, einspringend N/S verlaengern) und werden wie manuelle Gaenge (`LG_GANG`, `QUELLE=manuell`, Kern `lg-gang-einfuegen`; per Linie oder Option `Rechteck` = Flaeche mit dem echten BricsCAD-Befehl RECHTECK gezeichnet, inkl. aller seiner Optionen (`lg-rechteck-zeichnen`: `_.RECTANG` + `(command pause)`-Schleife bei CMDECHO 1, Polylinie danach ueber `lg-rechteck-ecken-aus-poly` gelesen und geloescht; nur 4 Ecken ohne Boegen, sonst Meldung), Breite/Lage aus dem Rechteck ueber `lg-gang-aus-ecken`, Schleife `lg-linien-schleife` mit `rechteck-fn`) als **Sperrflaechen** aus Reihen/Haupt-/Quergaengen ausgeschnitten (`ssg-poly-band-x`). **Von Hand Gesetztes loest KEINE Neuberechnung aus**: `LG_REIHE`/`LG_GANG` (`lg-manuell-einfuegen`) und das Bearbeiten einer Reihe/eines Gangs (`lg-linie-neu-aufbauen-sperre`) schneiden nur die eigene Flaeche aus den rangniedrigeren Objekten heraus (`lg-sperre-anwenden`, reiner Kern `lg-linie-zuschnitt`; Rang `lg-quelle-rang`: auto < auto_geaendert < manuell) - frueher fuellte ein manueller Gang den ganzen Bereich neu, dabei kamen geloeschte Objekte zurueck und geaenderte wurden ersetzt. **Bereich bearbeiten ueberschreibt nichts**: Nicht-Geometrie-Werte (Belag, Haengeebenen) werden auf alle vorhandenen Kinder uebertragen (`lg-bereich-attribute-uebertragen`), neu berechnet wird nur auf Rueckfrage und mit Vorgabe Ja nur bei Geometrieaenderung (`lg-bereich-geometrie-geaendert-p`). Die Neuberechnung (`lg-bereich-fuellen`) entfernt nur `QUELLE=auto`; ALLE `manuell`/`auto_geaendert`-Objekte des Geschosses (`lg-von-hand-auf-geschoss`) sperren ihre Flaeche - auch in den Randgaengen (`lg-randgang-stuecke`), ein manueller Gang ersetzt den Randgang statt von ihm ueberlagert zu werden. `lg-blockdef` ergaenzt bei Altbestand fehlende ATTDEFs (Neudefinition + `_.ATTSYNC`). `LAGER_EXPORT` schreibt NUR `<dwg>_lager.json` nach `DXFM_RESULTS` (Format `ssg-lager` Version 2, kein Python-Schritt; das RFQ-Projekt uebernimmt Mapping und Hand-Abgleich): alle Geschosse, Bereiche, Reihen und Gaenge mit Attributen und voller Geometrie (Konturpunkte, Start/Ende/Mitte, 4 Ecken) plus `kennwerte` je Geschoss und `lager` gesamt (lichte Hoehe, Regal-/Schienenlaenge, Haengeebenen, Gaenge je Art und Breite, Belags-/Gitterrostflaeche, Gitterkorb, Regalrohr = Laenge x Haengeebenen), je Geschoss-Kennwert `herkunft` (Formel + Quelle). **`null` = fehlt (offener Punkt), nicht Zutreffendes wird weggelassen** (Marker `'ENTFAELLT`, `lg-json-ohne-entfallend`). Plausibilitaetswarnungen je Geschoss (`lg-plausibilitaet`, Grenzwerte aus dem Regelprofil). Das Reihen-Attribut `SCHIENEN` ist entfallen; `SCHIENEN_JE_GANG` am Bereich (Trolley) wird noch nicht ausgewertet. Eigener JSON-Schreiber `lg-json-*` ueber getaggte Werte `(OBJ ...)`/`(ARR ...)` (`lg-json-text` rueckt einLine truncated
| `LagerPruefung.lsp` | LG_REGELN | Regelprofile der Lagerplanung: `cfg/stahlbau/regelwerk/<LAND>.json` laden, `erbt_von` aufloesen (`lg-profil-mischen`), je Regel den STRENGSTEN Wert aller zutreffenden Quellen (`lg-regel-aufloesen`: `art` min/max/wert, `bedingung` gegen einen Kontext - fehlt der Schluessel, konservativ einbezogen -, `tabelle` + `tabellen_schluessel`) mit Protokoll. Jede Pruefregel der Lagerplanung wird genau hier implementiert (Python rendert nur). Alle Startwerte `verifiziert: false` | | `LagerPruefung.lsp` | LG_REGELN | Regelprofile der Lagerplanung: `cfg/stahlbau/regelwerk/<LAND>.json` laden, `erbt_von` aufloesen (`lg-profil-mischen`), je Regel den STRENGSTEN Wert aller zutreffenden Quellen (`lg-regel-aufloesen`: `art` min/max/wert, `bedingung` gegen einen Kontext - fehlt der Schluessel, konservativ einbezogen -, `tabelle` + `tabellen_schluessel`) mit Protokoll. Jede Pruefregel der Lagerplanung wird genau hier implementiert (Python rendert nur). Alle Startwerte `verifiziert: false` |
| `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. | | `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). | | `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). |
+102 -9
View File
@@ -1185,11 +1185,30 @@
) )
) )
) )
;; Randgaenge selbst an den AEUSSEREN Sperrflaechen (manuelle/geaenderte
;; Objekte) beschneiden - ein von Hand gesetzter Gang ersetzt den Randgang
;; dort, wo er liegt, statt von ihm ueberlagert zu werden.
(foreach s rand-str (foreach s rand-str
(setq recs (cons (list "randgang" (cadr s) (caddr s) (cadddr s)) recs))) (foreach st (lg-randgang-stuecke (cadr s) (caddr s) (cadddr s) (lg-param params "sperr" nil) min-g)
(setq recs (cons (list "randgang" (car st) (cadr st) (cadddr s)) recs))))
(list (reverse recs) (- (- ymax oben) y) module) (list (reverse recs) (- (- ymax oben) y) module)
) )
;; Stuecke eines Randgangs (Mittellinie p1-p2, Breite b) ohne die Flaechen
;; der Sperrpolygone (gleiches System). Reiner Kern ueber lg-linie-zuschnitt.
;; Rueckgabe ((q1 q2) ...); ohne Ueberdeckung ((p1 p2)).
(defun lg-randgang-stuecke (p1 p2 b sperr min-g / a l lok st)
(setq a (angle p1 p2) l (distance p1 p2))
(setq lok (mapcar '(lambda (poly)
(ssg-poly-drehen (mapcar '(lambda (q) (list (- (car q) (car p1)) (- (cadr q) (cadr p1)))) poly)
(- a) '(0.0 0.0)))
sperr))
(setq st (if lok (lg-linie-zuschnitt l b lok min-g) 'unveraendert))
(if (eq st 'unveraendert)
(list (list p1 p2))
(mapcar '(lambda (i) (list (polar p1 a (car i)) (polar p1 a (cadr i)))) st))
)
;; Richtung der Reihen als Vorgabe: Winkel der laengsten Konturkante (Grad, ;; Richtung der Reihen als Vorgabe: Winkel der laengsten Konturkante (Grad,
;; auf [0,180) normiert). ;; auf [0,180) normiert).
(defun lg-kontur-richtung (pts / best w l) (defun lg-kontur-richtung (pts / best w l)
@@ -1381,6 +1400,15 @@
(append (lg-alle-bloecke "LG_REIHE_*") (lg-alle-bloecke "LG_GANG_*"))) (append (lg-alle-bloecke "LG_REIHE_*") (lg-alle-bloecke "LG_GANG_*")))
) )
;; Alle von Hand gesetzten oder geaenderten Reihen/Gaenge (QUELLE manuell
;; oder auto_geaendert) des Geschosses gs (String) - gleich welchem Bereich
;; sie gehoeren und wo ihre Mitte liegt. Sie sind Sperre fuer jede Fuellung.
(defun lg-von-hand-auf-geschoss (gs)
(vl-remove-if-not
'(lambda (e) (and (= (cdr (assoc "GESCHOSS" (ssg-attrib-read e))) gs) (lg-von-hand-p e)))
(append (lg-alle-bloecke "LG_REIHE_*") (lg-alle-bloecke "LG_GANG_*")))
)
;; Von Hand gesetzte Reihen/Gaenge (QUELLE manuell) desselben Geschosses, ;; Von Hand gesetzte Reihen/Gaenge (QUELLE manuell) desselben Geschosses,
;; die nicht mit einem Bereich verknuepft sind, aber mit ihrer Mitte in der ;; die nicht mit einem Bereich verknuepft sind, aber mit ihrer Mitte in der
;; Kontur pts liegen (z.B. Altbestand von LG_REIHE vor der Verknuepfung). ;; Kontur pts liegen (z.B. Altbestand von LG_REIHE vor der Verknuepfung).
@@ -1402,8 +1430,8 @@
;; Die automatisch erzeugten Kinder (QUELLE auto) werden vorher entfernt ;; Die automatisch erzeugten Kinder (QUELLE auto) werden vorher entfernt
;; (Sektions-Neuaufbau statt Feld-Splice). Von Hand gesetzte (manuell) und ;; (Sektions-Neuaufbau statt Feld-Splice). Von Hand gesetzte (manuell) und
;; von Hand geaenderte (auto_geaendert) Reihen und Gaenge bleiben stehen und ;; von Hand geaenderte (auto_geaendert) Reihen und Gaenge bleiben stehen und
;; sparen ihre Flaeche aus - ebenso unverknuepfte manuelle Objekte in der ;; sparen ihre Flaeche aus - das gilt fuer alle von-Hand-Objekte des
;; Kontur. Rueckgabe: (reihen gaenge restbreite). ;; Geschosses, auch aus den Randgaengen. Rueckgabe: (reihen gaenge restbreite).
(defun lg-bereich-fuellen (bereich-ent / a kontur pts w pts-l erg z gs (defun lg-bereich-fuellen (bereich-ent / a kontur pts w pts-l erg z gs
n-reihen n-gaenge werte-reihe werte-gang p1 p2 behalten) n-reihen n-gaenge werte-reihe werte-gang p1 p2 behalten)
(setq a (ssg-attrib-read bereich-ent) (setq a (ssg-attrib-read bereich-ent)
@@ -1433,8 +1461,10 @@
(cons "min_gang" (lg-zahl (lg-vorgabe '("bereich" "min_ganglaenge_mm") 100))) (cons "min_gang" (lg-zahl (lg-vorgabe '("bereich" "min_ganglaenge_mm") 100)))
(cons "rand" (lg-bereich-rand a)) (cons "rand" (lg-bereich-rand a))
(cons "richtung" w) (cons "richtung" w)
;; Sperre: ALLE von Hand gesetzten/geaenderten Objekte des
;; Geschosses (auch fremder Bereiche, auch nur teilweise in der Kontur)
(cons "sperr" (mapcar '(lambda (g) (ssg-poly-drehen (lg-linie-polygon g) (- w) '(0.0 0.0))) (cons "sperr" (mapcar '(lambda (g) (ssg-poly-drehen (lg-linie-polygon g) (- w) '(0.0 0.0)))
behalten))))) (lg-von-hand-auf-geschoss (cdr (assoc "GESCHOSS" a))))))))
(setq gs (cdr (assoc "GESCHOSS" a)) n-reihen 0 n-gaenge 0) (setq gs (cdr (assoc "GESCHOSS" a)) n-reihen 0 n-gaenge 0)
(setq werte-reihe (setq werte-reihe
(list (cons "GESCHOSS" gs) (cons "TIEFE_mm" (cdr (assoc "REGALTIEFE_mm" a))) (list (cons "GESCHOSS" gs) (cons "TIEFE_mm" (cdr (assoc "REGALTIEFE_mm" a)))
@@ -1573,11 +1603,13 @@
;; (dx dy) versetzt; in einer 3D-Zeichnung (Konturen auf Belagshoehe) ;; (dx dy) versetzt; in einer 3D-Zeichnung (Konturen auf Belagshoehe)
;; zusaetzlich in Z um den Hoehenabstand. ;; zusaetzlich in Z um den Hoehenabstand.
;; Reiner Kern: Belag eines kopierten Bereichs/Gangs. Entsprach er dem ;; Reiner Kern: Belag eines kopierten Bereichs/Gangs. Ist fuer die Kopie
;; Geschossbelag der Quelle, folgt er dem neuen Geschossbelag; bewusst ;; ein Belag gewaehlt, bekommen ALLE Gaenge und Bereiche ihn - auch von Hand
;; abweichende (z.B. Gitterrost-Gang auf Spanplatte-Buehne) bleiben. ;; gesetzte Rand-/Sondergaenge (sonst blieb der alte Belag stehen). Ohne
;; Wahl (neu leer) bleibt der Belag. alt (Belag der Quelle) wird nicht mehr
;; ausgewertet, bleibt aber fuer die Aufrufer in der Signatur.
(defun lg-kopie-belag (belag alt neu) (defun lg-kopie-belag (belag alt neu)
(if (and belag alt neu (= (strcase belag) (strcase alt))) neu belag) (if (and belag neu (= (type neu) 'STR) (/= neu "")) neu belag)
) )
;; Reiner Kern: Attributwerte einer kopierten Reihe/eines Gangs fuer ;; Reiner Kern: Attributwerte einer kopierten Reihe/eines Gangs fuer
@@ -2186,6 +2218,67 @@
(princ) (princ)
) )
;; ------------------------------------------------------------
;; Bereich bearbeiten: was eingezeichnet ist, wird aktualisiert, nicht
;; ueberschrieben. Nur eine Geometrieaenderung fuehrt (auf Rueckfrage) zur
;; Neuberechnung der automatisch erzeugten Kinder.
;; ------------------------------------------------------------
;; Bereichs-Attribute, deren Aenderung die Lage der Reihen/Gaenge aendert.
(setq *lg-bereich-geometrie-tags*
'("GANGBREITE_mm" "REGALTIEFE_mm" "REIHEN_JE_GANG" "QUERGANG_ABSTAND_mm" "QUERGANG_BREITE_mm"
"RICHTUNG" "RANDGANG_N_mm" "RANDGANG_O_mm" "RANDGANG_S_mm" "RANDGANG_W_mm"))
;; Reiner Kern: T, wenn sich zwischen alt und neu (Attribut-Alists) ein
;; Geometrie-Wert aendert (numerisch verglichen, leer = 0; fehlt ein Tag in
;; neu, gilt er als unveraendert).
(defun lg-bereich-geometrie-geaendert-p (alt neu)
(if (vl-some '(lambda (tag / x y)
(if (lg-wert-fuer-tag tag neu)
(progn
(setq x (cond ((lg-zahl (lg-wert-fuer-tag tag alt))) (0.0))
y (cond ((lg-zahl (lg-wert-fuer-tag tag neu))) (0.0)))
(not (equal x y 1e-6)))))
*lg-bereich-geometrie-tags*)
T)
)
;; Geaenderte Nicht-Geometrie-Werte auf ALLE vorhandenen Kinder des Bereichs
;; uebertragen (QUELLE egal, nichts wird geloescht oder neu gelegt):
;; BELAG -> jeder Gang wird mit dem neuen Belag an derselben Stelle neu
;; aufgebaut (Belag steckt im Blocknamen/der Schraffur), HAENGEEBENEN ->
;; Attribut jeder Reihe. Rueckgabe: Anzahl geaenderter Objekte.
(defun lg-bereich-attribute-uebertragen (ent alt neu / b-alt b-neu e-alt e-neu n ka)
(setq b-alt (lg-wert-fuer-tag "BELAG" alt) b-neu (lg-wert-fuer-tag "BELAG" neu)
e-alt (lg-wert-fuer-tag "HAENGEEBENEN" alt) e-neu (lg-wert-fuer-tag "HAENGEEBENEN" neu)
n 0)
(foreach k (lg-bereich-kinder ent)
(setq ka (ssg-attrib-read k))
(cond
((wcmatch (strcase (lg-blockname k)) "LG_GANG_*")
(if (and b-neu (/= b-neu "") (not (equal b-alt b-neu))
(not (equal (lg-wert-fuer-tag "BELAG" ka) b-neu)))
(if (lg-linie-neu-aufbauen k (lg-wert-setzen ka "BELAG" b-neu)) (setq n (1+ n)))))
((wcmatch (strcase (lg-blockname k)) "LG_REIHE_*")
(if (and e-neu (not (equal e-alt e-neu)))
(progn (lg-attribute-setzen k (list (cons "HAENGEEBENEN" e-neu))) (setq n (1+ n)))))
)
)
n
)
;; Nach dem Bereichsdialog: Werte uebertragen, bei Geometrieaenderung
;; Rueckfrage "neu berechnen?" (Vorgabe Ja; ohne Aenderung Vorgabe Nein -
;; damit laesst sich ein Bereich auch bewusst neu berechnen).
(defun lg-bereich-aktualisieren (ent alt neu / geo n)
(setq n (lg-bereich-attribute-uebertragen ent alt neu)
geo (lg-bereich-geometrie-geaendert-p alt neu))
(if (> n 0) (princ (ssg-textf "lg-bereich-uebertragen" (list (itoa n)))))
(if (ssg-in-yesno (ssg-text "lg-frage-neu-berechnen") geo)
(lg-bereich-fuellen ent)
(lg-darstellung-geschoss (atoi (cond ((cdr (assoc "GESCHOSS" (ssg-attrib-read ent)))) ("0")))))
)
;; Doppelklick-Ziel (SSG_BLOCKEDIT, Zweig LG_*) und Befehl LG_EDIT. ;; Doppelklick-Ziel (SSG_BLOCKEDIT, Zweig LG_*) und Befehl LG_EDIT.
(defun lg-edit-ent (ent / name a neu) (defun lg-edit-ent (ent / name a neu)
(setq name (strcase (lg-blockname ent)) (setq name (strcase (lg-blockname ent))
@@ -2205,7 +2298,7 @@
;; Pfeil des Symbols folgt der Reihenrichtung ;; Pfeil des Symbols folgt der Reihenrichtung
(vla-put-Rotation (vlax-ename->vla-object ent) (vla-put-Rotation (vlax-ename->vla-object ent)
(* (/ (cond ((lg-zahl (cdr (assoc "RICHTUNG" neu)))) (0.0)) 180.0) pi)) (* (/ (cond ((lg-zahl (cdr (assoc "RICHTUNG" neu)))) (0.0)) 180.0) pi))
(lg-bereich-fuellen ent)))) (lg-bereich-aktualisieren ent a neu))))
((wcmatch name "LG_REIHE_*") ((wcmatch name "LG_REIHE_*")
(if (setq neu (lg-dialog "lg_reihe" *lg-felder-reihe* a nil)) (if (setq neu (lg-dialog "lg_reihe" *lg-felder-reihe* a nil))
(progn (progn
+2 -2
View File
@@ -879,11 +879,11 @@ Phase 0 + 1 (Mengen, 2D).
| --- | --- | | --- | --- |
| `c:LG_GESCHOSS` | Belagskontur waehlen/zeichnen, Dialog `lg_geschoss` (`dcl/lager.dcl`), Block `LG_GESCHOSS` + XDATA-Verknuepfung zur Kontur | | `c:LG_GESCHOSS` | Belagskontur waehlen/zeichnen, Dialog `lg_geschoss` (`dcl/lager.dcl`), Block `LG_GESCHOSS` + XDATA-Verknuepfung zur Kontur |
| `c:LG_GESCHOSS_AKTIV` | Aktives Geschoss setzen, Layer `LG_*_G<n>` der anderen Geschosse frieren (0 = alle zeigen) | | `c:LG_GESCHOSS_AKTIV` | Aktives Geschoss setzen, Layer `LG_*_G<n>` der anderen Geschosse frieren (0 = alle zeigen) |
| `c:LG_GESCHOSS_KOPIEREN` | Geschoss mit Belagskontur, Bereichen, Reihen und Gaengen 1:1 in ein oder mehrere neue Geschosse kopieren (Dialog `lg_geschoss_kopie`: Quelle - Vorgabe oberstes Geschoss -, Anzahl, Geschosshoehe je Kopie, Belag, Versatz X/Y je Kopie, 0 = deckungsgleich). Belaege gleich dem Quell-Geschossbelag folgen dem neuen Belag; Verknuepfungen, Layer `_G<n>` und IDs sind neu | | `c:LG_GESCHOSS_KOPIEREN` | Geschoss mit Belagskontur, Bereichen, Reihen und Gaengen 1:1 in ein oder mehrere neue Geschosse kopieren (Dialog `lg_geschoss_kopie`: Quelle - Vorgabe oberstes Geschoss -, Anzahl, Geschosshoehe je Kopie, Belag, Versatz X/Y je Kopie, 0 = deckungsgleich). Alle Gaenge (auch manuelle) bekommen den gewaehlten Belag; Verknuepfungen, Layer `_G<n>` und IDs sind neu |
| `c:LG_BEREICH` | Lagerbereich-Kontur + Dialog `lg_bereich`; Auto-Fuellung mit `LG_REIHE_<L>_<T>` / `LG_GANG_<L>_<B>_<BELAG>`, optional Randgaenge Nord/Ost/Sued/West entlang der Konturkanten (auch L-Form) und Absturzsicherung unter den Reihen (`UNTER_REIHE` gitterrost/gitterkorb/keine, `GITTERKORB_HOEHE_mm`) | | `c:LG_BEREICH` | Lagerbereich-Kontur + Dialog `lg_bereich`; Auto-Fuellung mit `LG_REIHE_<L>_<T>` / `LG_GANG_<L>_<B>_<BELAG>`, optional Randgaenge Nord/Ost/Sued/West entlang der Konturkanten (auch L-Form) und Absturzsicherung unter den Reihen (`UNTER_REIHE` gitterrost/gitterkorb/keine, `GITTERKORB_HOEHE_mm`) |
| `c:LG_REIHE` | Einzelne Regalreihen per Start/Ende oder getippter Laenge; wie bei `LG_GANG` mit dem Bereich verknuepft und ausgeschnitten statt neu berechnet (`lg-manuell-einfuegen`) | | `c:LG_REIHE` | Einzelne Regalreihen per Start/Ende oder getippter Laenge; wie bei `LG_GANG` mit dem Bereich verknuepft und ausgeschnitten statt neu berechnet (`lg-manuell-einfuegen`) |
| `c:LG_GANG` | Einzelne Gaenge (Dialog `lg_gang`: Breite, Art gang/randgang/quergang, Belag), mittig auf der Linie - oder ueber die Option `Rechteck` als Flaeche, gezeichnet mit dem BricsCAD-Befehl RECHTECK samt aller seiner Optionen (Abmessungen, Flaeche, Drehung ...; `lg-rechteck-zeichnen`, Auswertung `lg-rechteck-ecken-aus-poly`, Fase/Rundung wird abgelehnt) (Lage und Breite aus dem Rechteck, laengere Seite = Gangrichtung; Kern `lg-gang-aus-ecken`, `lg-gang-rechteck-einfuegen`, `Linie` schaltet zurueck); liegt die Mitte in einem Bereich, wird der Gang mit ihm verknuepft. Der Gang schneidet seine Flaeche aus den automatisch erzeugten Reihen/Gaengen heraus (`lg-sperre-anwenden`), OHNE den Bereich neu zu berechnen - von Hand geloeschte oder geaenderte Objekte bleiben, wie sie sind; bei jeder Neuberechnung bleibt er stehen (Sperrflaeche) | | `c:LG_GANG` | Einzelne Gaenge (Dialog `lg_gang`: Breite, Art gang/randgang/quergang, Belag), mittig auf der Linie - oder ueber die Option `Rechteck` als Flaeche, gezeichnet mit dem BricsCAD-Befehl RECHTECK samt aller seiner Optionen (Abmessungen, Flaeche, Drehung ...; `lg-rechteck-zeichnen`, Auswertung `lg-rechteck-ecken-aus-poly`, Fase/Rundung wird abgelehnt) (Lage und Breite aus dem Rechteck, laengere Seite = Gangrichtung; Kern `lg-gang-aus-ecken`, `lg-gang-rechteck-einfuegen`, `Linie` schaltet zurueck); liegt die Mitte in einem Bereich, wird der Gang mit ihm verknuepft. Der Gang schneidet seine Flaeche aus den automatisch erzeugten Reihen/Gaengen heraus (`lg-sperre-anwenden`), OHNE den Bereich neu zu berechnen - von Hand geloeschte oder geaenderte Objekte bleiben, wie sie sind; bei jeder Neuberechnung bleibt er stehen (Sperrflaeche) |
| `c:LG_EDIT` | Bearbeiten (auch per Doppelklick ueber `SSG_BLOCKEDIT`, Zweig `LG_*`): Bereich -> Neuberechnung (von Hand eingefuegte und geaenderte Reihen/Gaenge bleiben stehen und werden ausgespart), Reihe/Gang -> Neuaufbau, danach Zuschnitt der rangniedrigeren Objekte (`auto` < `auto_geaendert` < `manuell`, `lg-quelle-rang`) statt Neuberechnung des Bereichs | | `c:LG_EDIT` | Bearbeiten (auch per Doppelklick ueber `SSG_BLOCKEDIT`, Zweig `LG_*`): Bereich -> geaenderter Belag/Haengeebenen werden auf alle vorhandenen Reihen/Gaenge uebertragen, Neuberechnung nur auf Rueckfrage (Vorgabe Ja bei Geometrieaenderung; von Hand eingefuegte und geaenderte Reihen/Gaenge des Geschosses bleiben stehen und werden ausgespart, auch aus den Randgaengen), Reihe/Gang -> Neuaufbau, danach Zuschnitt der rangniedrigeren Objekte (`auto` < `auto_geaendert` < `manuell`, `lg-quelle-rang`) statt Neuberechnung des Bereichs |
| `c:LG_REGALE` | Regalreihen `LG_REIHE_*` zaehlen (`lg-reihe-eintrag` + `lg-reihen-auswerten`): Anzahl, Laenge und Laenge x Haengeebenen je Geschoss plus Gesamtsumme in der Befehlszeile | | `c:LG_REGALE` | Regalreihen `LG_REIHE_*` zaehlen (`lg-reihe-eintrag` + `lg-reihen-auswerten`): Anzahl, Laenge und Laenge x Haengeebenen je Geschoss plus Gesamtsumme in der Befehlszeile |
| `c:LG_DARSTELLUNG` | Darstellung aktualisieren: Farben/Schraffuren aus `lager.json` (`darstellung`, `belag_schraffur`) auf die Reihen-/Gang-Definitionen, Absturzsicherung unter den Reihen aller Geschosse neu zeichnen (Gitterrost/Gitterkorb als Schraffur, Gitterkorb-Abgrenzung nur an offenen Kanten, Layer `LG_Sicherung_G<n>`). Geschieht nach Aenderungen automatisch fuer das betroffene Geschoss | | `c:LG_DARSTELLUNG` | Darstellung aktualisieren: Farben/Schraffuren aus `lager.json` (`darstellung`, `belag_schraffur`) auf die Reihen-/Gang-Definitionen, Absturzsicherung unter den Reihen aller Geschosse neu zeichnen (Gitterrost/Gitterkorb als Schraffur, Gitterkorb-Abgrenzung nur an offenen Kanten, Layer `LG_Sicherung_G<n>`). Geschieht nach Aenderungen automatisch fuer das betroffene Geschoss |
| `c:LAGER_EXPORT` | `<dwg>_lager.json` in `DXFM_RESULTS`: alle Geschosse, Bereiche, Reihen und Gaenge mit Attributen und Geometrie, Kennwerte je Geschoss und gesamt (inkl. Gitterkorb mit offenen Kanten), Herkunft je Kennwert, Warnungen. Kein Python-Schritt | | `c:LAGER_EXPORT` | `<dwg>_lager.json` in `DXFM_RESULTS`: alle Geschosse, Bereiche, Reihen und Gaenge mit Attributen und Geometrie, Kennwerte je Geschoss und gesamt (inkl. Gitterkorb mit offenen Kanten), Herkunft je Kennwert, Warnungen. Kein Python-Schritt |
+22 -8
View File
@@ -145,8 +145,9 @@ Stattdessen entsteht jedes Objekt ueber die normalen Einfuegefunktionen neu:
- Reihen und Gaenge 1:1 aus der Quelle (`lg-linie-einfuegen`). Es wird nicht neu - Reihen und Gaenge 1:1 aus der Quelle (`lg-linie-einfuegen`). Es wird nicht neu
gefuellt, damit Handaenderungen (`auto_geaendert`, manuelle Reihen/Gaenge) erhalten gefuellt, damit Handaenderungen (`auto_geaendert`, manuelle Reihen/Gaenge) erhalten
bleiben. bleiben.
- Belaege, die dem Geschossbelag der Quelle entsprachen, folgen dem neuen Belag, - Ist im Dialog ein Belag gewaehlt, bekommen ALLE Gaenge und Bereiche des neuen
inklusive Schraffur. Bewusst abweichende bleiben. Geschosses ihn, inklusive Schraffur - auch von Hand gesetzte Rand- und
Sondergaenge (`lg-kopie-belag`).
### Auto-Fuellung (`lg-fuellung-berechnen`) ### Auto-Fuellung (`lg-fuellung-berechnen`)
@@ -162,12 +163,25 @@ liegen (konkave Konturen werden korrekt beschnitten). Quergaenge: Luecken der
Breite `QUERGANG_BREITE_mm` nach je `QUERGANG_ABSTAND_mm`, ueber alle Reihen Breite `QUERGANG_BREITE_mm` nach je `QUERGANG_ABSTAND_mm`, ueber alle Reihen
ausgerichtet; keine Luecke am Reihenende, wenn dahinter kein Mindeststueck mehr ausgerichtet; keine Luecke am Reihenende, wenn dahinter kein Mindeststueck mehr
passt. Hauptgaenge laufen durch. Der Rest quer zu den Reihen steht in passt. Hauptgaenge laufen durch. Der Rest quer zu den Reihen steht in
`RESTBREITE_mm`. Edit des Bereichs = Neuaufbau aller Kinder (Sektions-Neuaufbau, `RESTBREITE_mm`.
kein Feld-Splice) - aber nur der automatisch erzeugten (`QUELLE=auto`). Von Hand
eingefuegte (`manuell`) und von Hand geaenderte (`auto_geaendert`) Reihen und Gaenge **Bereich bearbeiten: aktualisieren statt ueberschreiben.** Was eingezeichnet ist,
bleiben stehen und werden ausgespart, ebenso unverknuepfte manuelle Objekte, deren bleibt stehen. Geaenderte Werte ohne Geometrie werden auf ALLE vorhandenen Kinder
Mitte in der Kontur liegt; die Anzahl wird gemeldet. Von Hand geloeschte uebertragen (`lg-bereich-attribute-uebertragen`): `BELAG` -> jeder Gang wird mit dem
automatische Objekte entstehen bei dieser ausdruecklichen Neuberechnung neu. neuen Belag an derselben Stelle neu aufgebaut, `HAENGEEBENEN` -> Attribut jeder
Reihe. Nur wenn sich ein Geometrie-Wert aendert (`lg-bereich-geometrie-geaendert-p`:
Gangbreite, Regaltiefe, Reihen je Gang, Quergaenge, Richtung, Randgang-Breiten),
fragt der Befehl "Bereich neu berechnen?" (Vorgabe Ja; ohne Aenderung Vorgabe
Nein - so laesst sich ein Bereich auch bewusst neu berechnen).
Die Neuberechnung (`lg-bereich-fuellen`) ersetzt nur die automatisch erzeugten
Kinder (`QUELLE=auto`). Sperre sind ALLE von Hand eingefuegten (`manuell`) und
geaenderten (`auto_geaendert`) Reihen und Gaenge des Geschosses
(`lg-von-hand-auf-geschoss`) - auch solche eines anderen Bereichs oder nur
teilweise in der Kontur. Sie werden aus Reihen, Haupt-, Quer- UND Randgaengen
ausgeschnitten (`lg-randgang-stuecke`): ein manueller Gang ersetzt den Randgang
dort, wo er liegt, statt von ihm ueberlagert zu werden. Von Hand geloeschte
automatische Objekte entstehen bei der Neuberechnung neu.
**Randgaenge** (`RANDGANG_N/O/S/W_mm`, Nord = +Y Welt): jede Konturkante bekommt **Randgaenge** (`RANDGANG_N/O/S/W_mm`, Nord = +Y Welt): jede Konturkante bekommt
den Randgang ihrer Himmelsrichtung (Aussennormale, auf N/O/S/W eingerastet, den Randgang ihrer Himmelsrichtung (Aussennormale, auf N/O/S/W eingerastet,
+2
View File
@@ -1280,6 +1280,8 @@
"lg-geaendert": "\nGeaendert.", "lg-geaendert": "\nGeaendert.",
"lg-bereich-ohne-kontur": "\n[Lager] Die Kontur des Bereichs fehlt - Fuellung nicht moeglich.", "lg-bereich-ohne-kontur": "\n[Lager] Die Kontur des Bereichs fehlt - Fuellung nicht moeglich.",
"lg-bereich-beibehalten": "\nBereich %2: %1 von Hand eingefuegte oder geaenderte Reihe(n)/Gaenge bleiben erhalten und werden ausgespart.", "lg-bereich-beibehalten": "\nBereich %2: %1 von Hand eingefuegte oder geaenderte Reihe(n)/Gaenge bleiben erhalten und werden ausgespart.",
"lg-bereich-uebertragen": "\n[Lager] %1 vorhandene Reihe(n)/Gang/Gaenge an die geaenderten Werte angepasst.",
"lg-frage-neu-berechnen": "\nBereich neu berechnen? (automatisch erzeugte Reihen/Gaenge neu legen; von Hand gesetzte und geaenderte bleiben)",
"lg-bereich-gefuellt": "\nBereich %1: %2 Regalreihe(n), %3 Gang-/Quergangflaeche(n), Restbreite %4 mm.", "lg-bereich-gefuellt": "\nBereich %1: %2 Regalreihe(n), %3 Gang-/Quergangflaeche(n), Restbreite %4 mm.",
"lg-prompt-reihe-start": "\nStartpunkt der Regalreihe <Enter = Ende>: ", "lg-prompt-reihe-start": "\nStartpunkt der Regalreihe <Enter = Ende>: ",
"lg-prompt-reihe-ende": "\nEndpunkt oder Laenge (mm): ", "lg-prompt-reihe-ende": "\nEndpunkt oder Laenge (mm): ",
+2
View File
@@ -1280,6 +1280,8 @@
"lg-geaendert": "\nChanged.", "lg-geaendert": "\nChanged.",
"lg-bereich-ohne-kontur": "\n[Storage] The contour of the area is missing - cannot fill.", "lg-bereich-ohne-kontur": "\n[Storage] The contour of the area is missing - cannot fill.",
"lg-bereich-beibehalten": "\nArea %2: %1 manually inserted or changed row(s)/aisle(s) are kept and left out.", "lg-bereich-beibehalten": "\nArea %2: %1 manually inserted or changed row(s)/aisle(s) are kept and left out.",
"lg-bereich-uebertragen": "\n[Storage] %1 existing row(s)/aisle(s) updated to the changed values.",
"lg-frage-neu-berechnen": "\nRecalculate area? (re-create automatically generated rows/aisles; manually placed and modified ones stay)",
"lg-bereich-gefuellt": "\nArea %1: %2 rack row(s), %3 aisle/cross aisle area(s), remaining width %4 mm.", "lg-bereich-gefuellt": "\nArea %1: %2 rack row(s), %3 aisle/cross aisle area(s), remaining width %4 mm.",
"lg-prompt-reihe-start": "\nStart point of the rack row <Enter = finish>: ", "lg-prompt-reihe-start": "\nStart point of the rack row <Enter = finish>: ",
"lg-prompt-reihe-ende": "\nEnd point or length (mm): ", "lg-prompt-reihe-ende": "\nEnd point or length (mm): ",
+38 -3
View File
@@ -100,7 +100,7 @@
(vl-some '(lambda (g) (if (= (ssg-json-get g "nr") nr) g)) (ssg-json-get daten "geschosse"))) (vl-some '(lambda (g) (if (= (ssg-json-get g "nr") nr) g)) (ssg-json-get daten "geschosse")))
(defun lager:tests ( / k0 k1 g0 g1 kb bereich reihen gaenge r0 neu raw daten pfad f eg0 eg1 kr sl (defun lager:tests ( / k0 k1 g0 g1 kb bereich reihen gaenge r0 neu raw daten pfad f eg0 eg1 kr sl
kb2 b2 kinder mg mg2 hg alt eb kb2 b2 kinder mg mg2 hg alt eb mr ba
r1 gg1 n-alt g2 r2 gg2 ids b2k n-kinder bb rg rk zl r1 gg1 n-alt g2 r2 gg2 ids b2k n-kinder bb rg rk zl
b3 rh3 mg3 ge3 ag3 n3 mr3 alt3) b3 rh3 mg3 ge3 ag3 n3 mr3 alt3)
(setvar "CMDECHO" 0) (setvar "CMDECHO" 0)
@@ -244,6 +244,39 @@
(setq mg2 (lg-linie-neu-aufbauen mg (lg-wert-setzen (ssg-attrib-read mg) "BELAG" "spanplatte"))) (setq mg2 (lg-linie-neu-aufbauen mg (lg-wert-setzen (ssg-attrib-read mg) "BELAG" "spanplatte")))
(tlg-eq "manuell: belag geaendert" "LG_GANG_4000_1000_SPANPLATTE" (if mg2 (cdr (assoc 2 (entget mg2))))) (tlg-eq "manuell: belag geaendert" "LG_GANG_4000_1000_SPANPLATTE" (if mg2 (cdr (assoc 2 (entget mg2)))))
(tlg-eq "manuell: bleibt kind" T (if (member mg2 (lg-bereich-kinder b2)) T nil)) (tlg-eq "manuell: bleibt kind" T (if (member mg2 (lg-bereich-kinder b2)) T nil))
;; Manueller Gang IM Nord-Randgang: Neuberechnung legt keinen Randgang darueber
(setq mr (lg-gang-einfuegen '(21000.0 5500.0 0.0) '(23000.0 5500.0 0.0)
(list (cons "GESCHOSS" "1") (cons "BREITE_mm" "1000") (cons "ART" "randgang")
(cons "BELAG" "gitterrost"))))
(lg-bereich-fuellen b2)
(tlg-eq "randgang: manueller bleibt" T (if (entget mr) T nil))
(tlg-eq "randgang: kein ueberlappender auto-randgang" nil
(vl-some '(lambda (k / bb)
(setq bb (ssg-poly-bbox (lg-linie-polygon k)))
(if (and (= (tlg-attr k "QUELLE") "auto")
(> (- (min (car (cadr bb)) 23000.0) (max (car (car bb)) 21000.0)) 1.0)
(> (- (min (cadr (cadr bb)) 6000.0) (max (cadr (car bb)) 5000.0)) 1.0))
k))
(tlg-nur (lg-bereich-kinder b2) "LG_GANG_*")))
(tlg-eq "randgang: nord ausgespart (2 stuecke + sued)" 3
(tlg-anzahl-art (vl-remove-if-not '(lambda (k) (= (tlg-attr k "QUELLE") "auto")) (lg-bereich-kinder b2))
"randgang"))
;; Belag des Bereichs aendern: vorhandene Gaenge werden umgestellt, nichts neu gelegt
(setq ba (ssg-attrib-read b2) n-kinder (length (lg-bereich-kinder b2)))
(tlg-eq "uebertragen: geaendert" T
(> (lg-bereich-attribute-uebertragen b2 ba (lg-wert-setzen ba "BELAG" "gitterrost")) 0))
(setq kinder (lg-bereich-kinder b2))
(tlg-eq "uebertragen: anzahl gleich" n-kinder (length kinder))
(tlg-eq "uebertragen: alle gitterrost" (length (tlg-nur kinder "LG_GANG_*"))
(tlg-anzahl-attr (tlg-nur kinder "LG_GANG_*") "BELAG" "gitterrost"))
(tlg-eq "uebertragen: manuell bleibt manuell" 2 (tlg-anzahl-attr kinder "QUELLE" "manuell"))
;; Zustand fuer die folgenden Tests wiederherstellen
(lg-bereich-attribute-uebertragen b2 (lg-wert-setzen ba "BELAG" "gitterrost") ba)
(tlg-eq "uebertragen: zurueck auf spanplatte" 0
(tlg-anzahl-attr (tlg-nur (lg-bereich-kinder b2) "LG_GANG_*") "BELAG" "gitterrost"))
(entdel (vl-some '(lambda (k) (if (wcmatch (cdr (assoc 2 (entget k))) "LG_GANG_2000_1000_*") k))
(lg-bereich-kinder b2)))
(lg-bereich-fuellen b2)
;; Hallenboden: keine Schraffur; ausserhalb jedes Bereichs: nicht verknuepft ;; Hallenboden: keine Schraffur; ausserhalb jedes Bereichs: nicht verknuepft
(setq hg (lg-gang-einfuegen '(40000.0 0.0 0.0) '(42000.0 0.0 0.0) (setq hg (lg-gang-einfuegen '(40000.0 0.0 0.0) '(42000.0 0.0 0.0)
(list (cons "GESCHOSS" "1") (cons "BREITE_mm" "1500") (cons "ART" "gang") (list (cons "GESCHOSS" "1") (cons "BREITE_mm" "1500") (cons "ART" "gang")
@@ -362,12 +395,14 @@
(setq nr (tlg-attr b "NR")) (setq nr (tlg-attr b "NR"))
(vl-every '(lambda (k) (= (tlg-attr k "BEREICH") nr)) (lg-bereich-kinder b))) (vl-every '(lambda (k) (= (tlg-attr k "BEREICH") nr)) (lg-bereich-kinder b)))
(tlg-gs "LG_BEREICH" 2))) (tlg-gs "LG_BEREICH" 2)))
;; Belag folgt dem Geschoss (Spanplatte -> Gitterrost), Hallenboden-Gang bleibt ;; ALLE Gaenge bekommen den gewaehlten Belag (Gitterrost) - auch manuelle
;; und der Hallenboden-Gang
(tlg-eq "kopie: belag folgt" 0 (tlg-anzahl-attr gg2 "BELAG" "spanplatte")) (tlg-eq "kopie: belag folgt" 0 (tlg-anzahl-attr gg2 "BELAG" "spanplatte"))
(tlg-eq "kopie: alle gaenge neuer belag" (length gg2) (tlg-anzahl-attr gg2 "BELAG" "gitterrost"))
(tlg-eq "kopie: manueller gang gitterrost" 1 (tlg-eq "kopie: manueller gang gitterrost" 1
(length (tlg-nur (vl-remove-if-not '(lambda (e) (= (tlg-attr e "QUELLE") "manuell")) gg2) (length (tlg-nur (vl-remove-if-not '(lambda (e) (= (tlg-attr e "QUELLE") "manuell")) gg2)
"LG_GANG_4000_1000_GITTERROST"))) "LG_GANG_4000_1000_GITTERROST")))
(tlg-eq "kopie: hallenboden bleibt" 1 (length (tlg-nur gg2 "LG_GANG_2000_1500_HALLENBODEN"))) (tlg-eq "kopie: hallenboden-gang folgt" 1 (length (tlg-nur gg2 "LG_GANG_2000_1500_GITTERROST")))
(tlg-eq "kopie: bereich belag" T (tlg-eq "kopie: bereich belag" T
(vl-every '(lambda (b) (= (tlg-attr b "BELAG") "gitterrost")) (tlg-gs "LG_BEREICH" 2))) (vl-every '(lambda (b) (= (tlg-attr b "BELAG") "gitterrost")) (tlg-gs "LG_BEREICH" 2)))
(tlg-eq "kopie: unter_reihe gitterkorb" 1 (tlg-anzahl-attr (tlg-gs "LG_BEREICH" 2) "UNTER_REIHE" "gitterkorb")) (tlg-eq "kopie: unter_reihe gitterkorb" 1 (tlg-anzahl-attr (tlg-gs "LG_BEREICH" 2) "UNTER_REIHE" "gitterkorb"))
+30 -1
View File
@@ -3312,9 +3312,38 @@
;; --- Geschoss kopieren --- ;; --- Geschoss kopieren ---
(setq _kand2 (list (list 1 0.0 _sq0) (list 2 3100.0 _sq0))) (setq _kand2 (list (list 1 0.0 _sq0) (list 2 3100.0 _sq0)))
;; Kopie: ALLE Gaenge bekommen den gewaehlten Belag, auch abweichende
(tu-eq "lg-kopie-belag/folgt" "spanplatte" (lg-kopie-belag "hallenboden" "hallenboden" "spanplatte")) (tu-eq "lg-kopie-belag/folgt" "spanplatte" (lg-kopie-belag "hallenboden" "hallenboden" "spanplatte"))
(tu-eq "lg-kopie-belag/eigen" "gitterrost" (lg-kopie-belag "gitterrost" "hallenboden" "spanplatte")) (tu-eq "lg-kopie-belag/eigen" "spanplatte" (lg-kopie-belag "gitterrost" "hallenboden" "spanplatte"))
(tu-eq "lg-kopie-belag/ohne-wahl" "gitterrost" (lg-kopie-belag "gitterrost" "hallenboden" ""))
(tu-nil "lg-kopie-belag/nil" (lg-kopie-belag nil "hallenboden" "spanplatte")) (tu-nil "lg-kopie-belag/nil" (lg-kopie-belag nil "hallenboden" "spanplatte"))
;; Randgang an Sperrflaechen (manueller Gang) beschnitten
(tu-eqf "lg-randgang-stuecke/geteilt"
'(((0.0 5800.0) (4000.0 5800.0)) ((5000.0 5800.0) (10000.0 5800.0)))
(lg-randgang-stuecke '(0.0 5800.0) '(10000.0 5800.0) 400.0
'(((4000.0 5500.0) (5000.0 5500.0) (5000.0 6000.0) (4000.0 6000.0))) 100.0))
(tu-eqf "lg-randgang-stuecke/frei" '(((0.0 5800.0) (10000.0 5800.0)))
(lg-randgang-stuecke '(0.0 5800.0) '(10000.0 5800.0) 400.0 nil 100.0))
(tu-nil "lg-randgang-stuecke/ganz-ueberdeckt"
(lg-randgang-stuecke '(0.0 5800.0) '(10000.0 5800.0) 400.0
'(((-10.0 5500.0) (10010.0 5500.0) (10010.0 6000.0) (-10.0 6000.0))) 100.0))
(setq _fr (lg-fuellung-berechnen '((0.0 0.0) (10000.0 0.0) (10000.0 6000.0) (0.0 6000.0))
(list (cons "rand" '(("N" . 1000.0) ("O" . 0.0) ("S" . 0.0) ("W" . 0.0)))
(cons "sperr" '(((4000.0 5000.0) (5000.0 5000.0) (5000.0 6000.0) (4000.0 6000.0)))))))
(tu-eq "lg-fuellung/randgang-ausgespart" 2
(length (vl-remove-if-not '(lambda (r) (= (car r) "randgang")) (car _fr))))
;; Bereich bearbeiten: nur Geometrie fuehrt zur Neuberechnung
(setq _ba '(("GANGBREITE_mm" . "1000") ("REGALTIEFE_mm" . "700") ("BELAG" . "spanplatte")
("HAENGEEBENEN" . "2300/1200") ("RANDGANG_N_mm" . "0")))
(tu-nil "lg-bereich-geometrie/belag"
(lg-bereich-geometrie-geaendert-p _ba (lg-wert-setzen (lg-wert-setzen _ba "BELAG" "gitterrost")
"HAENGEEBENEN" "2400/1000")))
(tu-nil "lg-bereich-geometrie/gleich-zahl"
(lg-bereich-geometrie-geaendert-p _ba (lg-wert-setzen _ba "GANGBREITE_mm" "1000.0")))
(tu-eq "lg-bereich-geometrie/gangbreite" T
(lg-bereich-geometrie-geaendert-p _ba (lg-wert-setzen _ba "GANGBREITE_mm" "1200")))
(tu-eq "lg-bereich-geometrie/randgang" T
(lg-bereich-geometrie-geaendert-p _ba (lg-wert-setzen _ba "RANDGANG_N_mm" "1600")))
(setq _w (lg-kopie-werte '(("ID" . "2A") ("GESCHOSS" . "1") ("LAYER" . "LG_Gang_G1") ("LAENGE" . "9000") (setq _w (lg-kopie-werte '(("ID" . "2A") ("GESCHOSS" . "1") ("LAYER" . "LG_Gang_G1") ("LAENGE" . "9000")
("BREITE_mm" . "1000") ("ART" . "gang") ("BELAG" . "hallenboden") ("BREITE_mm" . "1000") ("ART" . "gang") ("BELAG" . "hallenboden")
("BEREICH" . "3") ("QUELLE" . "manuell")) ("BEREICH" . "3") ("QUELLE" . "manuell"))