Oeffnungen-Sublayer + Sturzlinien + Referenz-Layer + Pill-Inputs + Anordnen-Pill

- Oeffnungen-Subtree (Rahmen/Glas/Tuerblatt/Sims/Pane/Schwung/Sturz) als
  nested Children unter WAENDE im dossier_ebenen-Tree registriert + per-Kind
  Material (Glas mit Transparenz)
- Sturzlinien bei 1:100 Tueren mit Innen/Aussen/Beide/Keine-Dropdown
- Referenzlinien-Layer (19) als eigene Ebene fuer wand_axis + oeffnung_point
- Swisstopo Patch-Terrain (Brep.CreatePatch) ersetzt das falsche Loft
- Pill-Style fuer alle Inputs zentral via index.css
- 2x2 Anordnen-Pill in der Oberleiste (BringToFront/Forward/Backward/SendToBack
  via Rhinos DisplayOrder, kein Z-Offset)
- Chevron-Verschiebung in Ebenen-Panel ohne dass Siblings shiften
- Fix: _update_ebene_field walked nur Top-Level, nested Sublayer-Style-
  Changes wurden nicht persistiert
- Fix: Sturz-Linetype wurde bei jedem Wand-Regen zurueckgesetzt

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-23 16:07:44 +02:00
parent 3dc6e31374
commit 3277f61ced
12 changed files with 803 additions and 80 deletions
+65
View File
@@ -844,6 +844,71 @@ def generate_schichtenmodell(doc, contour_curves, progress=None):
return created
def generate_patch_from_contours(doc, contour_curves, progress=None):
"""Erzeugt eine NURBS-Patch-Flaeche durch alle Hoehenlinien — der
kanonische Rhino-Workflow fuer Terrain aus Konturen (Brep.CreatePatch
fittet eine Surface durch Curves + Points). Loft funktioniert hier
nicht, weil benachbarte Konturen unterschiedliche Topologie haben
(Inseln, Halbinseln, geschlossen vs. offen am Rand).
UV-Spans werden aus dem Bounding-Box-Aspect-Ratio abgeleitet, so
dass ein rechteckiger Site mehr Spans in der laengeren Richtung
bekommt.
Liefert das erstellte RhinoObject oder None."""
import System
if not contour_curves: return None
valid = [c for c in contour_curves if c is not None]
if len(valid) < 2:
if progress: progress("Patch braucht mindestens 2 Hoehenlinien")
return None
bb = rg.BoundingBox.Unset
for c in valid:
bb_c = c.GetBoundingBox(True)
if not bb_c.IsValid: continue
if not bb.IsValid:
bb = bb_c
else:
bb.Union(bb_c)
if not bb.IsValid:
if progress: progress("Patch: ungueltige Bounding-Box")
return None
dx = bb.Max.X - bb.Min.X
dy = bb.Max.Y - bb.Min.Y
base_span = 40
if dx >= dy and dy > 1e-6:
aspect = dx / dy
u_spans = int(round(base_span * math.sqrt(aspect)))
v_spans = base_span
elif dx > 1e-6:
aspect = dy / dx
u_spans = base_span
v_spans = int(round(base_span * math.sqrt(aspect)))
else:
u_spans = v_spans = base_span
u_spans = max(8, min(200, u_spans))
v_spans = max(8, min(200, v_spans))
if progress:
progress("Patch aus {} Hoehenlinien ({}x{} UV-Spans)...".format(
len(valid), u_spans, v_spans))
geom_list = System.Collections.Generic.List[rg.GeometryBase]()
for c in valid: geom_list.Add(c)
try:
brep = rg.Brep.CreatePatch(
geom_list, u_spans, v_spans, doc.ModelAbsoluteTolerance)
if brep is None:
if progress: progress("Patch fehlgeschlagen (None zurueck)")
return None
gid = doc.Objects.AddBrep(brep)
if gid and gid != System.Guid.Empty:
obj = doc.Objects.Find(gid)
if progress: progress("→ Patch-Terrain erzeugt")
return obj
except Exception as ex:
if progress: progress("Patch-Fehler: {}".format(ex))
return None
def generate_contour_curves(grid, shift_lv95, m_to_unit, interval=2.0,
progress=None):
"""Generiert Hoehenlinien (Contour-Curves) aus dem Terrain-Grid via