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
|
L1 = v1.Length
|
||||||
L2 = v2.Length
|
L2 = v2.Length
|
||||||
half_b = float(breite) * 0.5
|
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")
|
print("[ELEMENTE] L-Treppe: Lauflinien zu kurz fuer Podest")
|
||||||
return None
|
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))
|
N = max(2, int(n_stufen))
|
||||||
S = H / N
|
S = H / N
|
||||||
|
|
||||||
# Stufen-Verteilung: N1 wird aus L1 mit dem optimalen A bestimmt,
|
# Stufen-Verteilung: N1 wird aus eff_L1 mit dem optimalen A bestimmt.
|
||||||
# damit die Klick-Position des Users direkt N1 (Stufen vor Podest)
|
eff_L1 = L1 - cut_back
|
||||||
# entspricht — genauso wie's der Live-Preview anzeigt.
|
eff_L2 = L2 - cut_back
|
||||||
eff_L1 = L1 - half_b
|
|
||||||
eff_L2 = L2 - half_b
|
|
||||||
if eff_L1 + eff_L2 <= 0: return None
|
if eff_L1 + eff_L2 <= 0: return None
|
||||||
A_opt = 0.63 - 2.0 * S
|
A_opt = 0.63 - 2.0 * S
|
||||||
if A_opt < 0.21: A_opt = 0.21
|
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()
|
v1u = rg.Vector3d(v1); v1u.Unitize()
|
||||||
v2u = rg.Vector3d(v2); v2u.Unitize()
|
v2u = rg.Vector3d(v2); v2u.Unitize()
|
||||||
|
|
||||||
# Run 1: von p0 bis p1 - v1u*half_b
|
# Run 1: von p0 bis p1 - v1u*cut_back
|
||||||
run1_end = rg.Point3d(p1.X - v1u.X * half_b, p1.Y - v1u.Y * half_b, 0)
|
run1_end = rg.Point3d(p1.X - v1u.X * cut_back, p1.Y - v1u.Y * cut_back, 0)
|
||||||
line1 = rg.LineCurve(p0, run1_end)
|
line1 = rg.LineCurve(p0, run1_end)
|
||||||
z_podest = float(uk) + N1 * S
|
z_podest = float(uk) + N1 * S
|
||||||
brep1 = _make_treppe_volume(line1, breite, referenz, N1,
|
brep1 = _make_treppe_volume(line1, breite, referenz, N1,
|
||||||
float(uk), z_podest, modus, lauf_d)
|
float(uk), z_podest, modus, lauf_d)
|
||||||
|
|
||||||
# Run 2: von p1 + v2u*half_b bis p2
|
# Run 2: von p1 + v2u*cut_back bis p2
|
||||||
run2_start = rg.Point3d(p1.X + v2u.X * half_b, p1.Y + v2u.Y * half_b, 0)
|
run2_start = rg.Point3d(p1.X + v2u.X * cut_back, p1.Y + v2u.Y * cut_back, 0)
|
||||||
line2 = rg.LineCurve(run2_start, p2)
|
line2 = rg.LineCurve(run2_start, p2)
|
||||||
brep2 = _make_treppe_volume(line2, breite, referenz, N2,
|
brep2 = _make_treppe_volume(line2, breite, referenz, N2,
|
||||||
z_podest, float(ok), modus, lauf_d)
|
z_podest, float(ok), modus, lauf_d)
|
||||||
@@ -9595,15 +9597,23 @@ class ElementeBridge(panel_base.BaseBridge):
|
|||||||
first_pt, breite, referenz, n_stufen)
|
first_pt, breite, referenz, n_stufen)
|
||||||
if gp2.Get() != GetResult.Point: return
|
if gp2.Get() != GetResult.Point: return
|
||||||
clicked = gp2.Point()
|
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
|
dx = clicked.X - first_pt.X
|
||||||
dy = clicked.Y - first_pt.Y
|
dy = clicked.Y - first_pt.Y
|
||||||
dist = (dx * dx + dy * dy) ** 0.5
|
dist = (dx * dx + dy * dy) ** 0.5
|
||||||
if dist < 1e-4:
|
if dist < 1e-4:
|
||||||
print("[ELEMENTE] Keine Richtung gewaehlt"); return
|
print("[ELEMENTE] Keine Richtung gewaehlt"); return
|
||||||
|
if treppe_art == "gerade":
|
||||||
L_min2, L_max2 = _l_range(n_stufen, H)
|
L_min2, L_max2 = _l_range(n_stufen, H)
|
||||||
# Clamp Mauspos-Distanz in die Range (oder reskaliere auf fix
|
else:
|
||||||
# wenn Range gleich null).
|
# 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:
|
if abs(L_max2 - L_min2) < 1e-4:
|
||||||
final_L = L_min2
|
final_L = L_min2
|
||||||
else:
|
else:
|
||||||
@@ -9620,15 +9630,47 @@ class ElementeBridge(panel_base.BaseBridge):
|
|||||||
if treppe_art == "l":
|
if treppe_art == "l":
|
||||||
if referenz == "mid":
|
if referenz == "mid":
|
||||||
referenz = "links"
|
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 = ric.GetPoint()
|
||||||
gp3.SetCommandPrompt(
|
gp3.SetCommandPrompt(
|
||||||
"L-Treppe: Endpunkt nach dem Podest [Stufen={}, Breite={:.2f}, Ref={}]".format(
|
"L-Treppe: Endpunkt nach Eck [Stufen={}, Breite={:.2f}, Ref={}, Modus={}]".format(
|
||||||
n_stufen, breite, referenz))
|
n_stufen, breite, referenz, regel_mode))
|
||||||
gp3.SetBasePoint(second_pt, True)
|
gp3.SetBasePoint(second_pt, True)
|
||||||
gp3.DynamicDraw += _make_treppe_preview_handler(
|
gp3.DynamicDraw += _make_treppe_preview_handler(
|
||||||
second_pt, breite, referenz, max(1, n_stufen // 2))
|
second_pt, breite, referenz, max(1, n_stufen // 2))
|
||||||
if gp3.Get() != GetResult.Point: return
|
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_first = rg.Point3d(first_pt.X, first_pt.Y, 0)
|
||||||
p_corner = rg.Point3d(second_pt.X, second_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)
|
p_end = rg.Point3d(third_pt.X, third_pt.Y, 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user