From bcc399b84242f1d9de8eb03b0ba33ceae291febb Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Sun, 19 Mar 2023 13:13:15 +1100 Subject: [PATCH] Empty psets are purged to discourage invalid psets with no properties --- .../blenderbim/bim/module/pset/operator.py | 31 ++++++++++++------- src/blenderbim/blenderbim/tool/pset.py | 9 ++++++ src/blenderbim/test/tool/test_pset.py | 13 ++++++++ 3 files changed, 42 insertions(+), 11 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/pset/operator.py b/src/blenderbim/blenderbim/bim/module/pset/operator.py index a184d63759..69a8c6177b 100644 --- a/src/blenderbim/blenderbim/bim/module/pset/operator.py +++ b/src/blenderbim/blenderbim/bim/module/pset/operator.py @@ -219,6 +219,12 @@ class DisablePsetEditing(bpy.types.Operator, Operator): def _execute(self, context): props = get_pset_props(context, self.obj, self.obj_type) + pset = tool.Ifc.get().by_id(props.active_pset_id) + ifc_definition_id = blenderbim.bim.helper.get_obj_ifc_definition_id(context, self.obj, self.obj_type) + if tool.Pset.is_pset_empty(pset): + ifcopenshell.api.run( + "pset.remove_pset", tool.Ifc.get(), product=tool.Ifc.get().by_id(ifc_definition_id), pset=pset + ) props.active_pset_id = 0 @@ -250,16 +256,15 @@ class EditPset(bpy.types.Operator, Operator): e[value_name] for e in prop.enumerated_value.enumerated_values if e.is_selected ] + pset = self.file.by_id(pset_id) if tool.Ifc.get().by_id(pset_id).is_a() in ("IfcPropertySet", "IfcMaterialProperties", "IfcProfileProperties"): ifcopenshell.api.run( "pset.edit_pset", self.file, - **{ - "pset": self.file.by_id(pset_id), - "name": props.active_pset_name, - "properties": properties, - "pset_template": blenderbim.bim.schema.ifc.psetqto.get_by_name(props.active_pset_name), - }, + pset=pset, + name=props.active_pset_name, + properties=properties, + pset_template=blenderbim.bim.schema.ifc.psetqto.get_by_name(props.active_pset_name), ) else: for key, value in properties.items(): @@ -268,13 +273,17 @@ class EditPset(bpy.types.Operator, Operator): ifcopenshell.api.run( "pset.edit_qto", self.file, - **{ - "qto": self.file.by_id(pset_id), - "name": props.active_pset_name, - "properties": properties, - }, + qto=pset, + name=props.active_pset_name, + properties=properties, ) bpy.ops.bim.load_cost_item_quantities() + + if tool.Pset.is_pset_empty(pset): + ifcopenshell.api.run( + "pset.remove_pset", tool.Ifc.get(), product=tool.Ifc.get().by_id(ifc_definition_id), pset=pset + ) + bpy.ops.bim.disable_pset_editing(obj=self.obj, obj_type=self.obj_type) diff --git a/src/blenderbim/blenderbim/tool/pset.py b/src/blenderbim/blenderbim/tool/pset.py index 7e5c206108..42469d5711 100644 --- a/src/blenderbim/blenderbim/tool/pset.py +++ b/src/blenderbim/blenderbim/tool/pset.py @@ -58,3 +58,12 @@ class Pset(blenderbim.core.tool.Pset): @classmethod def is_pset_applicable(cls, element, pset_name): return bool(pset_name in blenderbim.bim.schema.ifc.psetqto.get_applicable_names(element.is_a(), pset_only=True)) + + @classmethod + def is_pset_empty(cls, pset): + pset_dict = ifcopenshell.util.element.get_property_definition(pset) + del pset_dict["id"] + for value in pset_dict.values(): + if value is not None: + return False + return True diff --git a/src/blenderbim/test/tool/test_pset.py b/src/blenderbim/test/tool/test_pset.py index 32d0287458..f7c0effbd9 100644 --- a/src/blenderbim/test/tool/test_pset.py +++ b/src/blenderbim/test/tool/test_pset.py @@ -36,3 +36,16 @@ class TestGetElementPset(NewFile): element = ifc.createIfcWall() pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo") assert subject.get_element_pset(element, "Foo") == pset + + +class TestIsPsetEmpty(NewFile): + def test_run(self): + ifc = ifcopenshell.file() + tool.Ifc.set(ifc) + element = ifc.createIfcWall() + pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo") + assert subject.is_pset_empty(pset) is True + ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "Bar"}) + assert subject.is_pset_empty(pset) is False + ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": None}) + assert subject.is_pset_empty(pset) is True