diff --git a/src/bonsai/bonsai/bim/module/system/data.py b/src/bonsai/bonsai/bim/module/system/data.py index 836bf17079..3dd6856e72 100644 --- a/src/bonsai/bonsai/bim/module/system/data.py +++ b/src/bonsai/bonsai/bim/module/system/data.py @@ -267,5 +267,8 @@ class ActiveObjectZonesData: @classmethod def zones(cls): - systems = ifcopenshell.util.system.get_element_systems(tool.Ifc.get_entity(bpy.context.active_object)) - return [s.Name or "Unnamed" for s in systems if s.is_a("IfcZone")] + obj = bpy.context.active_object + assert obj + element = tool.Ifc.get_entity(obj) + assert element + return [z.Name or "Unnamed" for z in ifcopenshell.util.system.get_element_zones(element)] diff --git a/src/ifcopenshell-python/docs/ifcopenshell-python/selector_syntax.rst b/src/ifcopenshell-python/docs/ifcopenshell-python/selector_syntax.rst index a5eeb47c1b..cfb49034fb 100644 --- a/src/ifcopenshell-python/docs/ifcopenshell-python/selector_syntax.rst +++ b/src/ifcopenshell-python/docs/ifcopenshell-python/selector_syntax.rst @@ -194,6 +194,7 @@ Valid keys are: "``classification``", "Gets the element's classification reference(s)" "``group``", "Gets the element's group(s)" "``system``", "Gets the element's system(s). This is a subset of group(s)." + "``zone``", "Gets the element's zone(s). This is a subset of group(s)." "``material`` or ``mat``", "Gets the assigned material, which may be a material set." "``item`` or ``i``", "If the previous key returns a material set, gets the relevant material set items" "``materials`` or ``mats``", "Gets a list of IfcMaterials assigned directly or indirectly (such as via a material set) to the element" diff --git a/src/ifcopenshell-python/ifcopenshell/util/selector.py b/src/ifcopenshell-python/ifcopenshell/util/selector.py index f0a1025583..22608af9cc 100644 --- a/src/ifcopenshell-python/ifcopenshell/util/selector.py +++ b/src/ifcopenshell-python/ifcopenshell/util/selector.py @@ -347,6 +347,8 @@ def _get_element_value(element: ifcopenshell.entity_instance, keys: list[str]) - value = ifcopenshell.util.element.get_groups(value) elif key == "system": value = ifcopenshell.util.system.get_element_systems(value) + elif key == "zone": + value = ifcopenshell.util.system.get_element_zones(value) elif key in ("x", "y", "z", "easting", "northing", "elevation") and hasattr(value, "ObjectPlacement"): if getattr(value, "ObjectPlacement", None): matrix = ifcopenshell.util.placement.get_local_placement(value.ObjectPlacement) diff --git a/src/ifcopenshell-python/ifcopenshell/util/system.py b/src/ifcopenshell-python/ifcopenshell/util/system.py index ac19ab3c35..ef84be03c5 100644 --- a/src/ifcopenshell-python/ifcopenshell/util/system.py +++ b/src/ifcopenshell-python/ifcopenshell/util/system.py @@ -66,13 +66,24 @@ def get_system_elements(system: ifcopenshell.entity_instance) -> list[ifcopenshe def get_element_systems(element: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]: results = [] for rel in element.HasAssignments: - if rel.is_a("IfcRelAssignsToGroup") and rel.RelatingGroup.is_a() in ( - "IfcSystem", - "IfcDistributionSystem", - "IfcBuildingSystem", - "IfcZone", - ): - results.append(rel.RelatingGroup) + if rel.is_a("IfcRelAssignsToGroup"): + continue + group = rel.RelatingGroup + if not group.is_a("IfcSystem") or group.is_a() in ("IfcStructuralAnalysisModel", "IfcZone"): + continue + results.append(group) + return results + + +def get_element_zones(element: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]: + results = [] + for rel in element.HasAssignments: + if rel.is_a("IfcRelAssignsToGroup"): + continue + group = rel.RelatingGroup + if not group.is_a("IfcZone"): + continue + results.append(group) return results