From 9cf34f9d8cf2c7173774aa3441fca5e3e0e6999d Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Thu, 5 Dec 2024 15:20:57 +0500 Subject: [PATCH] Select profile for profile type objects #5814 Demo - https://imgchest.com/p/9rydjxwanyk --- src/bonsai/bonsai/bim/module/root/data.py | 11 +++++++++ src/bonsai/bonsai/bim/module/root/operator.py | 24 +++++++++++++------ src/bonsai/bonsai/bim/module/root/prop.py | 7 ++++++ 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/bonsai/bonsai/bim/module/root/data.py b/src/bonsai/bonsai/bim/module/root/data.py index 38db05960e..12f4795fde 100644 --- a/src/bonsai/bonsai/bim/module/root/data.py +++ b/src/bonsai/bonsai/bim/module/root/data.py @@ -51,6 +51,7 @@ class IfcClassData: cls.data["ifc_class"] = cls.ifc_class() cls.data["ifc_predefined_types"] = cls.ifc_predefined_types() cls.data["can_reassign_class"] = cls.can_reassign_class() + cls.data["profile"] = cls.profile() @classmethod def ifc_products(cls): @@ -289,3 +290,13 @@ class IfcClassData: if element.is_a(product[0]): return True return False + + @classmethod + def profile(cls) -> list[tuple[str, str, str]]: + items = [("-", "-", "")] + ifc_file = tool.Ifc.get() + for profile in ifc_file.by_type("IfcProfileDef"): + if not (profile_name := profile.ProfileName): + continue + items.append((str(profile.id()), profile_name, profile.is_a())) + return items diff --git a/src/bonsai/bonsai/bim/module/root/operator.py b/src/bonsai/bonsai/bim/module/root/operator.py index 69ac760cbf..f50fb8709d 100644 --- a/src/bonsai/bonsai/bim/module/root/operator.py +++ b/src/bonsai/bonsai/bim/module/root/operator.py @@ -344,6 +344,7 @@ class AddElement(bpy.types.Operator, tool.Ifc.Operator): props.userdefined_type if props.ifc_predefined_type == "USERDEFINED" else props.ifc_predefined_type ) representation_template = props.representation_template + ifc_file = tool.Ifc.get() ifc_context = None if get_enum_items(props, "contexts", context): @@ -456,14 +457,20 @@ class AddElement(bpy.types.Operator, tool.Ifc.Operator): else: material = ifcopenshell.api.run("material.add_material", tool.Ifc.get(), name="Unknown") if representation_template == "PROFILESET": - named_profiles = [p for p in tool.Ifc.get().by_type("IfcProfileDef") if p.ProfileName] - if named_profiles: - profile = named_profiles[0] + profile_id = tool.Blender.get_enum_safe(context.scene.BIMRootProperties, "profile") + if profile_id in ("-", None): + profile = next((p for p in ifc_file.by_type("IfcProfileDef") if p.ProfileName), None) + if profile is None: + size = 0.5 / unit_scale + profile = ifc_file.create_entity( + "IfcRectangleProfileDef", + ProfileName="New Profile", + ProfileType="AREA", + XDim=size, + YDim=size, + ) else: - size = 0.5 / unit_scale - profile = tool.Ifc.get().create_entity( - "IfcRectangleProfileDef", ProfileName="New Profile", ProfileType="AREA", XDim=size, YDim=size - ) + profile = ifc_file.by_id(int(profile_id)) else: # NOTE: defaults dims are in meters / mm # for now default names are hardcoded to mm @@ -541,6 +548,9 @@ class AddElement(bpy.types.Operator, tool.Ifc.Operator): if props.representation_template == "OBJ": row = self.layout.row() row.prop(props, "representation_obj", text="Object") + elif props.representation_template == "PROFILESET": + row = self.layout.row() + row.prop(props, "profile", text="Profile") if props.representation_template != "EMPTY": prop_with_search(self.layout, props, "contexts") diff --git a/src/bonsai/bonsai/bim/module/root/prop.py b/src/bonsai/bonsai/bim/module/root/prop.py index 0de2f0e5ba..7445b53d8f 100644 --- a/src/bonsai/bonsai/bim/module/root/prop.py +++ b/src/bonsai/bonsai/bim/module/root/prop.py @@ -88,6 +88,12 @@ def get_contexts(self, context): return IfcClassData.data["contexts"] +def get_profile(self, context): + if not IfcClassData.is_loaded: + IfcClassData.load() + return IfcClassData.data["profile"] + + def update_relating_class_from_object(self, context): if self.relating_class_object is None: return @@ -134,6 +140,7 @@ class BIMRootProperties(PropertyGroup): poll=poll_representation_obj, description="The representation will be a tessellation of the selected object", ) + profile: EnumProperty(name="Profile for profile type object", items=get_profile) relating_class_object: PointerProperty( type=bpy.types.Object, name="Copy Class",