Fix addresses not updating immediately in IfcPerson UI

Found by @sboddy in #6869

Caused by trying to remove Blender entities from owner/data.py
This commit is contained in:
Andrej730
2025-07-07 13:00:04 +05:00
parent 4fda916c2f
commit 40dcd393c6
3 changed files with 42 additions and 63 deletions
+3 -18
View File
@@ -60,30 +60,15 @@ class RolesAddressesData:
return results
@classmethod
def get_address_list_attributes(cls, address: ifcopenshell.entity_instance) -> list[dict[str, Any]]:
results: list[dict[str, Any]] = []
props = tool.Owner.get_owner_props()
def get_address_list_attributes(cls, address: ifcopenshell.entity_instance) -> list[str]:
if address.is_a("IfcPostalAddress"):
names = ["AddressLines"]
elif address.is_a("IfcTelecomAddress"):
names = ["TelephoneNumbers", "FacsimileNumbers", "ElectronicMailAddresses", "MessagingIDs"]
else:
assert False, f"Unexpected entity: {address}"
for name in names:
if name == "AddressLines":
items = [{"id": id, "prop": prop} for id, prop in enumerate(props.address_lines)]
elif name == "TelephoneNumbers":
items = [{"id": id, "prop": prop} for id, prop in enumerate(props.telephone_numbers)]
elif name == "FacsimileNumbers":
items = [{"id": id, "prop": prop} for id, prop in enumerate(props.facsimile_numbers)]
elif name == "ElectronicMailAddresses":
items = [{"id": id, "prop": prop} for id, prop in enumerate(props.electronic_mail_addresses)]
elif name == "MessagingIDs":
items = [{"id": id, "prop": prop} for id, prop in enumerate(props.messaging_ids)]
else:
assert False, f"Unexpected name: {name}"
results.append({"name": name, "items": items})
return results
return names
class PeopleData(RolesAddressesData):
+4 -3
View File
@@ -72,12 +72,13 @@ def draw_addresses(box: bpy.types.UILayout, parent: dict[str, Any]) -> None:
op = row.operator("bim.add_address_attribute", icon="ADD", text="")
op.name = attribute["name"]
for item in attribute["items"]:
collection = tool.Owner.get_address_collection(attribute["name"])
for i, item in enumerate(collection):
row = box.row(align=True)
row.prop(item["prop"], "name", text="")
row.prop(item, "name", text="")
op = row.operator("bim.remove_address_attribute", icon="REMOVE", text="")
op.name = attribute["name"]
op.id = item["id"]
op.id = i
else:
row = box.row(align=True)
row.label(text=address["label"])
+35 -42
View File
@@ -26,7 +26,7 @@ from typing import Union, Any, TYPE_CHECKING, Literal, assert_never
if TYPE_CHECKING:
from bonsai.bim.module.owner.prop import BIMOwnerProperties
from bonsai.bim.prop import Attribute
from bonsai.bim.prop import Attribute, StrProperty
class Owner(bonsai.core.tool.Owner):
@@ -60,9 +60,28 @@ class Owner(bonsai.core.tool.Owner):
props = cls.get_owner_props()
props.active_address_id = address.id()
@classmethod
def get_address_collection_name(cls, attribute_name: AddressAttributeType) -> str:
blender_names: dict[tool.Owner.AddressAttributeType, str] = {
"AddressLines": "address_lines",
"TelephoneNumbers": "telephone_numbers",
"FacsimileNumbers": "facsimile_numbers",
"ElectronicMailAddresses": "electronic_mail_addresses",
"MessagingIDs": "messaging_ids",
}
return blender_names[attribute_name]
@classmethod
def get_address_collection(
cls, attribute_name: AddressAttributeType
) -> bpy.types.bpy_prop_collection_idprop[StrProperty]:
props = cls.get_owner_props()
blender_name = cls.get_address_collection_name(attribute_name)
return getattr(props, blender_name)
@classmethod
def import_address_attributes(cls) -> None:
props = props = cls.get_owner_props()
props = cls.get_owner_props()
props.address_attributes.clear()
props.address_lines.clear()
props.telephone_numbers.clear()
@@ -73,21 +92,10 @@ class Owner(bonsai.core.tool.Owner):
address = cls.get_address()
def callback(name: str, prop, data: dict[str, Any]) -> None:
if name == "AddressLines":
if name in cls.ADDREESS_ATTRIBUTE_TYPES:
collection = cls.get_address_collection(name)
for line in data[name] or []:
props.address_lines.add().name = line
elif name == "TelephoneNumbers":
for line in data[name] or []:
props.telephone_numbers.add().name = line
elif name == "FacsimileNumbers":
for line in data[name] or []:
props.facsimile_numbers.add().name = line
elif name == "ElectronicMailAddresses":
for line in data[name] or []:
props.electronic_mail_addresses.add().name = line
elif name == "MessagingIDs":
for line in data[name] or []:
props.messaging_ids.add().name = line
collection.add().name = line
bonsai.bim.helper.import_attributes(address.is_a(), props.address_attributes, address.get_info(), callback)
@@ -117,38 +125,23 @@ class Owner(bonsai.core.tool.Owner):
AddressAttributeType = Literal[
"AddressLines", "TelephoneNumbers", "FacsimileNumbers", "ElectronicMailAddresses", "MessagingIDs"
]
ADDREESS_ATTRIBUTE_TYPES = (
"AddressLines",
"TelephoneNumbers",
"FacsimileNumbers",
"ElectronicMailAddresses",
"MessagingIDs",
)
@classmethod
def add_address_attribute(cls, name: AddressAttributeType) -> None:
props = cls.get_owner_props()
if name == "AddressLines":
props.address_lines.add()
elif name == "TelephoneNumbers":
props.telephone_numbers.add()
elif name == "FacsimileNumbers":
props.facsimile_numbers.add()
elif name == "ElectronicMailAddresses":
props.electronic_mail_addresses.add()
elif name == "MessagingIDs":
props.messaging_ids.add()
else:
assert_never(name)
collection = cls.get_address_collection(name)
collection.add()
@classmethod
def remove_address_attribute(cls, name: AddressAttributeType, id: int) -> None:
props = cls.get_owner_props()
if name == "AddressLines":
props.address_lines.remove(id)
elif name == "TelephoneNumbers":
props.telephone_numbers.remove(id)
elif name == "FacsimileNumbers":
props.facsimile_numbers.remove(id)
elif name == "ElectronicMailAddresses":
props.electronic_mail_addresses.remove(id)
elif name == "MessagingIDs":
props.messaging_ids.remove(id)
else:
assert_never(name)
collection = cls.get_address_collection(name)
collection.remove(id)
@classmethod
def set_organisation(cls, organisation: ifcopenshell.entity_instance) -> None: