mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 08:35:14 +00:00
Improves interactive editing of horizontal alignment
This commit is contained in:
@@ -39,14 +39,28 @@ def _on_vertical_visibility_update(self, context):
|
||||
VerticalProfileDecorator.tag_redraw()
|
||||
|
||||
|
||||
# Blender requires a dynamic EnumProperty callback to keep a reference to the
|
||||
# items it returns — the strings are read by the C/RNA layer after the Python
|
||||
# call returns, and if the list is only local to the function it can be
|
||||
# garbage-collected before that happens. Without this cache, the dropdown can
|
||||
# resolve its stored index against a stale/freed items list — e.g. right
|
||||
# after adding and drawing a new alignment — leaving the dropdown (and the
|
||||
# segment table, which reads its value) showing a different alignment than
|
||||
# the one actually active in the viewport. See bpy.props.EnumProperty docs.
|
||||
_alignment_enum_items_cache: list[tuple[str, str, str]] = []
|
||||
|
||||
|
||||
def _alignment_enum_items(self, context):
|
||||
"""Dynamic items: all top-level IfcAlignment entities in the current file."""
|
||||
import bonsai.tool as tool
|
||||
|
||||
global _alignment_enum_items_cache
|
||||
|
||||
items = [("0", "— select alignment —", "")]
|
||||
ifc_file = tool.Ifc.get()
|
||||
if not ifc_file:
|
||||
return items
|
||||
_alignment_enum_items_cache = items
|
||||
return _alignment_enum_items_cache
|
||||
try:
|
||||
for a in ifc_file.by_type("IfcAlignment"):
|
||||
# Skip child alignments (used in multi-vertical template)
|
||||
@@ -59,7 +73,8 @@ def _alignment_enum_items(self, context):
|
||||
items.append((str(a.id()), label, ""))
|
||||
except Exception:
|
||||
pass
|
||||
return items
|
||||
_alignment_enum_items_cache = items
|
||||
return _alignment_enum_items_cache
|
||||
|
||||
|
||||
def _on_active_alignment_update(self, context):
|
||||
|
||||
@@ -1057,6 +1057,23 @@ class Alignment:
|
||||
@classmethod
|
||||
def get_active_alignment(cls) -> ifcopenshell.entity_instance | None:
|
||||
if obj := tool.Blender.get_active_object():
|
||||
# PI curve marker empties (see PICurveMarkerProperties) are never
|
||||
# IFC-linked — they're transient viewport helpers — so they need
|
||||
# their own lookup via the alignment_id they were tagged with,
|
||||
# rather than falling through to tool.Ifc.get_entity() below.
|
||||
# Without this, selecting a marker to press Apply Curve leaves
|
||||
# this returning None, and the Alignments tab's dropdown/segment
|
||||
# table (which sync from this) revert to "select an alignment".
|
||||
marker = obj.bonsai_pi_curve_marker
|
||||
if marker.is_pi_marker:
|
||||
ifc_file = tool.Ifc.get()
|
||||
if not ifc_file:
|
||||
return None
|
||||
try:
|
||||
alignment = ifc_file.by_id(marker.alignment_id)
|
||||
except RuntimeError:
|
||||
return None
|
||||
return cls._get_top_level_alignment(alignment) if alignment.is_a("IfcAlignment") else None
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if not element:
|
||||
return None
|
||||
|
||||
Reference in New Issue
Block a user