From f9d2d494b1ad7f8a3638499ea1a0ce9c7f4f2817 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Sun, 26 Oct 2025 18:21:00 +1100 Subject: [PATCH] Fix #4275. Using psets_only kwarg in get_pset utility now includes predefined psets. --- .../ifcopenshell/util/element.py | 15 +++++++++++--- .../test/util/test_element.py | 20 ++++++++++++++++++- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/ifcopenshell-python/ifcopenshell/util/element.py b/src/ifcopenshell-python/ifcopenshell/util/element.py index 22665772da..bf870cb1ed 100644 --- a/src/ifcopenshell-python/ifcopenshell/util/element.py +++ b/src/ifcopenshell-python/ifcopenshell/util/element.py @@ -117,6 +117,7 @@ def get_pset( if ( psets_only and not pset.is_a("IfcPropertySet") + and not pset.is_a("IfcPreDefinedPropertySet") and not (is_ifc2x3 and pset.is_a("IfcExtendedMaterialProperties")) ): pset = None @@ -126,7 +127,11 @@ def get_pset( if type_pset is not None and not prop: if psets_only or qtos_only: type_pset_element = element.file.by_id(type_pset["id"]) - if psets_only and not type_pset_element.is_a("IfcPropertySet"): + if ( + psets_only + and not type_pset_element.is_a("IfcPropertySet") + and not type_pset_element.is_a("IfcPreDefinedPropertySet") + ): type_pset = None elif qtos_only and not type_pset_element.is_a("IfcElementQuantity"): type_pset = None @@ -177,7 +182,7 @@ def get_psets( psets = {} if element.is_a("IfcTypeObject"): for definition in element.HasPropertySets or []: - if psets_only and not definition.is_a("IfcPropertySet"): + if psets_only and not definition.is_a("IfcPropertySet") and not definition.is_a("IfcPreDefinedPropertySet"): continue if qtos_only and not definition.is_a("IfcElementQuantity"): continue @@ -213,7 +218,11 @@ def get_psets( for relationship in is_defined_by: if relationship.is_a("IfcRelDefinesByProperties"): definition = relationship.RelatingPropertyDefinition - if psets_only and not definition.is_a("IfcPropertySet"): + if ( + psets_only + and not definition.is_a("IfcPropertySet") + and not definition.is_a("IfcPreDefinedPropertySet") + ): continue if qtos_only and not definition.is_a("IfcElementQuantity"): continue diff --git a/src/ifcopenshell-python/test/util/test_element.py b/src/ifcopenshell-python/test/util/test_element.py index 0113e68d2f..2c62c6d7c5 100644 --- a/src/ifcopenshell-python/test/util/test_element.py +++ b/src/ifcopenshell-python/test/util/test_element.py @@ -43,7 +43,7 @@ import ifcopenshell.util.element as subject from ifcopenshell.util.shape_builder import ShapeBuilder -class TestIFC2X3MaterialProfilePsts(test.bootstrap.IFC2X3): +class TestIFC2X3MaterialProfilePsets(test.bootstrap.IFC2X3): def test_get_profile_pset(self): profile = ifcopenshell.api.profile.add_parameterized_profile(self.file, "IfcRectangleProfileDef") pset = ifcopenshell.api.pset.add_pset(self.file, profile, "") @@ -159,6 +159,15 @@ class TestGetPsetIFC4(test.bootstrap.IFC4): assert subject.get_pset(self.file.create_entity("IfcPerson"), "name") is None assert subject.get_pset(self.file.create_entity("IfcPerson"), "name", "a") is None + def test_getting_predefined_psets(self): + element = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcDoorType") + pset = self.file.create_entity("IfcDoorLiningProperties", ifcopenshell.guid.new()) + pset.Name = "My Lining" + pset.LiningDepth = 42 + element.HasPropertySets = [pset] + assert subject.get_pset(element, "My Lining") == {"LiningDepth": 42, "id": pset.id()} + assert subject.get_pset(element, "My Lining", psets_only=True) == {"LiningDepth": 42, "id": pset.id()} + class TestGetPsetsIFC4(test.bootstrap.IFC4): def test_getting_the_psets_of_a_product_as_a_dictionary(self): @@ -222,6 +231,15 @@ class TestGetPsetsIFC4(test.bootstrap.IFC4): ifcopenshell.api.pset.edit_qto(self.file, qto=qto, properties={"x": 42}) assert subject.get_psets(element, qtos_only=True) == {"qto": {"x": 42, "id": qto.id()}} + def test_getting_predefined_psets(self): + element = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcDoorType") + pset = self.file.create_entity("IfcDoorLiningProperties", ifcopenshell.guid.new()) + pset.Name = "My Lining" + pset.LiningDepth = 42 + element.HasPropertySets = [pset] + assert subject.get_psets(element) == {"My Lining": {"LiningDepth": 42, "id": pset.id()}} + assert subject.get_psets(element, psets_only=True) == {"My Lining": {"LiningDepth": 42, "id": pset.id()}} + class TestGetPropertyDefinitionIFC4(test.bootstrap.IFC4): def test_getting_the_properties_of_a_pset(self):