Vorschau-Quader fuer Fenster/Tuer + Launcher reinweiss + SectionStyle-Apply gehaertet
Elemente: - _make_oeffnung_preview baut jetzt einen vollen 3D-Quader (12 Kanten) mit Wand-Dicke statt nur einer 2D-Flaeche. Glas-Diagonalen auf Vorder- und Hinterflaeche, Brueest-Linie (gepunktet) auf der Vorderflaeche, Achs- Marker auf der Wand-Achse, dazu ein 3D-Mass-Label "B x H Br" ueberm Sturz (zentriert, an der Wand "geheftet"). Aktualisiert live bei Option-Aenderungen. Launcher: - Paper-Theme zu reinem Weiss umgestellt (User-Feedback "zu warm"): --bg #ffffff, --dark #f0f0f0, neutrale Greys statt Sand-Tones, Schatten ohne warmen Braun-Stich. Petrol-Radial-Gradient oben raus. - latest.json aus dem neuen Release-Build. SectionStyle (Bug-Hunt — Hatch/Boundary haben nicht gegriffen): - *Source-Properties (HatchColorSource, BoundaryColorSource, BoundaryLinetypeSource) jetzt explizit auf ColorFromObject / LinetypeFromObject — sonst hat Rhino die eigenen Color/Linetype- Werte ignoriert (Default ist ByLayer). - doc.Layers.Modify nach SetCustomSectionStyle, sonst persistiert Mac Rhino den Custom-Style nicht zuverlaessig. - Helper _try_set + _enum_int eliminieren das 8x duplizierte Property-Probe-Pattern. - Property-Inventar wird einmal pro Session gedumpt (verfuegbare SectionStyle-Felder) damit API-Mismatches sichtbar werden. - Per-Layer Apply-Logs zeigen welche Properties via welchem Namen gesetzt wurden — leicht debuggbar im Mismatch-Fall. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+80
-23
@@ -503,13 +503,19 @@ def _make_circle_preview(center):
|
||||
return handler
|
||||
|
||||
|
||||
def _make_oeffnung_preview(axis_curve, breite, hoehe, brueest, base_z):
|
||||
"""Preview fuer Fenster/Tuer-Platzierung. Zeigt das vertikale Rechteck
|
||||
der Oeffnungsflaeche auf Hoehe der Achse (entlang Tangente x Hoehe),
|
||||
zusaetzlich eine Marker-Linie auf der Achse die die Breite andeutet."""
|
||||
def _make_oeffnung_preview(axis_curve, wall_dicke, breite, hoehe, brueest, base_z, typ):
|
||||
"""Preview fuer Fenster/Tuer-Platzierung. Zeigt:
|
||||
- Voller 3D-Quader des Oeffnungs-Cutouts (mit Wand-Dicke)
|
||||
- Glas-Diagonalen auf Vorder- und Hinterflaeche
|
||||
- Brueestungs-Markierung (gepunktet) bei Fenster mit Brueest > 0
|
||||
- Achs-Marker (Strich auf der Wand-Achse)
|
||||
- Mass-Label oberhalb des Sturzes (B x H, ggf. Brueest)
|
||||
Aktualisiert sich live wenn User Optionen aendert."""
|
||||
import System.Drawing as SD
|
||||
color = SD.Color.FromArgb(255, 95, 200, 180) # Accent gruen
|
||||
color_axis = SD.Color.FromArgb(180, 95, 200, 180) # halbtransparent
|
||||
color_main = SD.Color.FromArgb(255, 95, 200, 180) # Accent gruen, voll
|
||||
color_soft = SD.Color.FromArgb(160, 95, 200, 180) # halbtransparent
|
||||
color_dotted = SD.Color.FromArgb(210, 95, 200, 180) # Brueest-/Achs-Marker
|
||||
hd = wall_dicke * 0.5
|
||||
def handler(sender, e):
|
||||
try:
|
||||
cur = e.CurrentPoint
|
||||
@@ -520,25 +526,70 @@ def _make_oeffnung_preview(axis_curve, breite, hoehe, brueest, base_z):
|
||||
tlen = (tan.X * tan.X + tan.Y * tan.Y) ** 0.5
|
||||
if tlen < 1e-9: return
|
||||
tx = tan.X / tlen; ty = tan.Y / tlen
|
||||
# Normale zur Tangente in XY (90deg gegen Uhrzeigersinn)
|
||||
nx, ny = -ty, tx
|
||||
hb = breite * 0.5
|
||||
z_bot = base_z + brueest
|
||||
z_top = z_bot + hoehe
|
||||
cx, cy = on_axis.X, on_axis.Y
|
||||
# Breiten-Marker auf der Achse
|
||||
left_xy = rg.Point3d(cx - hb * tx, cy - hb * ty, on_axis.Z)
|
||||
right_xy = rg.Point3d(cx + hb * tx, cy + hb * ty, on_axis.Z)
|
||||
e.Display.DrawLine(left_xy, right_xy, color_axis, 1)
|
||||
# 4 Kanten der vertikalen Oeffnungs-Flaeche
|
||||
p_lb = rg.Point3d(cx - hb * tx, cy - hb * ty, z_bot)
|
||||
p_rb = rg.Point3d(cx + hb * tx, cy + hb * ty, z_bot)
|
||||
p_rt = rg.Point3d(cx + hb * tx, cy + hb * ty, z_top)
|
||||
p_lt = rg.Point3d(cx - hb * tx, cy - hb * ty, z_top)
|
||||
for a, b in ((p_lb, p_rb), (p_rb, p_rt),
|
||||
(p_rt, p_lt), (p_lt, p_lb)):
|
||||
e.Display.DrawLine(a, b, color, 2)
|
||||
# Diagonalen — Andeutung der Glasflaeche
|
||||
e.Display.DrawLine(p_lb, p_rt, color_axis, 1)
|
||||
e.Display.DrawLine(p_lt, p_rb, color_axis, 1)
|
||||
|
||||
# 8 Ecken des Quaders. side_t = ±1 (links/rechts entlang Tangente),
|
||||
# side_n = ±1 (vorne/hinten entlang Normale)
|
||||
def pt(side_t, side_n, z):
|
||||
return rg.Point3d(
|
||||
cx + side_t * hb * tx + side_n * hd * nx,
|
||||
cy + side_t * hb * ty + side_n * hd * ny,
|
||||
z)
|
||||
|
||||
lbf = pt(-1, +1, z_bot); rbf = pt(+1, +1, z_bot)
|
||||
rtf = pt(+1, +1, z_top); ltf = pt(-1, +1, z_top)
|
||||
lbb = pt(-1, -1, z_bot); rbb = pt(+1, -1, z_bot)
|
||||
rtb = pt(+1, -1, z_top); ltb = pt(-1, -1, z_top)
|
||||
|
||||
# 12 Quader-Kanten
|
||||
for a, b in (
|
||||
(lbf, rbf), (rbf, rtf), (rtf, ltf), (ltf, lbf), # vorne
|
||||
(lbb, rbb), (rbb, rtb), (rtb, ltb), (ltb, lbb), # hinten
|
||||
(lbf, lbb), (rbf, rbb), (rtf, rtb), (ltf, ltb), # Tiefen-Kanten
|
||||
):
|
||||
e.Display.DrawLine(a, b, color_main, 2)
|
||||
|
||||
# Glas-Diagonalen (vorne + hinten)
|
||||
e.Display.DrawLine(lbf, rtf, color_soft, 1)
|
||||
e.Display.DrawLine(ltf, rbf, color_soft, 1)
|
||||
e.Display.DrawLine(lbb, rtb, color_soft, 1)
|
||||
e.Display.DrawLine(ltb, rbb, color_soft, 1)
|
||||
|
||||
# Achs-Marker (durchgestrichen wo das Loch sitzt)
|
||||
ax_l = rg.Point3d(cx - hb * tx, cy - hb * ty, on_axis.Z)
|
||||
ax_r = rg.Point3d(cx + hb * tx, cy + hb * ty, on_axis.Z)
|
||||
try: e.Display.DrawDottedLine(ax_l, ax_r, color_dotted)
|
||||
except Exception: e.Display.DrawLine(ax_l, ax_r, color_dotted, 1)
|
||||
|
||||
# Brueestungs-Linie (gepunktet, nur Fenster mit Brueest > 0)
|
||||
if typ == "fenster" and brueest > 1e-4:
|
||||
# quer ueber die Vorderflaeche
|
||||
bL = rg.Point3d(cx - hb * tx + hd * nx, cy - hb * ty + hd * ny, z_bot)
|
||||
bR = rg.Point3d(cx + hb * tx + hd * nx, cy + hb * ty + hd * ny, z_bot)
|
||||
try: e.Display.DrawDottedLine(bL, bR, color_dotted)
|
||||
except Exception: pass
|
||||
|
||||
# Mass-Label ueberm Sturz
|
||||
try:
|
||||
if typ == "fenster":
|
||||
label = "{:.2f} x {:.2f} Br {:.2f}".format(breite, hoehe, brueest)
|
||||
else:
|
||||
label = "{:.2f} x {:.2f}".format(breite, hoehe)
|
||||
anchor = rg.Point3d(cx, cy, z_top + 0.12)
|
||||
# Plane: X = Tangente (horizontal an Wand), Y = vertikal
|
||||
text_plane = rg.Plane(anchor,
|
||||
rg.Vector3d(tx, ty, 0),
|
||||
rg.Vector3d(0, 0, 1))
|
||||
t3d = Rhino.Display.Text3d(label, text_plane, 0.10)
|
||||
try: t3d.HorizontalAlignment = Rhino.DocObjects.TextHorizontalAlignment.Center
|
||||
except Exception: pass
|
||||
e.Display.Draw3dText(t3d, color_main)
|
||||
except Exception: pass
|
||||
except Exception: pass
|
||||
return handler
|
||||
|
||||
@@ -5578,10 +5629,16 @@ class ElementeBridge(panel_base.BaseBridge):
|
||||
gp.SetCommandPrompt(prompt)
|
||||
try: gp.Constrain(axis_curve, False)
|
||||
except Exception: pass
|
||||
# Live-Preview: gruenes Oeffnungs-Rechteck auf der Wand
|
||||
# Live-Preview: gruener Oeffnungs-Quader mit Glas-Diagonalen,
|
||||
# Brueest-Marker und Mass-Label oberhalb des Sturzes
|
||||
try:
|
||||
wall_dicke = float(wall_meta.get("dicke", 0.15))
|
||||
except Exception:
|
||||
wall_dicke = 0.15
|
||||
try:
|
||||
gp.DynamicDraw += _make_oeffnung_preview(
|
||||
axis_curve, breite, hoehe, brueest, preview_base_z)
|
||||
axis_curve, wall_dicke, breite, hoehe, brueest,
|
||||
preview_base_z, typ)
|
||||
except Exception: pass
|
||||
opt_b = gp.AddOption("Breite")
|
||||
opt_h = gp.AddOption("Hoehe")
|
||||
|
||||
Reference in New Issue
Block a user