L-Treppe: Schrittmass-Clamp bei Setzen + 3D-Podest Lage-aware
Bisher griff der Schrittmass-Clamp nur bei treppe_art=='gerade'. Fuer L-Treppen jetzt: - gp2 (Eck-Klick): clampt erste Lauf-Laenge auf [1-Stufe-min, (n-1)-Stufen-max] - gp3 (End-Klick): schaetzt N1 aus erster Lauf-Laenge, clampt zweiten Lauf auf den S/A-konformen Bereich (mit cut_back kompensiert) Volume-Fix _make_treppe_l_volume: - cut_back am Eckpunkt war hardcoded half_b (= passt nur fuer Lage=mid). Fuer Lage=links/rechts wird die FULL breite cut-back gebraucht — sonst ueberlappen die Lauf-Volumen am Eckpunkt mit dem Podest falsch. Fix: cut_back = half_b if mid else breite.
This commit is contained in:
+58
-16
@@ -5887,7 +5887,11 @@ def _make_treppe_l_volume(axis_polyline, breite, referenz, n_stufen, uk, ok,
|
||||
L1 = v1.Length
|
||||
L2 = v2.Length
|
||||
half_b = float(breite) * 0.5
|
||||
if L1 < half_b + 0.05 or L2 < half_b + 0.05:
|
||||
# Cut-back am Eckpunkt: Lage=mid → half_b (treppe extends ±b/2 perp,
|
||||
# halbe Ueberlappung pro Lauf). Lage=links/rechts → FULL b (treppe
|
||||
# extends 0..b auf einer Seite, ganze Ueberlappung pro Lauf).
|
||||
cut_back = half_b if referenz == "mid" else float(breite)
|
||||
if L1 < cut_back + 0.05 or L2 < cut_back + 0.05:
|
||||
print("[ELEMENTE] L-Treppe: Lauflinien zu kurz fuer Podest")
|
||||
return None
|
||||
|
||||
@@ -5896,11 +5900,9 @@ def _make_treppe_l_volume(axis_polyline, breite, referenz, n_stufen, uk, ok,
|
||||
N = max(2, int(n_stufen))
|
||||
S = H / N
|
||||
|
||||
# Stufen-Verteilung: N1 wird aus L1 mit dem optimalen A bestimmt,
|
||||
# damit die Klick-Position des Users direkt N1 (Stufen vor Podest)
|
||||
# entspricht — genauso wie's der Live-Preview anzeigt.
|
||||
eff_L1 = L1 - half_b
|
||||
eff_L2 = L2 - half_b
|
||||
# Stufen-Verteilung: N1 wird aus eff_L1 mit dem optimalen A bestimmt.
|
||||
eff_L1 = L1 - cut_back
|
||||
eff_L2 = L2 - cut_back
|
||||
if eff_L1 + eff_L2 <= 0: return None
|
||||
A_opt = 0.63 - 2.0 * S
|
||||
if A_opt < 0.21: A_opt = 0.21
|
||||
@@ -5913,15 +5915,15 @@ def _make_treppe_l_volume(axis_polyline, breite, referenz, n_stufen, uk, ok,
|
||||
v1u = rg.Vector3d(v1); v1u.Unitize()
|
||||
v2u = rg.Vector3d(v2); v2u.Unitize()
|
||||
|
||||
# Run 1: von p0 bis p1 - v1u*half_b
|
||||
run1_end = rg.Point3d(p1.X - v1u.X * half_b, p1.Y - v1u.Y * half_b, 0)
|
||||
# Run 1: von p0 bis p1 - v1u*cut_back
|
||||
run1_end = rg.Point3d(p1.X - v1u.X * cut_back, p1.Y - v1u.Y * cut_back, 0)
|
||||
line1 = rg.LineCurve(p0, run1_end)
|
||||
z_podest = float(uk) + N1 * S
|
||||
brep1 = _make_treppe_volume(line1, breite, referenz, N1,
|
||||
float(uk), z_podest, modus, lauf_d)
|
||||
|
||||
# Run 2: von p1 + v2u*half_b bis p2
|
||||
run2_start = rg.Point3d(p1.X + v2u.X * half_b, p1.Y + v2u.Y * half_b, 0)
|
||||
# Run 2: von p1 + v2u*cut_back bis p2
|
||||
run2_start = rg.Point3d(p1.X + v2u.X * cut_back, p1.Y + v2u.Y * cut_back, 0)
|
||||
line2 = rg.LineCurve(run2_start, p2)
|
||||
brep2 = _make_treppe_volume(line2, breite, referenz, N2,
|
||||
z_podest, float(ok), modus, lauf_d)
|
||||
@@ -9595,15 +9597,23 @@ class ElementeBridge(panel_base.BaseBridge):
|
||||
first_pt, breite, referenz, n_stufen)
|
||||
if gp2.Get() != GetResult.Point: return
|
||||
clicked = gp2.Point()
|
||||
if regel_mode == "regel" and treppe_art == "gerade":
|
||||
# Schrittmass-Clamp im "regel"-Modus — fuer gerade Treppen mit
|
||||
# voller n_stufen. Fuer L-Treppen: lockerer Clamp (1..n-1 Stufen
|
||||
# in diesem Lauf, da der zweite noch kommt).
|
||||
if regel_mode == "regel" and treppe_art in ("gerade", "l"):
|
||||
dx = clicked.X - first_pt.X
|
||||
dy = clicked.Y - first_pt.Y
|
||||
dist = (dx * dx + dy * dy) ** 0.5
|
||||
if dist < 1e-4:
|
||||
print("[ELEMENTE] Keine Richtung gewaehlt"); return
|
||||
if treppe_art == "gerade":
|
||||
L_min2, L_max2 = _l_range(n_stufen, H)
|
||||
# Clamp Mauspos-Distanz in die Range (oder reskaliere auf fix
|
||||
# wenn Range gleich null).
|
||||
else:
|
||||
# L: clamp auf [1 Stufe × A_min, (n-1) Stufen × A_max]
|
||||
L1_min, L1_max = _l_range(1, H)
|
||||
L_minF, L_maxF = _l_range(max(2, n_stufen - 1), H)
|
||||
L_min2 = L1_min
|
||||
L_max2 = L_maxF
|
||||
if abs(L_max2 - L_min2) < 1e-4:
|
||||
final_L = L_min2
|
||||
else:
|
||||
@@ -9620,15 +9630,47 @@ class ElementeBridge(panel_base.BaseBridge):
|
||||
if treppe_art == "l":
|
||||
if referenz == "mid":
|
||||
referenz = "links"
|
||||
# Erste Lauf-Laenge (bereits via cut_back im Volume reduziert,
|
||||
# hier nur fuer Stufen-Verteilung)
|
||||
d1x = second_pt.X - first_pt.X
|
||||
d1y = second_pt.Y - first_pt.Y
|
||||
L1_cur = (d1x * d1x + d1y * d1y) ** 0.5
|
||||
gp3 = ric.GetPoint()
|
||||
gp3.SetCommandPrompt(
|
||||
"L-Treppe: Endpunkt nach dem Podest [Stufen={}, Breite={:.2f}, Ref={}]".format(
|
||||
n_stufen, breite, referenz))
|
||||
"L-Treppe: Endpunkt nach Eck [Stufen={}, Breite={:.2f}, Ref={}, Modus={}]".format(
|
||||
n_stufen, breite, referenz, regel_mode))
|
||||
gp3.SetBasePoint(second_pt, True)
|
||||
gp3.DynamicDraw += _make_treppe_preview_handler(
|
||||
second_pt, breite, referenz, max(1, n_stufen // 2))
|
||||
if gp3.Get() != GetResult.Point: return
|
||||
third_pt = gp3.Point()
|
||||
third_pt_raw = gp3.Point()
|
||||
# Schrittmass-Clamp fuer Lauf 2: verbleibende Stufen = n - N1_est
|
||||
# Mit cut_back-Aware Stufen-Schaetzung: N1_est aus eff_L1 = L1 - cut_back
|
||||
if regel_mode == "regel":
|
||||
d2x = third_pt_raw.X - second_pt.X
|
||||
d2y = third_pt_raw.Y - second_pt.Y
|
||||
d2 = (d2x * d2x + d2y * d2y) ** 0.5
|
||||
if d2 < 1e-4:
|
||||
print("[ELEMENTE] Keine Richtung gewaehlt"); return
|
||||
S_cur = H / max(2, int(n_stufen))
|
||||
cb = (breite * 0.5) if referenz == "mid" else float(breite)
|
||||
eff_L1 = max(0.01, L1_cur - cb)
|
||||
A_opt = max(0.21, min(0.35, 0.63 - 2.0 * S_cur))
|
||||
N1_est = max(1, min(n_stufen - 1, int(round(eff_L1 / A_opt))))
|
||||
N2_est = max(1, n_stufen - N1_est)
|
||||
# Range fuer Lauf 2 (mit cut_back-Anteil dazu)
|
||||
L2_min, L2_max = _l_range(N2_est, H * N2_est / n_stufen)
|
||||
L2_min += cb
|
||||
L2_max += cb
|
||||
if abs(L2_max - L2_min) < 1e-4:
|
||||
final_L2 = L2_min
|
||||
else:
|
||||
final_L2 = max(L2_min, min(L2_max, d2))
|
||||
third_pt = rg.Point3d(second_pt.X + d2x / d2 * final_L2,
|
||||
second_pt.Y + d2y / d2 * final_L2,
|
||||
second_pt.Z)
|
||||
else:
|
||||
third_pt = third_pt_raw
|
||||
p_first = rg.Point3d(first_pt.X, first_pt.Y, 0)
|
||||
p_corner = rg.Point3d(second_pt.X, second_pt.Y, 0)
|
||||
p_end = rg.Point3d(third_pt.X, third_pt.Y, 0)
|
||||
|
||||
Reference in New Issue
Block a user