T-Join 1-Wand-Modus: nur die zu snappende Wand selektieren reicht
UX-Verbesserung: User-Frage "muss ich nur das Element anwaehlen das ich snappen moechte?" — jetzt ja. Wenn nur 1 wand_axis in der Selection ist, sucht T-Join automatisch die naechste andere Wand-Achse im Doc (innerhalb 1m) und snappt die selektierte Wand auf jene. Die andere bleibt unangetastet — wie bei klassischem T-Stem gegen Through-Wand. 2-Wand-Modus bleibt: dann werden GENAU die beiden selektierten betrachtet (z.B. wenn 3+ Waende in der Nähe sind und User exakt eine andere meinen will). Selection-Hint vereinfacht: nur noch warnen wenn 0 Wand-Achsen aber wand- Objekte vorhanden (z.B. nur Volumen selektiert, wo Axis nicht mitkam).
This commit is contained in:
@@ -124,16 +124,66 @@ def _walls_and_curves_from_sel(doc, sel):
|
||||
return axes, generic
|
||||
|
||||
|
||||
def _find_nearest_other_wand_axis(doc, my_axis_obj, my_id, tol=1.0):
|
||||
"""Findet die naechste andere wand_axis im Doc (innerhalb tol).
|
||||
Return das axis Object oder None."""
|
||||
if my_axis_obj is None: return None
|
||||
g = my_axis_obj.Geometry
|
||||
if not isinstance(g, rg.Curve): return None
|
||||
bb = g.GetBoundingBox(True)
|
||||
if not bb.IsValid: return None
|
||||
best = None; best_d = tol
|
||||
for obj in doc.Objects:
|
||||
try:
|
||||
if obj.Attributes.GetUserString("dossier_element_type") != "wand_axis":
|
||||
continue
|
||||
wid = obj.Attributes.GetUserString("dossier_element_id") or ""
|
||||
if wid == my_id or not wid: continue
|
||||
except Exception: continue
|
||||
og = obj.Geometry
|
||||
if not isinstance(og, rg.Curve): continue
|
||||
try:
|
||||
# Mindest-Distanz: Endpunkte gegeneinander UND ClosestPoint
|
||||
d_min = float('inf')
|
||||
for ep in (g.PointAtStart, g.PointAtEnd):
|
||||
rc, t = og.ClosestPoint(ep)
|
||||
if rc:
|
||||
d = og.PointAt(t).DistanceTo(ep)
|
||||
if d < d_min: d_min = d
|
||||
for ep in (og.PointAtStart, og.PointAtEnd):
|
||||
rc, t = g.ClosestPoint(ep)
|
||||
if rc:
|
||||
d = g.PointAt(t).DistanceTo(ep)
|
||||
if d < d_min: d_min = d
|
||||
if d_min < best_d:
|
||||
best_d = d_min; best = obj
|
||||
except Exception: continue
|
||||
return best
|
||||
|
||||
|
||||
def _t_join_attempt(doc, sel):
|
||||
"""T-Join: 2 OFFENE Kurven wobei der EINE Endpunkt der einen Kurve
|
||||
nahe (< 20cm) auf der ANDEREN Kurve mitten landet (zwischen deren
|
||||
nahe (< 1m) auf der ANDEREN Kurve mitten landet (zwischen deren
|
||||
Endpunkten). Schiebt diesen Endpunkt exakt auf die andere Kurve.
|
||||
Die andere Kurve bleibt unveraendert.
|
||||
|
||||
Auch 1-Wand-Modus: wenn nur 1 wand_axis selektiert, sucht automatisch
|
||||
die naechste andere Wand und snappt diese eine.
|
||||
|
||||
Liefert True wenn ausgefuehrt."""
|
||||
axes, generic = _walls_and_curves_from_sel(doc, sel)
|
||||
if len(axes) == 2 and len(generic) == 0:
|
||||
o1, o2 = axes[0], axes[1]
|
||||
elif len(axes) == 1 and len(generic) == 0:
|
||||
# 1-Wand-Modus: finde naechste andere wand_axis im Doc
|
||||
my_id = axes[0].Attributes.GetUserString("dossier_element_id") or ""
|
||||
other = _find_nearest_other_wand_axis(doc, axes[0], my_id, tol=1.0)
|
||||
if other is None:
|
||||
print("[SMART-JOIN] 1-Wand T-Join: keine Nachbar-Wand "
|
||||
"innerhalb 1m gefunden")
|
||||
return False
|
||||
o1 = axes[0]; o2 = other
|
||||
print("[SMART-JOIN] 1-Wand T-Join: snappe an Nachbar-Wand")
|
||||
elif len(axes) == 0 and len(generic) == 2:
|
||||
o1, o2 = generic[0], generic[1]
|
||||
else:
|
||||
@@ -252,16 +302,15 @@ def _run():
|
||||
sel = list(doc.Objects.GetSelectedObjects(False, False))
|
||||
if not sel:
|
||||
Rhino.RhinoApp.RunScript("_Join", False); return
|
||||
# Hint wenn zu wenig Wand-Objekte selektiert
|
||||
# Info-Hint (T-Join unterstuetzt 1-Wand-Modus, L-Join braucht 2)
|
||||
n_wand_axes = sum(1 for o in sel
|
||||
if (o.Attributes.GetUserString("dossier_element_type")
|
||||
or "") == "wand_axis")
|
||||
if n_wand_axes < 2 and any(
|
||||
if n_wand_axes == 0 and any(
|
||||
(o.Attributes.GetUserString("dossier_element_type") or "")
|
||||
.startswith("wand_") for o in sel):
|
||||
print("[SMART-JOIN] nur {} Wand-Achse(n) selektiert — fuer T/L-Join "
|
||||
"GENAU 2 Waende selektieren (Click Wand + Shift+Click 2. Wand)."
|
||||
.format(n_wand_axes))
|
||||
print("[SMART-JOIN] keine Wand-Achse in Selection — selektiere die "
|
||||
"Wand-Linie oder das Wand-Volumen.")
|
||||
|
||||
# T-Join: Endpunkt der einen Curve trifft mitten auf die andere → snap.
|
||||
# L-Join: beide Endpunkte werden zum Schnittpunkt der verlaengerten Linien
|
||||
|
||||
Reference in New Issue
Block a user