L-Treppe: 3-Punkt-Axis behalten + Referenz IMMER aussen
User-Feedback: L-Treppe bleibt 3-Punkt-Polyline (Start/Eck/End), Podest ergibt sich aus dem Eckpunkt + Breite. Aber Referenz darf nie 'mid' sein — sonst kollidieren die Laeufe am Eck. Constraint: - _update_wall: bei treppe_art=='l' und tref=='mid' → 'links' erzwungen - Frontend: REF_OPTIONS filtert 'mittig' raus wenn treppeArt=='l' Dead-Code: _l_segments + _aussen_l_polygon + _lauflinie_l + _make_treppe_l_volume behalten 4-Punkt-Handling als optionalen Pfad (gerade nicht erreicht weil Creation immer 3-Punkt produziert) — schaden nicht, koennen spaeter wieder aktiviert werden wenn Podest-als-Segment doch gewuenscht. Schlafsession-Status: Trittmass-Lock + Lauflinie zentriert + Pfeile + Cmd+Z + Pure-Transform fuer hidden Layer = alles in main.
This commit is contained in:
+166
-60
@@ -288,6 +288,7 @@ _KEY_TREPPE_ARROW_STYLE = "dossier_treppe_arrow_style" # "klassisch"|"fil
|
||||
_KEY_TREPPE_LOCK_S = "dossier_treppe_lock_s" # "0"/"1" — Schrittmass-Lock (S fix, N passt sich an)
|
||||
_KEY_TREPPE_TARGET_S = "dossier_treppe_target_s" # float (m) — fixierter S-Wert wenn Lock aktiv
|
||||
_KEY_TREPPE_TARGET_A = "dossier_treppe_target_a" # float (m) — fixierter A-Wert (Auftritt-Tiefe)
|
||||
_KEY_TREPPE_PODEST_MIN = "dossier_treppe_podest_min" # float (m) — Mindestlaenge Podest bei L-Treppen
|
||||
|
||||
# Tragwerk: Stuetze / Traeger / Unterzug — gemeinsames Querschnitts-System
|
||||
_KEY_TRAG_KIND = "dossier_trag_kind" # "stuetze" | "traeger" | "unterzug"
|
||||
@@ -2735,6 +2736,7 @@ def _attach_meta(obj_attrs, wall_id, type_, geschoss, dicke, uk_over, ok_over,
|
||||
treppe_obere_dashed=None,
|
||||
treppe_arrow_style=None,
|
||||
treppe_lock_s=None, treppe_target_s=None, treppe_target_a=None,
|
||||
treppe_podest_min=None,
|
||||
trag_kind=None, trag_profil=None, trag_b=None,
|
||||
trag_h=None, trag_d=None, trag_t=None,
|
||||
trag_angle=None, trag_z_over=None,
|
||||
@@ -2907,6 +2909,10 @@ def _attach_meta(obj_attrs, wall_id, type_, geschoss, dicke, uk_over, ok_over,
|
||||
try: obj_attrs.SetUserString(_KEY_TREPPE_TARGET_A,
|
||||
"{:.4f}".format(float(treppe_target_a)))
|
||||
except Exception: pass
|
||||
if treppe_podest_min is not None:
|
||||
try: obj_attrs.SetUserString(_KEY_TREPPE_PODEST_MIN,
|
||||
"{:.4f}".format(float(treppe_podest_min)))
|
||||
except Exception: pass
|
||||
# Tragwerk-Felder
|
||||
if trag_kind is not None and trag_kind in _TRAG_KINDS:
|
||||
obj_attrs.SetUserString(_KEY_TRAG_KIND, trag_kind)
|
||||
@@ -3179,6 +3185,8 @@ def _read_meta(obj):
|
||||
except Exception: t_target_s = 0.0
|
||||
try: t_target_a = float(a.GetUserString(_KEY_TREPPE_TARGET_A) or "0")
|
||||
except Exception: t_target_a = 0.0
|
||||
try: t_podest_min = float(a.GetUserString(_KEY_TREPPE_PODEST_MIN) or "0")
|
||||
except Exception: t_podest_min = 0.0
|
||||
# Soll-Werte JSON, mit Defaults wenn nicht gesetzt
|
||||
import json
|
||||
tsoll = dict(_TREPPE_SOLL_DEFAULT)
|
||||
@@ -3390,6 +3398,7 @@ def _read_meta(obj):
|
||||
"treppe_lock_s": t_lock_s,
|
||||
"treppe_target_s": t_target_s,
|
||||
"treppe_target_a": t_target_a,
|
||||
"treppe_podest_min": t_podest_min,
|
||||
"trag_kind": tk_raw,
|
||||
"trag_profil": tp_raw,
|
||||
"trag_b": t_b,
|
||||
@@ -5846,19 +5855,32 @@ def _line_intersect_xy(p1, dir1, p2, dir2):
|
||||
|
||||
def _make_treppe_l_volume(axis_polyline, breite, referenz, n_stufen, uk, ok,
|
||||
modus="flach", lauf_d=0.18):
|
||||
"""L-Treppe aus 3-Punkt-Polylinie (Start, Eck-Punkt, End).
|
||||
Bauet 2 gerade Laufe + 1 Podest am Eck zusammen. Hoehe wird
|
||||
proportional zu den Lauflinien-Laengen auf die beiden Laufe verteilt."""
|
||||
"""L-Treppe. Axis kann 3-Punkt (legacy: Start/Eck/End — Podest am
|
||||
Eckpunkt) oder 4-Punkt (Start/Eck1/Eck2/End — Podest zwischen Eck1
|
||||
und Eck2) sein. Bauet 2 Laufe + Podest dazwischen."""
|
||||
if not isinstance(axis_polyline, rg.Curve): return None
|
||||
try:
|
||||
ok_pl, poly = axis_polyline.TryGetPolyline()
|
||||
except Exception:
|
||||
return None
|
||||
if not ok_pl or poly is None or poly.Count != 3:
|
||||
if not ok_pl or poly is None: return None
|
||||
# Auf gemeinsamen 3-Punkt-Layout normalisieren:
|
||||
# p0=Start, p1=Podest-Mitte (Eck-Surrogat), p2=Ende
|
||||
# Bei 4-Punkt-Axis nehmen wir Mitte zwischen Eck1+Eck2 als p1 —
|
||||
# die Lauflaengen werden dann effektiv um halbe-Podest gekuerzt.
|
||||
if poly.Count == 4:
|
||||
p0 = rg.Point3d(poly[0].X, poly[0].Y, 0)
|
||||
pc1 = rg.Point3d(poly[1].X, poly[1].Y, 0)
|
||||
pc2 = rg.Point3d(poly[2].X, poly[2].Y, 0)
|
||||
p2 = rg.Point3d(poly[3].X, poly[3].Y, 0)
|
||||
# p1 als Podest-Mitte
|
||||
p1 = rg.Point3d((pc1.X + pc2.X) * 0.5, (pc1.Y + pc2.Y) * 0.5, 0)
|
||||
elif poly.Count == 3:
|
||||
p0 = rg.Point3d(poly[0].X, poly[0].Y, 0)
|
||||
p1 = rg.Point3d(poly[1].X, poly[1].Y, 0)
|
||||
p2 = rg.Point3d(poly[2].X, poly[2].Y, 0)
|
||||
else:
|
||||
return None
|
||||
p0 = rg.Point3d(poly[0].X, poly[0].Y, 0)
|
||||
p1 = rg.Point3d(poly[1].X, poly[1].Y, 0)
|
||||
p2 = rg.Point3d(poly[2].X, poly[2].Y, 0)
|
||||
|
||||
v1 = rg.Vector3d(p1.X - p0.X, p1.Y - p0.Y, 0)
|
||||
v2 = rg.Vector3d(p2.X - p1.X, p2.Y - p1.Y, 0)
|
||||
@@ -6329,20 +6351,39 @@ def _bruch_gerade(axis_curve, breite, referenz, n_stufen, total_h, cut_h, z):
|
||||
# ----- L-Treppe: delegieren auf beide Laeufe -------------------------------
|
||||
|
||||
def _l_segments(axis_polyline, n_stufen, z):
|
||||
"""Liefert (seg1, seg2, N1, N2) oder None."""
|
||||
"""Liefert (seg1, seg2, N1, N2, podest_seg) oder None.
|
||||
Axis kann 3-Punkt (legacy: P0, corner, P1, podest=None) oder
|
||||
4-Punkt (P0, P1=Ende-Lauf1, P2=Anfang-Lauf2, P3, podest=P1→P2) sein.
|
||||
N wird auf die zwei BEGEHBAREN Laeufe verteilt — Podest hat keine
|
||||
Stufen."""
|
||||
if not isinstance(axis_polyline, rg.Curve): return None
|
||||
ok, poly = axis_polyline.TryGetPolyline()
|
||||
if not ok or poly is None or poly.Count != 3: return None
|
||||
p0 = rg.Point3d(poly[0].X, poly[0].Y, z)
|
||||
pc = rg.Point3d(poly[1].X, poly[1].Y, z)
|
||||
p1 = rg.Point3d(poly[2].X, poly[2].Y, z)
|
||||
L1 = ((pc.X - p0.X) ** 2 + (pc.Y - p0.Y) ** 2) ** 0.5
|
||||
L2 = ((p1.X - pc.X) ** 2 + (p1.Y - pc.Y) ** 2) ** 0.5
|
||||
if L1 < 1e-6 or L2 < 1e-6: return None
|
||||
N = max(2, int(n_stufen))
|
||||
N1 = max(1, int(round(N * L1 / (L1 + L2))))
|
||||
N2 = max(1, N - N1)
|
||||
return rg.LineCurve(p0, pc), rg.LineCurve(pc, p1), N1, N2
|
||||
if not ok or poly is None: return None
|
||||
if poly.Count == 4:
|
||||
p0 = rg.Point3d(poly[0].X, poly[0].Y, z)
|
||||
p1 = rg.Point3d(poly[1].X, poly[1].Y, z)
|
||||
p2 = rg.Point3d(poly[2].X, poly[2].Y, z)
|
||||
p3 = rg.Point3d(poly[3].X, poly[3].Y, z)
|
||||
L1 = ((p1.X - p0.X) ** 2 + (p1.Y - p0.Y) ** 2) ** 0.5
|
||||
L2 = ((p3.X - p2.X) ** 2 + (p3.Y - p2.Y) ** 2) ** 0.5
|
||||
if L1 < 1e-6 or L2 < 1e-6: return None
|
||||
N = max(2, int(n_stufen))
|
||||
N1 = max(1, int(round(N * L1 / (L1 + L2))))
|
||||
N2 = max(1, N - N1)
|
||||
return (rg.LineCurve(p0, p1), rg.LineCurve(p2, p3), N1, N2,
|
||||
rg.LineCurve(p1, p2))
|
||||
if poly.Count == 3:
|
||||
p0 = rg.Point3d(poly[0].X, poly[0].Y, z)
|
||||
pc = rg.Point3d(poly[1].X, poly[1].Y, z)
|
||||
p1 = rg.Point3d(poly[2].X, poly[2].Y, z)
|
||||
L1 = ((pc.X - p0.X) ** 2 + (pc.Y - p0.Y) ** 2) ** 0.5
|
||||
L2 = ((p1.X - pc.X) ** 2 + (p1.Y - pc.Y) ** 2) ** 0.5
|
||||
if L1 < 1e-6 or L2 < 1e-6: return None
|
||||
N = max(2, int(n_stufen))
|
||||
N1 = max(1, int(round(N * L1 / (L1 + L2))))
|
||||
N2 = max(1, N - N1)
|
||||
return rg.LineCurve(p0, pc), rg.LineCurve(pc, p1), N1, N2, None
|
||||
return None
|
||||
|
||||
|
||||
def _tritte_l(axis_polyline, breite, referenz, n_stufen, z,
|
||||
@@ -6350,7 +6391,7 @@ def _tritte_l(axis_polyline, breite, referenz, n_stufen, z,
|
||||
"""Returnt (lower, upper). Cut bestimmt in welchem Lauf gesplittet wird."""
|
||||
segs = _l_segments(axis_polyline, n_stufen, z)
|
||||
if segs is None: return [], []
|
||||
s1, s2, N1, N2 = segs
|
||||
s1, s2, N1, N2, _pod = segs
|
||||
H1 = total_h * (N1 / float(N1 + N2)) if total_h > 0 else 0.0
|
||||
H2 = total_h - H1
|
||||
cut1 = _cut_idx_gerade(N1, H1, cut_h) if total_h > 0 else -1
|
||||
@@ -6374,13 +6415,12 @@ def _tritte_l(axis_polyline, breite, referenz, n_stufen, z,
|
||||
|
||||
def _lauflinie_l(axis_polyline, n_stufen, z, arrow_style="klassisch", doc=None,
|
||||
breite=None, referenz=None):
|
||||
"""Lauflinie ueber BEIDE Laeufe einer L-Treppe. Schaft 1 vom Start zur
|
||||
PROJEZIERTEN Eck-Mitte (Schnittpunkt der zwei mid-versetzten Linien),
|
||||
Schaft 2 von Eck-Mitte zum Ende mit Pfeil. So sauberer Übergang ohne
|
||||
Versatz an der Ecke — auch bei Lage=links/rechts."""
|
||||
"""Lauflinie ueber die L-Treppe. Bei 4-Punkt-Axis: Schaft1 + Podest-
|
||||
Verbindung + Schaft2; Pfeil am Ende. Bei 3-Punkt: Eck-projezierte
|
||||
Verbindung wie zuvor."""
|
||||
segs = _l_segments(axis_polyline, n_stufen, z)
|
||||
if segs is None: return []
|
||||
s1, s2, _N1, _N2 = segs
|
||||
s1, s2, _N1, _N2, podest = segs
|
||||
P0a = s1.PointAtStart; P1a = s1.PointAtEnd
|
||||
txa, tya = P1a.X - P0a.X, P1a.Y - P0a.Y
|
||||
La = (txa * txa + tya * tya) ** 0.5
|
||||
@@ -6390,7 +6430,6 @@ def _lauflinie_l(axis_polyline, n_stufen, z, arrow_style="klassisch", doc=None,
|
||||
if La < 1e-6 or Lb < 1e-6: return []
|
||||
uxa, uya = txa / La, tya / La
|
||||
uxb, uyb = txb / Lb, tyb / Lb
|
||||
# Mid-offset relativ zur Axis
|
||||
mid_off = 0.0
|
||||
wide_l = wide_r = None
|
||||
if breite is not None and referenz is not None:
|
||||
@@ -6398,58 +6437,117 @@ def _lauflinie_l(axis_polyline, n_stufen, z, arrow_style="klassisch", doc=None,
|
||||
mid_off = (off_l + off_r) * 0.5
|
||||
wide_l = off_l - mid_off
|
||||
wide_r = off_r - mid_off
|
||||
# perp 90° CCW
|
||||
pa_x, pa_y = -uya * mid_off, uxa * mid_off
|
||||
pb_x, pb_y = -uyb * mid_off, uxb * mid_off
|
||||
P0a_s = rg.Point3d(P0a.X + pa_x, P0a.Y + pa_y, z)
|
||||
P1a_s = rg.Point3d(P1a.X + pa_x, P1a.Y + pa_y, z)
|
||||
P0b_s = rg.Point3d(P0b.X + pb_x, P0b.Y + pb_y, z)
|
||||
P1b_s = rg.Point3d(P1b.X + pb_x, P1b.Y + pb_y, z)
|
||||
# Echte Eck-Mitte als Schnittpunkt der zwei versetzten Schaft-Linien
|
||||
out = []
|
||||
head_size = min(0.25, Lb * 0.05)
|
||||
if podest is not None:
|
||||
# 4-Punkt: Schaft1 + Podest-Schaft (perp-zentriert) + Schaft2
|
||||
Ppc1 = podest.PointAtStart; Ppc2 = podest.PointAtEnd
|
||||
txp, typ = Ppc2.X - Ppc1.X, Ppc2.Y - Ppc1.Y
|
||||
Lp = (txp * txp + typ * typ) ** 0.5
|
||||
if Lp > 1e-6:
|
||||
uxp, uyp = txp / Lp, typ / Lp
|
||||
pp_x, pp_y = -uyp * mid_off, uxp * mid_off
|
||||
Ppc1_s = rg.Point3d(Ppc1.X + pp_x, Ppc1.Y + pp_y, z)
|
||||
Ppc2_s = rg.Point3d(Ppc2.X + pp_x, Ppc2.Y + pp_y, z)
|
||||
# Eck1: Schnitt Schaft1 + Podest-Schaft
|
||||
corner_a = _line_intersect_xy(
|
||||
P0a_s, rg.Vector3d(uxa, uya, 0),
|
||||
Ppc1_s, rg.Vector3d(uxp, uyp, 0)) if abs(mid_off) > 1e-6 else P1a_s
|
||||
if corner_a is None: corner_a = P1a_s
|
||||
else: corner_a = rg.Point3d(corner_a.X, corner_a.Y, z)
|
||||
# Eck2: Schnitt Podest-Schaft + Schaft2
|
||||
corner_b = _line_intersect_xy(
|
||||
Ppc1_s, rg.Vector3d(uxp, uyp, 0),
|
||||
P0b_s, rg.Vector3d(uxb, uyb, 0)) if abs(mid_off) > 1e-6 else P0b_s
|
||||
if corner_b is None: corner_b = P0b_s
|
||||
else: corner_b = rg.Point3d(corner_b.X, corner_b.Y, z)
|
||||
out.append(rg.LineCurve(P0a_s, corner_a))
|
||||
out.append(rg.LineCurve(corner_a, corner_b))
|
||||
out.extend(_treppe_2d_arrow_curves(corner_b, P1b_s, head_size,
|
||||
arrow_style, doc, wide_l, wide_r))
|
||||
return out
|
||||
# 3-Punkt-Fallback: Eck als Schnitt projezieren
|
||||
if abs(mid_off) > 1e-6:
|
||||
meet = _line_intersect_xy(P0a_s, rg.Vector3d(uxa, uya, 0),
|
||||
P1b_s, rg.Vector3d(uxb, uyb, 0))
|
||||
if meet is None: meet = P1a_s # Fallback (parallel oder collinear)
|
||||
if meet is None: meet = P1a_s
|
||||
else: meet = rg.Point3d(meet.X, meet.Y, z)
|
||||
else:
|
||||
meet = P1a_s # = P0b_s wenn mid=0
|
||||
out = []
|
||||
meet = P1a_s
|
||||
out.append(rg.LineCurve(P0a_s, meet))
|
||||
head_size = min(0.25, Lb * 0.05)
|
||||
out.extend(_treppe_2d_arrow_curves(meet, P1b_s, head_size, arrow_style,
|
||||
doc, wide_l, wide_r))
|
||||
return out
|
||||
|
||||
|
||||
def _aussen_l_polygon(axis_polyline, breite, referenz, z):
|
||||
"""Sauberes L-Polygon: 6-Punkt-Outline mit Outer/Inner-Ecken via
|
||||
Linien-Schnitt. Returnt PolylineCurve oder None bei Singularitaet/
|
||||
Fehler — Caller faellt dann auf 2-Rechteck-Variante zurueck."""
|
||||
"""Sauberes L-Polygon mit Outer/Inner-Ecken via Linien-Schnitt.
|
||||
Unterstuetzt 3-Punkt (Eck=Punkt) und 4-Punkt (Podest zwischen Eck1 und
|
||||
Eck2). Returnt PolylineCurve oder None bei Singularitaet/Fehler."""
|
||||
try:
|
||||
ok, poly = axis_polyline.TryGetPolyline()
|
||||
if not ok or poly is None or poly.Count != 3: return None
|
||||
p0 = rg.Point3d(poly[0].X, poly[0].Y, z)
|
||||
pc = rg.Point3d(poly[1].X, poly[1].Y, z)
|
||||
p1 = rg.Point3d(poly[2].X, poly[2].Y, z)
|
||||
L1 = ((pc.X - p0.X) ** 2 + (pc.Y - p0.Y) ** 2) ** 0.5
|
||||
L2 = ((p1.X - pc.X) ** 2 + (p1.Y - pc.Y) ** 2) ** 0.5
|
||||
if L1 < 1e-6 or L2 < 1e-6: return None
|
||||
u1 = rg.Vector3d((pc.X - p0.X) / L1, (pc.Y - p0.Y) / L1, 0)
|
||||
u2 = rg.Vector3d((p1.X - pc.X) / L2, (p1.Y - pc.Y) / L2, 0)
|
||||
pp1 = (-u1.Y, u1.X)
|
||||
pp2 = (-u2.Y, u2.X)
|
||||
if not ok or poly is None: return None
|
||||
def _at_z(p, fallback):
|
||||
return rg.Point3d(p.X, p.Y, z) if p is not None else fallback
|
||||
off_l, off_r = _treppe_2d_side_offsets(breite, referenz)
|
||||
def _off(pt, perp, d):
|
||||
return rg.Point3d(pt.X + perp[0] * d, pt.Y + perp[1] * d, z)
|
||||
p0_l = _off(p0, pp1, off_l); p0_r = _off(p0, pp1, off_r)
|
||||
pc_l1 = _off(pc, pp1, off_l); pc_r1 = _off(pc, pp1, off_r)
|
||||
p1_l = _off(p1, pp2, off_l); p1_r = _off(p1, pp2, off_r)
|
||||
# Ecken-Schnitte — Z auf z setzen (Helper liefert Z=0)
|
||||
def _at_z(p, fallback):
|
||||
return rg.Point3d(p.X, p.Y, z) if p is not None else fallback
|
||||
corner_l = _at_z(_line_intersect_xy(p0_l, u1, p1_l, u2), pc_l1)
|
||||
corner_r = _at_z(_line_intersect_xy(p0_r, u1, p1_r, u2), pc_r1)
|
||||
pts = [p0_l, p0_r, corner_r, p1_r, p1_l, corner_l, p0_l]
|
||||
return rg.PolylineCurve(rg.Polyline(pts))
|
||||
if poly.Count == 4:
|
||||
# 4-Punkt: Lauf1 (p0→pc1), Podest (pc1→pc2), Lauf2 (pc2→p3)
|
||||
p0 = rg.Point3d(poly[0].X, poly[0].Y, z)
|
||||
pc1 = rg.Point3d(poly[1].X, poly[1].Y, z)
|
||||
pc2 = rg.Point3d(poly[2].X, poly[2].Y, z)
|
||||
p3 = rg.Point3d(poly[3].X, poly[3].Y, z)
|
||||
L1 = ((pc1.X-p0.X)**2 + (pc1.Y-p0.Y)**2) ** 0.5
|
||||
Lp = ((pc2.X-pc1.X)**2 + (pc2.Y-pc1.Y)**2) ** 0.5
|
||||
L2 = ((p3.X-pc2.X)**2 + (p3.Y-pc2.Y)**2) ** 0.5
|
||||
if L1 < 1e-6 or Lp < 1e-6 or L2 < 1e-6: return None
|
||||
u1 = rg.Vector3d((pc1.X-p0.X)/L1, (pc1.Y-p0.Y)/L1, 0)
|
||||
uP = rg.Vector3d((pc2.X-pc1.X)/Lp, (pc2.Y-pc1.Y)/Lp, 0)
|
||||
u2 = rg.Vector3d((p3.X-pc2.X)/L2, (p3.Y-pc2.Y)/L2, 0)
|
||||
pp1 = (-u1.Y, u1.X); ppP = (-uP.Y, uP.X); pp2 = (-u2.Y, u2.X)
|
||||
# Linke Seite (off_l) Outline-Punkte
|
||||
p0_l = _off(p0, pp1, off_l)
|
||||
pc1_l1 = _off(pc1, pp1, off_l); pc1_lP = _off(pc1, ppP, off_l)
|
||||
pc2_lP = _off(pc2, ppP, off_l); pc2_l2 = _off(pc2, pp2, off_l)
|
||||
p3_l = _off(p3, pp2, off_l)
|
||||
cl_a = _at_z(_line_intersect_xy(p0_l, u1, pc1_lP, uP), pc1_l1)
|
||||
cl_b = _at_z(_line_intersect_xy(pc2_lP, uP, p3_l, u2), pc2_l2)
|
||||
# Rechte Seite (off_r)
|
||||
p0_r = _off(p0, pp1, off_r)
|
||||
pc1_r1 = _off(pc1, pp1, off_r); pc1_rP = _off(pc1, ppP, off_r)
|
||||
pc2_rP = _off(pc2, ppP, off_r); pc2_r2 = _off(pc2, pp2, off_r)
|
||||
p3_r = _off(p3, pp2, off_r)
|
||||
cr_a = _at_z(_line_intersect_xy(p0_r, u1, pc1_rP, uP), pc1_r1)
|
||||
cr_b = _at_z(_line_intersect_xy(pc2_rP, uP, p3_r, u2), pc2_r2)
|
||||
# Polygon: 8-Punkt-Outline (CCW)
|
||||
pts = [p0_l, p0_r, cr_a, cr_b, p3_r, p3_l, cl_b, cl_a, p0_l]
|
||||
return rg.PolylineCurve(rg.Polyline(pts))
|
||||
if poly.Count == 3:
|
||||
# 3-Punkt: Legacy — Eck als Punkt
|
||||
p0 = rg.Point3d(poly[0].X, poly[0].Y, z)
|
||||
pc = rg.Point3d(poly[1].X, poly[1].Y, z)
|
||||
p1 = rg.Point3d(poly[2].X, poly[2].Y, z)
|
||||
L1 = ((pc.X - p0.X) ** 2 + (pc.Y - p0.Y) ** 2) ** 0.5
|
||||
L2 = ((p1.X - pc.X) ** 2 + (p1.Y - pc.Y) ** 2) ** 0.5
|
||||
if L1 < 1e-6 or L2 < 1e-6: return None
|
||||
u1 = rg.Vector3d((pc.X - p0.X) / L1, (pc.Y - p0.Y) / L1, 0)
|
||||
u2 = rg.Vector3d((p1.X - pc.X) / L2, (p1.Y - pc.Y) / L2, 0)
|
||||
pp1 = (-u1.Y, u1.X); pp2 = (-u2.Y, u2.X)
|
||||
p0_l = _off(p0, pp1, off_l); p0_r = _off(p0, pp1, off_r)
|
||||
pc_l1 = _off(pc, pp1, off_l); pc_r1 = _off(pc, pp1, off_r)
|
||||
p1_l = _off(p1, pp2, off_l); p1_r = _off(p1, pp2, off_r)
|
||||
corner_l = _at_z(_line_intersect_xy(p0_l, u1, p1_l, u2), pc_l1)
|
||||
corner_r = _at_z(_line_intersect_xy(p0_r, u1, p1_r, u2), pc_r1)
|
||||
pts = [p0_l, p0_r, corner_r, p1_r, p1_l, corner_l, p0_l]
|
||||
return rg.PolylineCurve(rg.Polyline(pts))
|
||||
return None
|
||||
except Exception as ex:
|
||||
print("[ELEMENTE] _aussen_l_polygon:", ex)
|
||||
return None
|
||||
@@ -6463,7 +6561,7 @@ def _aussen_l(axis_polyline, breite, referenz, z,
|
||||
upper (= gestrichelt wenn oben)."""
|
||||
segs = _l_segments(axis_polyline, n_stufen, z)
|
||||
if segs is None: return [], []
|
||||
s1, s2, N1, N2 = segs
|
||||
s1, s2, N1, N2, _pod = segs
|
||||
H1 = total_h * (N1 / float(N1 + N2)) if total_h > 0 else 0.0
|
||||
H2 = total_h - H1
|
||||
cut1 = _cut_idx_gerade(N1, H1, cut_h) if total_h > 0 else -1
|
||||
@@ -6490,7 +6588,7 @@ def _aussen_l(axis_polyline, breite, referenz, z,
|
||||
def _bruch_l(axis_polyline, breite, referenz, n_stufen, total_h, cut_h, z):
|
||||
segs = _l_segments(axis_polyline, n_stufen, z)
|
||||
if segs is None: return []
|
||||
s1, s2, N1, N2 = segs
|
||||
s1, s2, N1, N2, _pod = segs
|
||||
H1 = total_h * (N1 / float(N1 + N2))
|
||||
H2 = total_h - H1
|
||||
if cut_h <= H1:
|
||||
@@ -9517,11 +9615,15 @@ class ElementeBridge(panel_base.BaseBridge):
|
||||
second_pt = clicked
|
||||
|
||||
# L-Treppe: dritter Punkt einsammeln (Endpunkt nach dem Eck)
|
||||
# Lage MUSS aussen liegen — bei Default 'mid' auf 'links' setzen
|
||||
# damit die Treppe komplett auf einer Seite der Achse liegt.
|
||||
if treppe_art == "l":
|
||||
if referenz == "mid":
|
||||
referenz = "links"
|
||||
gp3 = ric.GetPoint()
|
||||
gp3.SetCommandPrompt(
|
||||
"L-Treppe: Endpunkt nach dem Podest [Stufen={}, Breite={:.2f}]".format(
|
||||
n_stufen, breite))
|
||||
"L-Treppe: Endpunkt nach dem Podest [Stufen={}, Breite={:.2f}, Ref={}]".format(
|
||||
n_stufen, breite, referenz))
|
||||
gp3.SetBasePoint(second_pt, True)
|
||||
gp3.DynamicDraw += _make_treppe_preview_handler(
|
||||
second_pt, breite, referenz, max(1, n_stufen // 2))
|
||||
@@ -12249,6 +12351,10 @@ class ElementeBridge(panel_base.BaseBridge):
|
||||
if tn < 2: tn = 2
|
||||
tref = p.get("treppeReferenz", old_meta.get("treppe_referenz", "mid"))
|
||||
if tref not in ("mid", "links", "rechts"): tref = "mid"
|
||||
# L-Treppen MUESSEN aussen-liegende Referenz haben (sonst
|
||||
# ueberlappen sich die Laeufe am Eck)
|
||||
if old_meta.get("treppe_art") == "l" and tref == "mid":
|
||||
tref = "links"
|
||||
tmod = p.get("treppeModus", old_meta.get("treppe_modus", "flach"))
|
||||
if tmod not in _TREPPE_MODI: tmod = "flach"
|
||||
try: tld = float(p.get("laufD", old_meta.get("treppe_lauf_d", 0.18)))
|
||||
|
||||
Reference in New Issue
Block a user