diff --git a/src/blenderbim/blenderbim/bim/handler.py b/src/blenderbim/blenderbim/bim/handler.py index 1f208585bf..e4ff613d7a 100644 --- a/src/blenderbim/blenderbim/bim/handler.py +++ b/src/blenderbim/blenderbim/bim/handler.py @@ -26,6 +26,7 @@ from blenderbim.bim.module.drawing.prop import RasterStyleProperty from bpy.app.handlers import persistent from blenderbim.bim.ifc import IfcStore from blenderbim.bim.module.owner.prop import get_user_person, get_user_organisation +from blenderbim.bim.module.model.data import AuthoringData from ifcopenshell.api.material.data import Data as MaterialData from ifcopenshell.api.type.data import Data as TypeData @@ -301,3 +302,4 @@ def setDefaultProperties(scene): drawing_style.name = "Blender Default" drawing_style.render_type = "DEFAULT" bpy.ops.bim.save_drawing_style(index="2") + AuthoringData.type_thumbnails = {} diff --git a/src/blenderbim/blenderbim/bim/module/profile/__init__.py b/src/blenderbim/blenderbim/bim/module/profile/__init__.py index 18c05e7619..86636ba5ff 100644 --- a/src/blenderbim/blenderbim/bim/module/profile/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/profile/__init__.py @@ -20,12 +20,13 @@ import bpy from . import ui, prop, operator classes = ( - operator.LoadProfiles, - operator.DisableProfileEditingUI, - operator.RemoveProfileDef, - operator.EnableEditingProfile, + operator.AddProfileDef, operator.DisableEditingProfile, + operator.DisableProfileEditingUI, operator.EditProfile, + operator.EnableEditingProfile, + operator.LoadProfiles, + operator.RemoveProfileDef, prop.Profile, prop.BIMProfileProperties, ui.BIM_PT_profiles, diff --git a/src/blenderbim/blenderbim/bim/module/profile/data.py b/src/blenderbim/blenderbim/bim/module/profile/data.py index d71faae1cd..d98747f658 100644 --- a/src/blenderbim/blenderbim/bim/module/profile/data.py +++ b/src/blenderbim/blenderbim/bim/module/profile/data.py @@ -17,6 +17,7 @@ # along with BlenderBIM Add-on. If not, see . import bpy +import ifcopenshell.util.doc import blenderbim.tool as tool @@ -30,9 +31,24 @@ class ProfileData: @classmethod def load(cls): - cls.data = {"total_profiles": cls.total_profiles()} + cls.data = {"total_profiles": cls.total_profiles(), "profile_classes": cls.profile_classes()} cls.is_loaded = True @classmethod def total_profiles(cls): return len(tool.Ifc.get().by_type("IfcProfileDef")) + + @classmethod + def profile_classes(cls): + classes = ["IfcArbitraryClosedProfileDef"] + queue = ["IfcParameterizedProfileDef"] + while queue: + item = queue.pop() + subtypes = [s.name() for s in tool.Ifc.schema().declaration_by_name(item).subtypes()] + classes.extend(subtypes) + queue.extend(subtypes) + schema_identifier = tool.Ifc.get_schema() + return [ + (c, c, ifcopenshell.util.doc.get_entity_doc(schema_identifier, c)["description"] or "") + for c in sorted(classes) + ] diff --git a/src/blenderbim/blenderbim/bim/module/profile/operator.py b/src/blenderbim/blenderbim/bim/module/profile/operator.py index cd339be015..453a788ec8 100644 --- a/src/blenderbim/blenderbim/bim/module/profile/operator.py +++ b/src/blenderbim/blenderbim/bim/module/profile/operator.py @@ -99,3 +99,20 @@ class EditProfile(bpy.types.Operator, tool.Ifc.Operator): ifcopenshell.api.run("profile.edit_profile", tool.Ifc.get(), profile=profile, attributes=attributes) bpy.ops.bim.load_profiles() return {"FINISHED"} + + +class AddProfileDef(bpy.types.Operator, tool.Ifc.Operator): + bl_idname = "bim.add_profile_def" + bl_label = "Add Profile" + bl_options = {"REGISTER", "UNDO"} + + def _execute(self, context): + props = context.scene.BIMProfileProperties + profile_class = props.profile_classes + if profile_class == "IfcArbitraryClosedProfileDef": + points = [(0, 0), (0.1, 0), (0.1, 0.1), (0, 0.1)] + ifcopenshell.api.run("profile.add_arbitrary_profile", tool.Ifc.get(), profile=points) + else: + ifcopenshell.api.run("profile.add_parameterized_profile", tool.Ifc.get(), ifc_class=profile_class) + bpy.ops.bim.load_profiles() + return {"FINISHED"} diff --git a/src/blenderbim/blenderbim/bim/module/profile/prop.py b/src/blenderbim/blenderbim/bim/module/profile/prop.py index 1f8f06ca33..7bfea0a221 100644 --- a/src/blenderbim/blenderbim/bim/module/profile/prop.py +++ b/src/blenderbim/blenderbim/bim/module/profile/prop.py @@ -22,6 +22,7 @@ import ifcopenshell.util.schema import ifcopenshell.util.attribute from blenderbim.bim.ifc import IfcStore from blenderbim.bim.prop import StrProperty, Attribute +from blenderbim.bim.module.profile.data import ProfileData from bpy.types import PropertyGroup from bpy.props import ( PointerProperty, @@ -35,6 +36,12 @@ from bpy.props import ( ) +def get_profile_classes(self, context): + if not ProfileData.is_loaded: + ProfileData.load() + return ProfileData.data["profile_classes"] + + class Profile(PropertyGroup): name: StringProperty(name="Name") ifc_definition_id: IntProperty(name="IFC Definition ID") @@ -46,3 +53,4 @@ class BIMProfileProperties(PropertyGroup): active_profile_index: IntProperty(name="Active Profile Index") active_profile_id: IntProperty(name="Active Profile Id") profile_attributes: CollectionProperty(name="Profile Attributes", type=Attribute) + profile_classes: EnumProperty(items=get_profile_classes, name="Profile Classes") diff --git a/src/blenderbim/blenderbim/bim/module/profile/ui.py b/src/blenderbim/blenderbim/bim/module/profile/ui.py index f351498c9d..38c6365144 100644 --- a/src/blenderbim/blenderbim/bim/module/profile/ui.py +++ b/src/blenderbim/blenderbim/bim/module/profile/ui.py @@ -50,6 +50,10 @@ class BIM_PT_profiles(Panel): if not self.props.is_editing: return + row = self.layout.row(align=True) + row.prop(self.props, "profile_classes", text="") + row.operator("bim.add_profile_def", text="", icon="ADD") + self.layout.template_list( "BIM_UL_profiles", "", diff --git a/src/blenderbim/blenderbim/bim/prop.py b/src/blenderbim/blenderbim/bim/prop.py index 4925c4ff1e..f94b79f62e 100644 --- a/src/blenderbim/blenderbim/bim/prop.py +++ b/src/blenderbim/blenderbim/bim/prop.py @@ -242,7 +242,7 @@ class Attribute(PropertyGroup): has_calculator: BoolProperty(name="Has Calculator", default=False) def get_value(self): - if self.is_null: + if self.is_optional and self.is_null: return None return getattr(self, str(self.get_value_name()), None)