mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 14:23:53 +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()
|
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):
|
def _alignment_enum_items(self, context):
|
||||||
"""Dynamic items: all top-level IfcAlignment entities in the current file."""
|
"""Dynamic items: all top-level IfcAlignment entities in the current file."""
|
||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
|
|
||||||
|
global _alignment_enum_items_cache
|
||||||
|
|
||||||
items = [("0", "— select alignment —", "")]
|
items = [("0", "— select alignment —", "")]
|
||||||
ifc_file = tool.Ifc.get()
|
ifc_file = tool.Ifc.get()
|
||||||
if not ifc_file:
|
if not ifc_file:
|
||||||
return items
|
_alignment_enum_items_cache = items
|
||||||
|
return _alignment_enum_items_cache
|
||||||
try:
|
try:
|
||||||
for a in ifc_file.by_type("IfcAlignment"):
|
for a in ifc_file.by_type("IfcAlignment"):
|
||||||
# Skip child alignments (used in multi-vertical template)
|
# Skip child alignments (used in multi-vertical template)
|
||||||
@@ -59,7 +73,8 @@ def _alignment_enum_items(self, context):
|
|||||||
items.append((str(a.id()), label, ""))
|
items.append((str(a.id()), label, ""))
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
return items
|
_alignment_enum_items_cache = items
|
||||||
|
return _alignment_enum_items_cache
|
||||||
|
|
||||||
|
|
||||||
def _on_active_alignment_update(self, context):
|
def _on_active_alignment_update(self, context):
|
||||||
|
|||||||
@@ -1057,6 +1057,23 @@ class Alignment:
|
|||||||
@classmethod
|
@classmethod
|
||||||
def get_active_alignment(cls) -> ifcopenshell.entity_instance | None:
|
def get_active_alignment(cls) -> ifcopenshell.entity_instance | None:
|
||||||
if obj := tool.Blender.get_active_object():
|
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)
|
element = tool.Ifc.get_entity(obj)
|
||||||
if not element:
|
if not element:
|
||||||
return None
|
return None
|
||||||
|
|||||||
Reference in New Issue
Block a user