L-Aussen-Polygon: Z-Konsistenz fix + try/except defensive

_line_intersect_xy lieferte Z=0 was nicht zum Polygon-Z (=OKFF) passte,
PolylineCurve mit gemischten Z konnte fehlschlagen → 2D-Generierung
broken fuer L-Treppen. Fix: _at_z(p, fallback) Helper setzt Z explicit.
Plus try/except um die ganze Polygon-Konstruktion — Fallback auf
2-Rechteck-Variante bei Fehler.
This commit is contained in:
2026-05-28 02:40:09 +02:00
parent bb64e4d41e
commit e406e8d9b2
+32 -30
View File
@@ -6421,36 +6421,38 @@ def _lauflinie_l(axis_polyline, n_stufen, z, arrow_style="klassisch", doc=None,
def _aussen_l_polygon(axis_polyline, breite, referenz, z): def _aussen_l_polygon(axis_polyline, breite, referenz, z):
"""Sauberes L-Polygon: 6-Punkt-Outline, die beiden Laeufe schliessen """Sauberes L-Polygon: 6-Punkt-Outline mit Outer/Inner-Ecken via
sich an der Ecke an (Outer/Inner via Linien-Schnitt). Returnt eine Linien-Schnitt. Returnt PolylineCurve oder None bei Singularitaet/
Polyline ODER None bei Singularitaet (parallele Schenkel).""" Fehler Caller faellt dann auf 2-Rechteck-Variante zurueck."""
ok, poly = axis_polyline.TryGetPolyline() try:
if not ok or poly is None or poly.Count != 3: return None ok, poly = axis_polyline.TryGetPolyline()
p0 = rg.Point3d(poly[0].X, poly[0].Y, z) if not ok or poly is None or poly.Count != 3: return None
pc = rg.Point3d(poly[1].X, poly[1].Y, z) p0 = rg.Point3d(poly[0].X, poly[0].Y, z)
p1 = rg.Point3d(poly[2].X, poly[2].Y, z) pc = rg.Point3d(poly[1].X, poly[1].Y, z)
L1 = ((pc.X - p0.X) ** 2 + (pc.Y - p0.Y) ** 2) ** 0.5 p1 = rg.Point3d(poly[2].X, poly[2].Y, z)
L2 = ((p1.X - pc.X) ** 2 + (p1.Y - pc.Y) ** 2) ** 0.5 L1 = ((pc.X - p0.X) ** 2 + (pc.Y - p0.Y) ** 2) ** 0.5
if L1 < 1e-6 or L2 < 1e-6: return None L2 = ((p1.X - pc.X) ** 2 + (p1.Y - pc.Y) ** 2) ** 0.5
u1 = rg.Vector3d((pc.X - p0.X) / L1, (pc.Y - p0.Y) / L1, 0) if L1 < 1e-6 or L2 < 1e-6: return None
u2 = rg.Vector3d((p1.X - pc.X) / L2, (p1.Y - pc.Y) / L2, 0) u1 = rg.Vector3d((pc.X - p0.X) / L1, (pc.Y - p0.Y) / L1, 0)
# perp 90° CCW u2 = rg.Vector3d((p1.X - pc.X) / L2, (p1.Y - pc.Y) / L2, 0)
pp1 = (-u1.Y, u1.X) pp1 = (-u1.Y, u1.X)
pp2 = (-u2.Y, u2.X) pp2 = (-u2.Y, u2.X)
off_l, off_r = _treppe_2d_side_offsets(breite, referenz) off_l, off_r = _treppe_2d_side_offsets(breite, referenz)
def _off(pt, perp, d): def _off(pt, perp, d):
return rg.Point3d(pt.X + perp[0] * d, pt.Y + perp[1] * d, z) return rg.Point3d(pt.X + perp[0] * d, pt.Y + perp[1] * d, z)
# Lauf1 Seiten (start + corner) p0_l = _off(p0, pp1, off_l); p0_r = _off(p0, pp1, off_r)
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)
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)
# Lauf2 Seiten (corner + end) # Ecken-Schnitte — Z auf z setzen (Helper liefert Z=0)
pc_l2 = _off(pc, pp2, off_l); pc_r2 = _off(pc, pp2, off_r) def _at_z(p, fallback):
p1_l = _off(p1, pp2, off_l); p1_r = _off(p1, pp2, off_r) return rg.Point3d(p.X, p.Y, z) if p is not None else fallback
# Ecken-Schnitte: linker Schenkel intersect, rechter Schenkel intersect corner_l = _at_z(_line_intersect_xy(p0_l, u1, p1_l, u2), pc_l1)
corner_l = _line_intersect_xy(p0_l, u1, p1_l, u2) or pc_l1 corner_r = _at_z(_line_intersect_xy(p0_r, u1, p1_r, u2), pc_r1)
corner_r = _line_intersect_xy(p0_r, u1, p1_r, u2) or pc_r1 pts = [p0_l, p0_r, corner_r, p1_r, p1_l, corner_l, p0_l]
pts = [p0_l, p0_r, corner_r, p1_r, p1_l, corner_l, p0_l] return rg.PolylineCurve(rg.Polyline(pts))
return rg.PolylineCurve(rg.Polyline(pts)) except Exception as ex:
print("[ELEMENTE] _aussen_l_polygon:", ex)
return None
def _aussen_l(axis_polyline, breite, referenz, z, def _aussen_l(axis_polyline, breite, referenz, z,