From 1c3b0f3919351090074e1a776c4af894fa17299b Mon Sep 17 00:00:00 2001 From: karim Date: Wed, 27 May 2026 01:00:33 +0200 Subject: [PATCH] =?UTF-8?q?Ebenen:=20Plangrafik=2060=20=E2=86=92=2080,=20R?= =?UTF-8?q?AEUME/GF/AGF=20auf=2060/61/62?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Doppelbelegung Code 60: alte Konvention "Plangrafik" steht im Weg fuer die neuen Raum-Layer (RAEUME 60, GF 61, AGF 62). Wenn ein Doc beides hat, fiel die Auto-Add-Logik in _find_ebene_sublayer_name aus → Raeume landeten auf Rhino-Layer "60_RAEUME" der aber im Dossier-Ebenen-Panel nie auftauchte (dort stand 60 = Plangrafik). Fix in zwei Teilen: 1) Frontend-Default-Schema (App.jsx INITIAL_EBENEN): - 60: RAEUME (neu, fuer HNF/NNF/VF/FF) - 61: GF (Geschossflaeche) - 62: AGF (Aussengeschossflaeche) - 80: Plangrafik (verschoben von 60) 2) One-shot Migration in elemente._migrate_plangrafik_60_to_80_once(): - Detect: dossier_ebenen hat code=60 + name=Plangrafik - Action: code 60 → 80, RAEUME/GF/AGF auf 60/61/62 hinzufuegen - Rhino-Layer rename: alle "60_Plangrafik" Layer → "80_Plangrafik" - build_layers + broadcast_state → Ebenen-Manager UI aktualisiert - Sticky-Flag verhindert Re-Run Plus kleinerer UX-Fix: Skala-Dropdown-Labels gekuerzt ("fix (m)" / "massstaeblich (mm)" statt langer Beschreibungen). --- rhino/elemente.py | 98 +++++++++++++++++++++++++++++++++++++++++++++ src/App.jsx | 8 +++- src/ElementeApp.jsx | 8 +++- 3 files changed, 111 insertions(+), 3 deletions(-) diff --git a/rhino/elemente.py b/rhino/elemente.py index 04bb32e..ee81d55 100644 --- a/rhino/elemente.py +++ b/rhino/elemente.py @@ -297,6 +297,7 @@ _KEY_RAUM_TXT_H = "dossier_raum_txt_h" # Texthoehe in m _KEY_RAUM_ALIGN = "dossier_raum_align" # "links"|"mid"|"rechts" _KEY_RAUM_SIA = "dossier_raum_sia" # "" | "hnf" | "nnf" | "vf" | "ff" _KEY_RAUM_FUELL = "dossier_raum_fuellung" # "" (keine) | "Solid" | Pattern-Name | "ByLayer" +_KEY_RAUM_PERSONEN = "dossier_raum_personen" # int — Anzahl Personen (SIA Personen-Belegung) # Stempel-Typografie (per-Raum-Override) — leer = Doc-Default-Font, Defaults siehe _read_meta _KEY_RAUM_TXT_FONT = "dossier_raum_txt_font" # Font-Quartet-Name (z.B. "DM Mono", "Helvetica") _KEY_RAUM_TXT_BOLD = "dossier_raum_txt_bold" # "0"|"1" @@ -2707,6 +2708,7 @@ def _attach_meta(obj_attrs, wall_id, type_, geschoss, dicke, uk_over, ok_over, raum_name=None, raum_nummer=None, raum_funktion=None, raum_rundung=None, raum_txt_h=None, raum_align=None, raum_sia=None, raum_fuellung=None, + raum_personen=None, raum_txt_font=None, raum_txt_bold=None, raum_txt_italic=None, raum_show_nummer=None, raum_show_name=None, raum_show_funktion=None, raum_show_area=None, @@ -2886,6 +2888,12 @@ def _attach_meta(obj_attrs, wall_id, type_, geschoss, dicke, uk_over, ok_over, else: v = str(raum_fuellung) obj_attrs.SetUserString(_KEY_RAUM_FUELL, v) + if raum_personen is not None: + try: + n = int(raum_personen) + if n < 0: n = 0 + obj_attrs.SetUserString(_KEY_RAUM_PERSONEN, str(n)) + except Exception: pass # Stempel-Typografie + Sichtbarkeit (per-Raum-Override) if raum_txt_font is not None: obj_attrs.SetUserString(_KEY_RAUM_TXT_FONT, str(raum_txt_font)) @@ -3136,6 +3144,10 @@ def _read_meta(obj): if r_fuell_raw == "1": r_fuell = "Solid" elif r_fuell_raw == "0": r_fuell = "" else: r_fuell = r_fuell_raw or "" + # Personen-Belegung (int, default 0 = nicht erfasst) + try: r_personen = int(a.GetUserString(_KEY_RAUM_PERSONEN) or "0") + except Exception: r_personen = 0 + if r_personen < 0: r_personen = 0 # Stempel-Typografie (Defaults: leer = Doc-Default-Font, bold/italic off) r_font = a.GetUserString(_KEY_RAUM_TXT_FONT) or "" r_bold = (a.GetUserString(_KEY_RAUM_TXT_BOLD) == "1") @@ -12518,6 +12530,89 @@ def _sync_orphan_grips(doc): sc.sticky[_SELECT_BUSY] = False +def _migrate_plangrafik_60_to_80_once(doc): + """One-shot pro Doc: alte Ebenen-Konvention 'code 60 = Plangrafik' + auf neue Konvention umstellen (60 ist jetzt RAEUME, Plangrafik wandert + auf 80). Konkret: + - dossier_ebenen JSON: code '60'+name 'Plangrafik' → code '80' + - Rhino-Layer 'EG::60_Plangrafik' → '80_Plangrafik' (ueber alle + Geschosse) + Sticky-Flag verhindert Re-Run pro Doc-Session.""" + if doc is None: return + try: key = "_dossier_plangrafik_migration_" + str(doc.RuntimeSerialNumber) + except Exception: key = "_dossier_plangrafik_migration_default" + if sc.sticky.get(key): return + sc.sticky[key] = True + raw = doc.Strings.GetValue("dossier_ebenen") + if not raw: return + try: + ebenen = json.loads(raw) + except Exception: return + if not isinstance(ebenen, list): return + changed = False + for e in ebenen: + if not isinstance(e, dict): continue + if e.get("code") == "60" and (e.get("name") or "").lower() == "plangrafik": + print("[ELEMENTE] Migration: Plangrafik von Code 60 → 80") + e["code"] = "80" + changed = True + break + # RAEUME / GF / AGF proaktiv eintragen wenn noch nicht vorhanden — damit + # sie im Ebenen-Manager sichtbar sind ohne erst einen Raum erstellen zu + # muessen. + existing_codes = {e.get("code") for e in ebenen if isinstance(e, dict)} + raum_defaults = [ + ("60", "RAEUME", "#7a8a9a", 0.13), + ("61", "GF", "#a0a0a0", 0.18), + ("62", "AGF", "#90b090", 0.13), + ] + for code, name, color, lw in raum_defaults: + if code not in existing_codes: + ebenen.append({ + "code": code, "name": name, + "color": color, "lw": lw, + "visible": True, "locked": False, + }) + print("[ELEMENTE] Migration: Ebene '{}_{}' hinzugefuegt".format( + code, name)) + changed = True + if not changed: return + # Speichern + Rhino-Layer umbenennen + try: + doc.Strings.SetString("dossier_ebenen", + json.dumps(ebenen, ensure_ascii=False)) + except Exception as ex: + print("[ELEMENTE] Plangrafik-Migration save:", ex) + return + # Rhino-Layer umbenennen: ::60_Plangrafik → 80_Plangrafik + n_renamed = 0 + try: + for layer in list(doc.Layers): + try: + if layer.IsDeleted: continue + if layer.Name == "60_Plangrafik": + layer.Name = "80_Plangrafik" + n_renamed += 1 + except Exception: pass + except Exception as ex: + print("[ELEMENTE] Plangrafik-Migration rename:", ex) + if n_renamed > 0: + print("[ELEMENTE] {} Rhino-Layer 60_Plangrafik → 80_Plangrafik umbenannt".format( + n_renamed)) + # build_layers + broadcast damit Ebenen-Manager UI nachzieht + try: + import layer_builder as _lb + z_raw = doc.Strings.GetValue("dossier_zeichnungsebenen") + zlist = json.loads(z_raw) if z_raw else [] + if zlist: _lb.build_layers(doc, zlist, ebenen) + except Exception as ex: + print("[ELEMENTE] build_layers nach Plangrafik-Migration:", ex) + try: + import rhinopanel as _rp + _rp._broadcast_state(doc) + except Exception: pass + + def _migrate_referenz_layer_once(doc): """One-shot pro Doc-Session: wand_axis + oeffnung_point auf den neuen Referenzlinien-Sublayer migrieren, und alle versehentlich @@ -12683,6 +12778,9 @@ def _on_idle_selection(sender, e): # versteckten wieder zeigen (Cleanup nach der abgebrochenen # Hide-on-Select-Implementation). _migrate_referenz_layer_once(doc) + # One-shot: Plangrafik von Code 60 auf 80 umziehen (Code 60 ist jetzt + # fuer RAEUME reserviert) + _migrate_plangrafik_60_to_80_once(doc) # Oeffnungen-Tree in dossier_ebenen anlegen falls noch nicht vorhanden # (sonst erscheinen die neuen Sublayer nicht im Ebenen-Panel). _ensure_oeff_ebenen_once(doc) diff --git a/src/App.jsx b/src/App.jsx index 2422db4..bb35abd 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -23,7 +23,13 @@ const INITIAL_EBENEN = [ { code: '31', name: 'Dächer', color: '#7a4a3a', lw: 0.35, visible: true, locked: false }, { code: '35', name: 'Träger', color: '#a87858', lw: 0.50, visible: true, locked: false }, { code: '50', name: 'Text', color: '#d0d0d0', lw: 0.13, visible: true, locked: false }, - { code: '60', name: 'Plangrafik', color: '#c0a040', lw: 0.13, visible: true, locked: false }, + // Raum-Familie: RAEUME (Nutzflaechen HNF/NNF/VF/FF) + GF (Geschossflaeche + // gross) + AGF (Aussengeschossflaeche). Wird vom Elemente-Modul auto- + // erzeugt sobald der erste Raum mit entsprechendem SIA-Tag entsteht. + { code: '60', name: 'RAEUME', color: '#7a8a9a', lw: 0.13, visible: true, locked: false }, + { code: '61', name: 'GF', color: '#a0a0a0', lw: 0.18, visible: true, locked: false }, + { code: '62', name: 'AGF', color: '#90b090', lw: 0.13, visible: true, locked: false }, + { code: '80', name: 'Plangrafik', color: '#c0a040', lw: 0.13, visible: true, locked: false }, { code: '90', name: 'Referenzen', color: '#585860', lw: 0.13, visible: true, locked: false }, { code: '99', name: 'Konstruktion', color: '#404048', lw: 0.13, visible: true, locked: false }, ] diff --git a/src/ElementeApp.jsx b/src/ElementeApp.jsx index 6c4f3e9..9991548 100644 --- a/src/ElementeApp.jsx +++ b/src/ElementeApp.jsx @@ -1109,8 +1109,12 @@ function RaumProperties({ raum, geschosse, onUpdate, onDelete, hatchPatterns, fo onChange={(e) => onUpdate({ txtModus: e.target.value })} title="fix: Hoehe in m via Oberleiste · masstab: Paper-mm via Massstab" style={{ flex: 1, fontSize: 11 }}> - - + +