Per-Wand Joint-Rolle: explizit waehlen wer am T-Stoss durchgeht
Neues UserString-Feld 'dossier_wand_joint_rolle' per wand_axis: - 'auto' (default): bisherige Logik. Bei beidseitig auto entscheidet die Style-Prio (hoehere = durchgehend) - 'durchgehend': diese Wand ueberschreibt → ich gehe durch, T-Miter wird NICHT auf mich angewendet - 'anstossend': diese Wand stoppt immer am Joint, auch wenn ich Prio-haerter waere T-Junction-Detection in regen ruft jetzt _wand_should_apply_t_miter: - my.rolle entscheidet zuerst - bei my=auto: through.rolle entscheidet - bei beide=auto: Prio-Vergleich (hoehere Prio = durchgehend) - Default: T-Miter applied (= ich stoppe am Through) Frontend: neue Dropdown 'Joint' in WallProperties zwischen Stil und Aufbau: - Auto (Prio entscheidet) - Durchgehend - Anstossend Backend-Pipeline: _attach_meta + _read_meta um wand_joint_rolle erweitert, state-JSON sendet 'jointRolle', _update_wall_body handhabt jointRolle-Patch.
This commit is contained in:
+51
-5
@@ -41,6 +41,7 @@ _KEY_WAND_LAYERS = "dossier_wand_layers" # JSON-Liste [{name, dicke, color}]
|
||||
_KEY_WAND_LAYER_IDX = "dossier_wand_layer_idx" # Layer-Index am Volume-Brep
|
||||
_KEY_WAND_CHAIN_MEMBERS = "dossier_wand_chain_members" # JSON-Liste wand_ids einer Polyline-Chain (nur auf wand_volume)
|
||||
_KEY_WAND_STYLE_ID = "dossier_wand_style_id" # Verweis auf Project-Settings wand_styles[].id
|
||||
_KEY_WAND_JOINT_ROLLE = "dossier_wand_joint_rolle" # "auto"|"durchgehend"|"anstossend" — per-Wand Override am T-Joint
|
||||
_KEY_DACH_NEIGUNG = "dossier_dach_neigung" # Grad als string ("30")
|
||||
_KEY_DACH_EAVE = "dossier_dach_eave" # Index der Traufkante (string)
|
||||
_KEY_DACH_TYP = "dossier_dach_typ" # "pult"|"sattel"|"walm"|"mansarde"
|
||||
@@ -3571,6 +3572,34 @@ def _wand_meta_prio(doc, meta):
|
||||
except Exception: return 500
|
||||
|
||||
|
||||
def _wand_should_apply_t_miter(doc, my_meta, through_wid):
|
||||
"""Entscheidet ob ich (T-Stem-Kandidat) am T-Junction zur Through-Wand
|
||||
angeschmiegt werden soll (= T-mitered). Per-Wand Joint-Rolle hat Vorrang
|
||||
vor Prio:
|
||||
- my.rolle='durchgehend': skip miter (ich bin Through, gehe drueber)
|
||||
- my.rolle='anstossend': apply miter (ich stoppe)
|
||||
- my.rolle='auto' + through.rolle='anstossend': skip (through stoppt)
|
||||
- my.rolle='auto' + through.rolle='durchgehend': apply
|
||||
- beide 'auto': Prio entscheidet (hoehere Prio = Through)"""
|
||||
if not my_meta: return True
|
||||
my_rolle = (my_meta.get("wand_joint_rolle") or "auto").lower()
|
||||
if my_rolle == "durchgehend": return False
|
||||
if my_rolle == "anstossend": return True
|
||||
# auto: schau auf through-wand
|
||||
th_meta = _wand_meta_by_id(doc, through_wid) if through_wid else None
|
||||
if th_meta:
|
||||
th_rolle = (th_meta.get("wand_joint_rolle") or "auto").lower()
|
||||
if th_rolle == "durchgehend": return True # through ist explizit through
|
||||
if th_rolle == "anstossend": return False # through stoppt → ich Through
|
||||
# beide auto → Prio
|
||||
try:
|
||||
if int(_wand_meta_prio(doc, my_meta)) > int(
|
||||
_wand_meta_prio(doc, th_meta)):
|
||||
return False # ich hoehere Prio = Through
|
||||
except Exception: pass
|
||||
return True # Default: T-mitere mich (T-Stem stoppt am Through)
|
||||
|
||||
|
||||
def _wand_meta_by_id(doc, wall_id):
|
||||
"""Kuerzel: liefert das meta-Dict fuer eine wall_id ueber _find_axis."""
|
||||
obj = _find_axis(doc, wall_id)
|
||||
@@ -3884,6 +3913,7 @@ def _attach_meta(obj_attrs, wall_id, type_, geschoss, dicke, uk_over, ok_over,
|
||||
wand_layered=None, wand_layers=None, wand_layer_idx=None,
|
||||
wand_chain_members=None,
|
||||
wand_style_id=None,
|
||||
wand_joint_rolle=None,
|
||||
aussp_parent=None):
|
||||
"""User-Strings auf die Object-Attributes setzen."""
|
||||
obj_attrs.SetUserString(_KEY_ID, wall_id)
|
||||
@@ -4186,6 +4216,12 @@ def _attach_meta(obj_attrs, wall_id, type_, geschoss, dicke, uk_over, ok_over,
|
||||
obj_attrs.SetUserString(_KEY_WAND_STYLE_ID,
|
||||
str(wand_style_id or ""))
|
||||
except Exception: pass
|
||||
if wand_joint_rolle is not None:
|
||||
try:
|
||||
rv = str(wand_joint_rolle or "auto").lower()
|
||||
if rv not in ("auto", "durchgehend", "anstossend"): rv = "auto"
|
||||
obj_attrs.SetUserString(_KEY_WAND_JOINT_ROLLE, rv)
|
||||
except Exception: pass
|
||||
if wand_chain_members is not None:
|
||||
try:
|
||||
import json as _json
|
||||
@@ -4580,6 +4616,7 @@ def _read_meta(obj):
|
||||
"wand_layer_idx": w_layer_idx,
|
||||
"wand_chain_members": w_chain_members,
|
||||
"wand_style_id": a.GetUserString(_KEY_WAND_STYLE_ID) or "",
|
||||
"wand_joint_rolle": (a.GetUserString(_KEY_WAND_JOINT_ROLLE) or "auto").lower(),
|
||||
"aussp_parent": aussp_parent_raw,
|
||||
}
|
||||
except Exception:
|
||||
@@ -8363,8 +8400,9 @@ def _regenerate_element_body(doc, element_id, src_obj, meta, geom, geschoss_name
|
||||
exclude_ids=chain_set)
|
||||
if tj is not None:
|
||||
_oid, b_tan, b_dicke = tj
|
||||
tm = _t_junction_miter(p_s, out_s, b_tan, b_dicke)
|
||||
if tm is not None: miter_start = tm
|
||||
if _wand_should_apply_t_miter(doc, meta, _oid):
|
||||
tm = _t_junction_miter(p_s, out_s, b_tan, b_dicke)
|
||||
if tm is not None: miter_start = tm
|
||||
else:
|
||||
# 3+ Joint: ich bin T-Stem wenn meine Tangente NICHT
|
||||
# collinear mit zwei collinearen Partner-Tangenten ist.
|
||||
@@ -8393,8 +8431,9 @@ def _regenerate_element_body(doc, element_id, src_obj, meta, geom, geschoss_name
|
||||
exclude_ids=chain_set)
|
||||
if tj is not None:
|
||||
_oid, b_tan, b_dicke = tj
|
||||
tm = _t_junction_miter(p_e, out_e, b_tan, b_dicke)
|
||||
if tm is not None: miter_end = tm
|
||||
if _wand_should_apply_t_miter(doc, meta, _oid):
|
||||
tm = _t_junction_miter(p_e, out_e, b_tan, b_dicke)
|
||||
if tm is not None: miter_end = tm
|
||||
else:
|
||||
# 3+ Joint: T-Stem-Erkennung (analog start)
|
||||
_my_t = geom.TangentAtEnd
|
||||
@@ -9498,6 +9537,7 @@ class ElementeBridge(panel_base.BaseBridge):
|
||||
"layered": bool(meta.get("wand_layered", False)),
|
||||
"layers": meta.get("wand_layers", []),
|
||||
"styleId": meta.get("wand_style_id", "") or "",
|
||||
"jointRolle": meta.get("wand_joint_rolle", "auto") or "auto",
|
||||
})
|
||||
elif meta["type"] == "decke_outline":
|
||||
uk, ok = _resolve_decke_z(doc, meta["geschoss"], meta["dicke"],
|
||||
@@ -14543,6 +14583,11 @@ class ElementeBridge(panel_base.BaseBridge):
|
||||
try:
|
||||
old_chain_members = _find_wall_chain(doc, wall_id)
|
||||
except Exception: pass
|
||||
# Joint-Rolle: explizit per-Wand "auto"/"durchgehend"/"anstossend"
|
||||
if old_meta["type"] == "wand_axis" and "jointRolle" in p:
|
||||
new_joint_rolle = p.get("jointRolle") or "auto"
|
||||
else:
|
||||
new_joint_rolle = old_meta.get("wand_joint_rolle", "auto")
|
||||
_attach_meta(attrs, wall_id, old_meta["type"], geschoss, dicke,
|
||||
uk_over, ok_over, referenz,
|
||||
neigung=neigung, eave_idx=eave_idx, dach_typ=dach_typ,
|
||||
@@ -14550,7 +14595,8 @@ class ElementeBridge(panel_base.BaseBridge):
|
||||
dach_variante=dach_variante,
|
||||
wand_layered=wand_layered,
|
||||
wand_layers=wand_layers if wand_layered else [],
|
||||
wand_style_id=new_style_id if old_meta["type"] == "wand_axis" else None)
|
||||
wand_style_id=new_style_id if old_meta["type"] == "wand_axis" else None,
|
||||
wand_joint_rolle=new_joint_rolle if old_meta["type"] == "wand_axis" else None)
|
||||
axis_obj.Attributes = attrs
|
||||
axis_obj.CommitChanges()
|
||||
# Volumen regenerieren (Layer ggf. anpassen)
|
||||
|
||||
Reference in New Issue
Block a user