diff --git a/src/blenderbim/blenderbim/bim/module/model/operator.py b/src/blenderbim/blenderbim/bim/module/model/operator.py index 5f1ab76021..a602b5b839 100644 --- a/src/blenderbim/blenderbim/bim/module/model/operator.py +++ b/src/blenderbim/blenderbim/bim/module/model/operator.py @@ -402,6 +402,7 @@ class DumbWallGenerator: self.relating_type = relating_type def generate(self): + self.file = IfcStore.get_file() unit_scale = ifcopenshell.util.unit.calculate_unit_scale(IfcStore.get_file()) thicknesses = [] for rel in self.relating_type.HasAssociations: @@ -550,4 +551,7 @@ class DumbWallGenerator: self.collection.objects.link(obj) bpy.ops.bim.assign_class(obj=obj.name, ifc_class="IfcWall") bpy.ops.bim.assign_type(relating_type=self.relating_type.id(), related_object=obj.name) + element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id) + pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, Name="EPset_Parametric") + ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, Properties={"Engine": "BlenderBIM.DumbWall"}) return obj diff --git a/src/blenderbim/blenderbim/bim/module/parametric/operator.py b/src/blenderbim/blenderbim/bim/module/parametric/operator.py index 78edab65a2..bf76155294 100644 --- a/src/blenderbim/blenderbim/bim/module/parametric/operator.py +++ b/src/blenderbim/blenderbim/bim/module/parametric/operator.py @@ -1,8 +1,12 @@ import bpy +import bmesh import ifcopenshell import ifcopenshell.api +import ifcopenshell.util.unit +import ifcopenshell.util.element import ifcopenshell.util.representation from blenderbim.bim.ifc import IfcStore +from ifcopenshell.api.pset.data import Data as PsetData def generate_box(usecase_path, ifc_file, **settings): @@ -29,10 +33,48 @@ def generate_box(usecase_path, ifc_file, **settings): ) +def calculate_dumb_quantities(usecase_path, ifc_file, **settings): + unit_scale = ifcopenshell.util.unit.calculate_unit_scale(ifc_file) + obj = settings["blender_object"] + product = ifc_file.by_id(obj.BIMObjectProperties.ifc_definition_id) + parametric = ifcopenshell.util.element.get_psets(product).get("EPset_Parametric") + if not parametric or parametric["Engine"] != "BlenderBIM.DumbWall": + return + qto = ifcopenshell.api.run( + "pset.add_qto", ifc_file, should_run_listeners=False, product=product, Name="Qto_WallBaseQuantities" + ) + length = obj.dimensions[0] / unit_scale + width = obj.dimensions[1] / unit_scale + height = obj.dimensions[2] / unit_scale + + if product.HasOpenings: + # TODO: calculate gross / net + gross_volume = 0 + net_volume = 0 + else: + bm = bmesh.new() + bm.from_mesh(obj.data) + gross_volume = bm.calc_volume() + net_volume = gross_volume + bm.free() + + ifcopenshell.api.run("pset.edit_qto", ifc_file, should_run_listeners=False, qto=qto, Properties={ + "Length": round(length, 2), + "Width": round(width, 2), + "Height": round(height, 2), + "GrossVolume": round(gross_volume, 2), + "NetVolume": round(net_volume, 2) + }) + PsetData.load(ifc_file, obj.BIMObjectProperties.ifc_definition_id) + + class ActivateParametricEngine(bpy.types.Operator): bl_idname = "bim.activate_parametric_engine" bl_label = "Activate Parametric Engine" def execute(self, context): ifcopenshell.api.add_post_listener("geometry.add_representation", IfcStore.get_file(), generate_box) + ifcopenshell.api.add_post_listener( + "geometry.add_representation", IfcStore.get_file(), calculate_dumb_quantities + ) return {"FINISHED"} diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_representation.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_representation.py index 26c844bffc..bcb6571175 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_representation.py +++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_representation.py @@ -44,11 +44,11 @@ class Usecase: return self.create_variable_representation() def evaluate_geometry(self): - + for modifier in self.settings["blender_object"].modifiers: if modifier.type == "BOOLEAN": modifier.show_viewport = False - + mesh = self.settings["blender_object"].evaluated_get(bpy.context.evaluated_depsgraph_get()).to_mesh() bm = bmesh.new() bm.from_mesh(mesh) @@ -57,23 +57,22 @@ class Usecase: if not self.settings["should_force_triangulation"]: bmesh.ops.dissolve_limit( bm, - angle_limit=0.00174533, + angle_limit=0.00174533, # 1 degree use_dissolve_boundaries=False, verts=bm.verts[:], edges=bm.edges[:], - delimit={'MATERIAL'} + delimit={"MATERIAL"}, ) bm.to_mesh(mesh) bm.free() del bm self.settings["geometry"] = mesh - + for modifier in self.settings["blender_object"].modifiers: if modifier.type == "BOOLEAN": modifier.show_viewport = True - def create_model_representation(self): if self.settings["context"].is_a() == "IfcGeometricRepresentationContext": return self.create_variable_representation() @@ -200,7 +199,7 @@ class Usecase: "XLength": self.convert_si_to_unit(width), "YLength": self.convert_si_to_unit(height), "ZLength": self.convert_si_to_unit(self.settings["geometry"].clip_end), - } + }, ) return self.file.createIfcShapeRepresentation(