T-Join Diagnostic: zeigt warum jeder Endpunkt-Check verworfen wurde

User-Test: L-Join layered funktioniert (3/3 layers built). Aber T-Join laeuft
fuer layered immer in den L-Join-Fallback. Um zu sehen warum, jetzt fuer
jeden der 4 Endpunkt-Checks im T-Join:
- distance zur anderen Curve
- distance zur deren Endpunkten
- Reason warum verworfen (zu weit / nahe Endpunkt / schon snapped)

So koennen wir live im Log sehen ob T-Stem geometrisch zu weit weg ist
oder ob er an einem Endpunkt der Through-Wand landet (= L-Sache).
This commit is contained in:
2026-05-31 13:20:27 +02:00
parent 26214a704d
commit c81d2c0c43
+20 -8
View File
@@ -145,23 +145,35 @@ def _t_join_attempt(doc, sel):
tol_snap = 0.20 # 20 cm Snap-Radius fuer T-Verbindung tol_snap = 0.20 # 20 cm Snap-Radius fuer T-Verbindung
end_tol = 0.05 # 5cm: wenn closest-point nahe Endpunkt → eigentlich L end_tol = 0.05 # 5cm: wenn closest-point nahe Endpunkt → eigentlich L
candidates = [] candidates = []
debug_rows = []
# Pro Endpunkt der einen Kurve: ClosestPoint auf der ANDEREN Kurve # Pro Endpunkt der einen Kurve: ClosestPoint auf der ANDEREN Kurve
for (a_obj, ac, b_obj, bc) in ((o1, c1, o2, c2), (o2, c2, o1, c1)): for (a_obj, ac, b_obj, bc) in ((o1, c1, o2, c2), (o2, c2, o1, c1)):
for end in (0, 1): for end in (0, 1):
ep = ac.PointAtStart if end == 0 else ac.PointAtEnd ep = ac.PointAtStart if end == 0 else ac.PointAtEnd
try: try:
rc, t = bc.ClosestPoint(ep) rc, t = bc.ClosestPoint(ep)
if not rc: continue if not rc:
debug_rows.append(("axis_end={}".format(end), "ClosestPoint failed"))
continue
cp = bc.PointAt(t) cp = bc.PointAt(t)
d = cp.DistanceTo(ep) d = cp.DistanceTo(ep)
# Skip wenn schon snapped oder zu weit
if d < 1e-6 or d > tol_snap: continue
# Skip wenn cp nahe einem Endpunkt von bc — das ist L-Join Territory
ps = bc.PointAtStart; pe = bc.PointAtEnd ps = bc.PointAtStart; pe = bc.PointAtEnd
if cp.DistanceTo(ps) < end_tol or cp.DistanceTo(pe) < end_tol: d_to_ps = cp.DistanceTo(ps)
continue d_to_pe = cp.DistanceTo(pe)
candidates.append((d, a_obj, ac, end, cp)) reason = None
except Exception: continue if d < 1e-6: reason = "schon gesnappt"
elif d > tol_snap: reason = "zu weit ({:.3f} > {:.2f})".format(d, tol_snap)
elif d_to_ps < end_tol: reason = "cp nahe Endpunkt-Start ({:.3f}<{:.2f}) → L-Join Sache".format(d_to_ps, end_tol)
elif d_to_pe < end_tol: reason = "cp nahe Endpunkt-End ({:.3f}<{:.2f}) → L-Join Sache".format(d_to_pe, end_tol)
debug_rows.append(("axis_end={} d={:.3f}".format(end, d),
reason or "candidate"))
if reason is None:
candidates.append((d, a_obj, ac, end, cp))
except Exception as ex:
debug_rows.append(("axis_end={}".format(end), "exc: {}".format(ex)))
# Diagnostic alles ausgeben
for tag, msg in debug_rows:
print("[SMART-JOIN] T-Join check {}: {}".format(tag, msg))
if not candidates: return False if not candidates: return False
# Naechster Endpunkt → der wird gesnappt # Naechster Endpunkt → der wird gesnappt
candidates.sort(key=lambda x: x[0]) candidates.sort(key=lambda x: x[0])