From 9acd2043d746c989e965b7bc343c598ffbdffcfa Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Mon, 30 Jan 2023 15:29:38 +0500 Subject: [PATCH] Window/Stair types added as presets in type manager --- .../blenderbim/bim/module/model/prop.py | 2 + .../blenderbim/bim/module/model/stair.py | 25 ++++---- .../blenderbim/bim/module/model/window.py | 6 +- .../blenderbim/bim/module/type/operator.py | 62 +++++++++++++++---- 4 files changed, 69 insertions(+), 26 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/model/prop.py b/src/blenderbim/blenderbim/bim/module/model/prop.py index 970f0d209c..9d7d19d616 100644 --- a/src/blenderbim/blenderbim/bim/module/model/prop.py +++ b/src/blenderbim/blenderbim/bim/module/model/prop.py @@ -241,6 +241,8 @@ class BIMModelProperties(PropertyGroup): ("LAYERSET_AXIS3", "Horizontal Layers", ""), ("PROFILESET", "Extruded Profile", ""), ("EMPTY", "Non-Geometric Type", ""), + ("WINDOW", "Window", ""), + ("STAIR", "Stair", ""), ), name="Type Template", default="MESH", diff --git a/src/blenderbim/blenderbim/bim/module/model/stair.py b/src/blenderbim/blenderbim/bim/module/model/stair.py index 5b10781915..8424f747ef 100644 --- a/src/blenderbim/blenderbim/bim/module/model/stair.py +++ b/src/blenderbim/blenderbim/bim/module/model/stair.py @@ -224,8 +224,8 @@ class BIM_OT_add_clever_stair(Operator): bl_options = {"REGISTER", "UNDO"} def execute(self, context): - ifcfile = tool.Ifc.get() - if not ifcfile: + ifc_file = tool.Ifc.get() + if not ifc_file: self.report({"ERROR"}, "You need to start IFC project first to create a stair.") return {"CANCELLED"} @@ -235,11 +235,10 @@ class BIM_OT_add_clever_stair(Operator): else: spawn_location = bpy.context.scene.cursor.location.copy() - mesh = bpy.data.meshes.new("StairFlight") + mesh = bpy.data.meshes.new("IfcStairFlight") obj = bpy.data.objects.new("StairFlight", mesh) - bpy.context.scene.collection.objects.link(obj) obj.location = spawn_location - body_context = ifcopenshell.util.representation.get_context(ifcfile, "Model", "Body", "MODEL_VIEW") + body_context = ifcopenshell.util.representation.get_context(ifc_file, "Model", "Body", "MODEL_VIEW") element = blenderbim.core.root.assign_class( tool.Ifc, tool.Collector, @@ -249,6 +248,7 @@ class BIM_OT_add_clever_stair(Operator): should_add_representation=True, context=body_context, ) + bpy.ops.object.select_all(action="DESELECT") bpy.context.view_layer.objects.active = None bpy.context.view_layer.objects.active = obj obj.select_set(True) @@ -267,8 +267,8 @@ class AddStair(bpy.types.Operator, tool.Ifc.Operator): element = tool.Ifc.get_entity(obj) props = obj.BIMStairProperties - if not element.is_a("IfcStairFlight"): - self.report({"ERROR"}, "Object has to be IfcStairFlight type to add a stair.") + if element.is_a() not in ("IfcStairFlight", "IfcStairFlightType"): + self.report({"ERROR"}, "Object has to be IfcStairFlight/IfcStairFlightType to add a stair.") return {"CANCELLED"} # need to make sure all default props will have correct units @@ -296,11 +296,12 @@ class AddStair(bpy.types.Operator, tool.Ifc.Operator): update_stair_modifier(context) # update IfcStairFlight properties - element.NumberOfRisers = props.number_of_treads + 1 - element.NumberOfTreads = props.number_of_treads - element.RiserHeight = props.height / element.NumberOfRisers - element.TreadLength = props.tread_depth element.PredefinedType = "STRAIGHT" + if element.is_a("IfcStairFlight"): + element.NumberOfRisers = props.number_of_treads + 1 + element.NumberOfTreads = props.number_of_treads + element.RiserHeight = props.height / element.NumberOfRisers + element.TreadLength = props.tread_depth return {"FINISHED"} @@ -348,12 +349,12 @@ class FinishEditingStair(bpy.types.Operator, tool.Ifc.Operator): ifcopenshell.api.run("pset.edit_pset", tool.Ifc.get(), pset=pset, properties={"Data": data}) # update IfcStairFlight properties + element.PredefinedType = "STRAIGHT" if element.is_a("IfcStairFlight"): element.NumberOfRisers = props.number_of_treads + 1 element.NumberOfTreads = props.number_of_treads element.RiserHeight = props.height / element.NumberOfRisers element.TreadLength = props.tread_depth - element.PredefinedType = "STRAIGHT" return {"FINISHED"} diff --git a/src/blenderbim/blenderbim/bim/module/model/window.py b/src/blenderbim/blenderbim/bim/module/model/window.py index 8e32197bc7..49fc130bdc 100644 --- a/src/blenderbim/blenderbim/bim/module/model/window.py +++ b/src/blenderbim/blenderbim/bim/module/model/window.py @@ -342,7 +342,6 @@ class BIM_OT_add_window(Operator): mesh = bpy.data.meshes.new("IfcWindow") obj = bpy.data.objects.new("IfcWindow", mesh) - bpy.context.scene.collection.objects.link(obj) obj.location = spawn_location body_context = ifcopenshell.util.representation.get_context(ifc_file, "Model", "Body", "MODEL_VIEW") element = blenderbim.core.root.assign_class( @@ -353,6 +352,7 @@ class BIM_OT_add_window(Operator): ifc_class="IfcWindow", should_add_representation=False ) + bpy.ops.object.select_all(action="DESELECT") bpy.context.view_layer.objects.active = None bpy.context.view_layer.objects.active = obj obj.select_set(True) @@ -371,6 +371,10 @@ class AddWindow(bpy.types.Operator, tool.Ifc.Operator): element = tool.Ifc.get_entity(obj) props = obj.BIMWindowProperties + if element.is_a() not in ("IfcWindow", "IfcWindowType"): + self.report({"ERROR"}, "Object has to be IfcWindow/IfcWindowType type to add a stair.") + return {"CANCELLED"} + # need to make sure all default props will have correct units if not props.window_added_previously: convert_property_group_from_si(props, skip_props=("is_editing", "window_type", "window_added_previously")) diff --git a/src/blenderbim/blenderbim/bim/module/type/operator.py b/src/blenderbim/blenderbim/bim/module/type/operator.py index ac2740563b..42f77ba2f0 100644 --- a/src/blenderbim/blenderbim/bim/module/type/operator.py +++ b/src/blenderbim/blenderbim/bim/module/type/operator.py @@ -177,7 +177,8 @@ class AddType(bpy.types.Operator, tool.Ifc.Operator): ifc_class = props.type_class predefined_type = props.type_predefined_type template = props.type_template - body = ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model", "Body", "MODEL_VIEW") + ifc_file = tool.Ifc.get() + body = ifcopenshell.util.representation.get_context(ifc_file, "Model", "Body", "MODEL_VIEW") if not body: return {"FINISHED"} if template == "MESH": @@ -209,7 +210,7 @@ class AddType(bpy.types.Operator, tool.Ifc.Operator): ifc_representation_class=None, ) elif template in ("LAYERSET_AXIS2", "LAYERSET_AXIS3"): - unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) + unit_scale = ifcopenshell.util.unit.calculate_unit_scale(ifc_file) obj = bpy.data.objects.new("TYPEX", None) element = blenderbim.core.root.assign_class( tool.Ifc, @@ -222,27 +223,27 @@ class AddType(bpy.types.Operator, tool.Ifc.Operator): context=body, ifc_representation_class=None, ) - materials = tool.Ifc.get().by_type("IfcMaterial") + materials = ifc_file.by_type("IfcMaterial") if materials: material = materials[0] # Arbitrarily pick a material else: material = self.add_default_material() rel = ifcopenshell.api.run( - "material.assign_material", tool.Ifc.get(), product=element, type="IfcMaterialLayerSet" + "material.assign_material", ifc_file, product=element, type="IfcMaterialLayerSet" ) layer_set = rel.RelatingMaterial - layer = ifcopenshell.api.run("material.add_layer", tool.Ifc.get(), layer_set=layer_set, material=material) + layer = ifcopenshell.api.run("material.add_layer", ifc_file, layer_set=layer_set, material=material) thickness = 0.1 # Arbitrary metric thickness for now layer.LayerThickness = thickness / unit_scale - pset = ifcopenshell.api.run("pset.add_pset", tool.Ifc.get(), product=element, name="EPset_Parametric") + pset = ifcopenshell.api.run("pset.add_pset", ifc_file, product=element, name="EPset_Parametric") if template == "LAYERSET_AXIS2": axis = "AXIS2" elif template == "LAYERSET_AXIS3": axis = "AXIS3" - ifcopenshell.api.run("pset.edit_pset", tool.Ifc.get(), pset=pset, properties={"LayerSetDirection": axis}) + ifcopenshell.api.run("pset.edit_pset", ifc_file, pset=pset, properties={"LayerSetDirection": axis}) elif template == "PROFILESET": - unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) + unit_scale = ifcopenshell.util.unit.calculate_unit_scale(ifc_file) obj = bpy.data.objects.new("TYPEX", None) element = blenderbim.core.root.assign_class( tool.Ifc, @@ -255,22 +256,22 @@ class AddType(bpy.types.Operator, tool.Ifc.Operator): context=body, ifc_representation_class=None, ) - materials = tool.Ifc.get().by_type("IfcMaterial") + materials = ifc_file.by_type("IfcMaterial") if materials: material = materials[0] # Arbitrarily pick a material else: material = self.add_default_material() size = 0.5 / unit_scale - profile = tool.Ifc.get().create_entity("IfcRectangleProfileDef", ProfileType="AREA", XDim=size, YDim=size) + profile = ifc_file.create_entity("IfcRectangleProfileDef", ProfileType="AREA", XDim=size, YDim=size) rel = ifcopenshell.api.run( - "material.assign_material", tool.Ifc.get(), product=element, type="IfcMaterialProfileSet" + "material.assign_material", ifc_file, product=element, type="IfcMaterialProfileSet" ) profile_set = rel.RelatingMaterial material_profile = ifcopenshell.api.run( - "material.add_profile", tool.Ifc.get(), profile_set=profile_set, material=material + "material.add_profile", ifc_file, profile_set=profile_set, material=material ) ifcopenshell.api.run( - "material.assign_profile", tool.Ifc.get(), material_profile=material_profile, profile=profile + "material.assign_profile", ifc_file, material_profile=material_profile, profile=profile ) elif template == "EMPTY": obj = bpy.data.objects.new("TYPEX", None) @@ -285,6 +286,41 @@ class AddType(bpy.types.Operator, tool.Ifc.Operator): context=body, ifc_representation_class=None, ) + elif template == "WINDOW": + mesh = bpy.data.meshes.new("IfcWindow") + obj = bpy.data.objects.new("TYPEX", mesh) + element = blenderbim.core.root.assign_class( + tool.Ifc, + tool.Collector, + tool.Root, + obj=obj, + ifc_class="IfcWindowType", + should_add_representation=False + ) + bpy.ops.object.select_all(action="DESELECT") + bpy.context.view_layer.objects.active = None + bpy.context.view_layer.objects.active = obj + obj.select_set(True) + bpy.ops.bim.add_window() + + elif template == "STAIR": + mesh = bpy.data.meshes.new("IfcStairFlight") + obj = bpy.data.objects.new("TYPEX", mesh) + element = blenderbim.core.root.assign_class( + tool.Ifc, + tool.Collector, + tool.Root, + obj=obj, + ifc_class="IfcStairFlightType", + should_add_representation=True, + context=body, + ) + bpy.ops.object.select_all(action="DESELECT") + bpy.context.view_layer.objects.active = None + bpy.context.view_layer.objects.active = obj + obj.select_set(True) + bpy.ops.bim.add_stair() + bpy.ops.bim.load_type_thumbnails(ifc_class=ifc_class) return {"FINISHED"}