From 3e2b66ef2fff9585014d8cffe768c21d8902e1ee Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Sat, 14 Aug 2021 13:01:22 +1000 Subject: [PATCH] You can now edit psets of profiles --- .../blenderbim/bim/module/pset/__init__.py | 4 +++ .../blenderbim/bim/module/pset/operator.py | 7 ++++ .../blenderbim/bim/module/pset/prop.py | 17 ++++++++++ .../blenderbim/bim/module/pset/ui.py | 34 +++++++++++++++++++ .../ifcopenshell/api/project/append_asset.py | 1 + .../ifcopenshell/api/pset/add_pset.py | 12 +++++++ .../ifcopenshell/api/pset/data.py | 11 +++++- 7 files changed, 85 insertions(+), 1 deletion(-) diff --git a/src/blenderbim/blenderbim/bim/module/pset/__init__.py b/src/blenderbim/blenderbim/bim/module/pset/__init__.py index 800817f8bd..ad512786a3 100644 --- a/src/blenderbim/blenderbim/bim/module/pset/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/pset/__init__.py @@ -14,11 +14,13 @@ classes = ( prop.MaterialPsetProperties, prop.TaskPsetProperties, prop.ResourcePsetProperties, + prop.ProfilePsetProperties, ui.BIM_PT_object_psets, ui.BIM_PT_object_qtos, ui.BIM_PT_material_psets, ui.BIM_PT_task_qtos, ui.BIM_PT_resource_qtos, + ui.BIM_PT_profile_psets, ) @@ -27,6 +29,7 @@ def register(): bpy.types.Material.PsetProperties = bpy.props.PointerProperty(type=prop.MaterialPsetProperties) bpy.types.Scene.TaskPsetProperties = bpy.props.PointerProperty(type=prop.TaskPsetProperties) bpy.types.Scene.ResourcePsetProperties = bpy.props.PointerProperty(type=prop.ResourcePsetProperties) + bpy.types.Scene.ProfilePsetProperties = bpy.props.PointerProperty(type=prop.ProfilePsetProperties) def unregister(): @@ -34,3 +37,4 @@ def unregister(): del bpy.types.Material.PsetProperties del bpy.types.Scene.TaskPsetProperties del bpy.types.Scene.ResourcePsetProperties + del bpy.types.Scene.ProfilePsetProperties diff --git a/src/blenderbim/blenderbim/bim/module/pset/operator.py b/src/blenderbim/blenderbim/bim/module/pset/operator.py index 0b96edfd6d..071d5dab3b 100644 --- a/src/blenderbim/blenderbim/bim/module/pset/operator.py +++ b/src/blenderbim/blenderbim/bim/module/pset/operator.py @@ -22,6 +22,8 @@ def get_pset_props(context, obj, obj_type): return context.scene.TaskPsetProperties elif obj_type == "Resource": return context.scene.ResourcePsetProperties + elif obj_type == "Profile": + return context.scene.ProfilePsetProperties def get_pset_obj_ifc_definition_id(context, obj, obj_type): @@ -39,6 +41,11 @@ def get_pset_obj_ifc_definition_id(context, obj, obj_type): return context.scene.BIMResourceTreeProperties.resources[ context.scene.BIMResourceProperties.active_resource_index ].ifc_definition_id + elif obj_type == "Profile": + return context.scene.BIMProfileProperties.profiles[ + context.scene.BIMProfileProperties.active_profile_index + ].ifc_definition_id + class TogglePsetExpansion(bpy.types.Operator): diff --git a/src/blenderbim/blenderbim/bim/module/pset/prop.py b/src/blenderbim/blenderbim/bim/module/pset/prop.py index 13eb2bb3d9..2b9a255971 100644 --- a/src/blenderbim/blenderbim/bim/module/pset/prop.py +++ b/src/blenderbim/blenderbim/bim/module/pset/prop.py @@ -72,6 +72,16 @@ def getResourceQtoNames(self, context): return qtonames[ifc_class] +def getProfilePsetNames(self, context): + global psetnames + pprops = context.scene.BIMProfileProperties + ifc_class = IfcStore.get_file().by_id(pprops.profiles[pprops.active_profile_index].ifc_definition_id).is_a() + if ifc_class not in psetnames: + psets = blenderbim.bim.schema.ifc.psetqto.get_applicable(ifc_class, pset_only=True) + psetnames[ifc_class] = [(p.Name, p.Name, "") for p in psets] + return psetnames[ifc_class] + + def getQtoNames(self, context): global qtonames if "/" in context.active_object.name: @@ -110,3 +120,10 @@ class ResourcePsetProperties(PropertyGroup): active_pset_name: StringProperty(name="Pset Name") properties: CollectionProperty(name="Properties", type=Attribute) qto_name: EnumProperty(items=getResourceQtoNames, name="Qto Name") + + +class ProfilePsetProperties(PropertyGroup): + active_pset_id: IntProperty(name="Active Pset ID") + active_pset_name: StringProperty(name="Pset Name") + properties: CollectionProperty(name="Properties", type=Attribute) + pset_name: EnumProperty(items=getProfilePsetNames, name="Pset Name") diff --git a/src/blenderbim/blenderbim/bim/module/pset/ui.py b/src/blenderbim/blenderbim/bim/module/pset/ui.py index c2c175e1ec..4bed5d65dc 100644 --- a/src/blenderbim/blenderbim/bim/module/pset/ui.py +++ b/src/blenderbim/blenderbim/bim/module/pset/ui.py @@ -287,3 +287,37 @@ class BIM_PT_resource_qtos(Panel): qtos = [(qto_id, Data.qtos[qto_id]) for qto_id in Data.products[ifc_definition_id]["qtos"]] for qto_id, qto in sorted(qtos, key=lambda v: v[1]["Name"]): draw_psetqto_ui(context, qto_id, qto, props, self.layout, "Resource") + + +class BIM_PT_profile_psets(Panel): + bl_label = "IFC Profile Property Sets" + bl_idname = "BIM_PT_profile_psets" + bl_space_type = "PROPERTIES" + bl_region_type = "WINDOW" + bl_context = "scene" + bl_parent_id = "BIM_PT_profiles" + + @classmethod + def poll(cls, context): + props = context.scene.BIMProfileProperties + if not props.is_editing: + return False + total_profiles = len(context.scene.BIMProfileProperties.profiles) + if total_profiles > 0 and props.active_profile_index < total_profiles: + return True + return False + + def draw(self, context): + props = context.scene.ProfilePsetProperties + pprops = context.scene.BIMProfileProperties + ifc_definition_id = pprops.profiles[pprops.active_profile_index].ifc_definition_id + if ifc_definition_id not in Data.products: + Data.load(IfcStore.get_file(), ifc_definition_id) + row = self.layout.row(align=True) + row.prop(props, "pset_name", text="") + op = row.operator("bim.add_pset", icon="ADD", text="") + op.obj_type = "Profile" + + psets = [(pset_id, Data.psets[pset_id]) for pset_id in Data.products[ifc_definition_id]["psets"]] + for pset_id, pset in sorted(psets, key=lambda v: v[1]["Name"]): + draw_psetqto_ui(context, pset_id, pset, props, self.layout, "Profile") diff --git a/src/ifcopenshell-python/ifcopenshell/api/project/append_asset.py b/src/ifcopenshell-python/ifcopenshell/api/project/append_asset.py index 501bae3538..7ecb9d31a0 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/project/append_asset.py +++ b/src/ifcopenshell-python/ifcopenshell/api/project/append_asset.py @@ -42,6 +42,7 @@ class Usecase: def append_profile_def(self): if [e for e in self.file.by_type("IfcProfileDef") if e.ProfileName == self.settings["element"].ProfileName]: return + self.whitelisted_inverse_attributes = {"IfcProfileDef": ["HasProperties"]} return self.add_element(self.settings["element"]) def append_type_product(self): diff --git a/src/ifcopenshell-python/ifcopenshell/api/pset/add_pset.py b/src/ifcopenshell-python/ifcopenshell/api/pset/add_pset.py index 1ad8f0cdd0..bdef548e4c 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/pset/add_pset.py +++ b/src/ifcopenshell-python/ifcopenshell/api/pset/add_pset.py @@ -64,3 +64,15 @@ class Usecase: "Material": self.settings["product"], } ) + elif self.settings["product"].is_a("IfcProfileDef"): + for definition in self.settings["product"].HasProperties or []: + if definition.Name == self.settings["name"]: + return definition + + return self.file.create_entity( + "IfcProfileProperties", + **{ + "Name": self.settings["name"], + "ProfileDefinition": self.settings["product"], + } + ) diff --git a/src/ifcopenshell-python/ifcopenshell/api/pset/data.py b/src/ifcopenshell-python/ifcopenshell/api/pset/data.py index 0800938da4..39d44c0832 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/pset/data.py +++ b/src/ifcopenshell-python/ifcopenshell/api/pset/data.py @@ -26,6 +26,8 @@ class Data: cls.add_type_product_psets(product, product_id) elif product.is_a("IfcMaterialDefinition"): cls.add_material_psets(product, product_id) + elif product.is_a("IfcProfileDef"): + cls.add_profile_psets(product, product_id) else: cls.add_product_psets(product, product_id) @@ -44,6 +46,13 @@ class Data: for pset in product.HasProperties: cls.add_pset(pset, product_id) + @classmethod + def add_profile_psets(cls, product, product_id): + if not product.HasProperties: + return + for pset in product.HasProperties: + cls.add_pset(pset, product_id) + @classmethod def add_product_psets(cls, product, product_id): if not hasattr(product, "IsDefinedBy") or not product.IsDefinedBy: @@ -59,7 +68,7 @@ class Data: @classmethod def add_pset(cls, pset, product_id): data = pset.get_info() - if not pset.is_a("IfcMaterialProperties"): + if not pset.is_a("IfcMaterialProperties") and not pset.is_a("IfcProfileProperties"): del data["OwnerHistory"] del data["HasProperties"] if hasattr(pset, "HasProperties"):