From 1a962a7f607a5b7770aa0a145342c5b13fab3698 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Mon, 7 Jun 2021 15:53:12 +1000 Subject: [PATCH] Dumb slabs now auto calculate new quantities when edited --- .../blenderbim/bim/module/model/handler.py | 3 + .../blenderbim/bim/module/model/slab.py | 74 +++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/src/blenderbim/blenderbim/bim/module/model/handler.py b/src/blenderbim/blenderbim/bim/module/model/handler.py index 14a623761c..353f97d334 100644 --- a/src/blenderbim/blenderbim/bim/module/model/handler.py +++ b/src/blenderbim/blenderbim/bim/module/model/handler.py @@ -36,6 +36,9 @@ def load_post(*args): ifcopenshell.api.add_post_listener( "geometry.add_representation", "BlenderBIM.DumbSlab.GenerateFootprint", slab.generate_footprint ) + ifcopenshell.api.add_post_listener( + "geometry.add_representation", "BlenderBIM.DumbSlab.CalculateQuantities", slab.calculate_quantities + ) ifcopenshell.api.add_pre_listener( "material.edit_layer", "BlenderBIM.DumbSlab.RegenerateFromLayer", slab.DumbSlabPlaner().regenerate_from_layer ) diff --git a/src/blenderbim/blenderbim/bim/module/model/slab.py b/src/blenderbim/blenderbim/bim/module/model/slab.py index 2933856b08..26b47def02 100644 --- a/src/blenderbim/blenderbim/bim/module/model/slab.py +++ b/src/blenderbim/blenderbim/bim/module/model/slab.py @@ -10,6 +10,7 @@ import blenderbim.bim.handler from blenderbim.bim.ifc import IfcStore from math import pi, degrees from mathutils import Vector, Matrix +from ifcopenshell.api.pset.data import Data as PsetData from ifcopenshell.api.material.data import Data as MaterialData from blenderbim.bim.module.geometry.helper import Helper @@ -121,6 +122,79 @@ def generate_footprint(usecase_path, ifc_file, settings): bpy.data.meshes.remove(mesh) +def calculate_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.DumbSlab": + return + qto = ifcopenshell.api.run( + "pset.add_qto", ifc_file, should_run_listeners=False, product=product, name="Qto_SlabBaseQuantities" + ) + length = obj.dimensions[0] / unit_scale + width = obj.dimensions[1] / unit_scale + depth = obj.dimensions[2] / unit_scale + + perimeter = 0 + helper = Helper(ifc_file) + indices = helper.auto_detect_arbitrary_profile_with_voids_extruded_area_solid(settings["geometry"]) + + bm = bmesh.new() + bm.from_mesh(settings["geometry"]) + bm.verts.ensure_lookup_table() + + def calculate_profile_length(indices): + indices.append(indices[0]) # Close the loop + edge_vert_pairs = list(zip(indices, indices[1:])) + return sum([(bm.verts[p[1]].co - bm.verts[p[0]].co).length for p in edge_vert_pairs]) + + perimeter += calculate_profile_length(indices["profile"]) + for inner_indices in indices["inner_curves"]: + perimeter += calculate_profile_length(inner_indices) + + bm.free() + + if product.HasOpenings: + # TODO: calculate gross / net + gross_area = 0 + net_area = 0 + gross_volume = 0 + net_volume = 0 + else: + bm = bmesh.new() + bm.from_object(obj, bpy.context.evaluated_depsgraph_get()) + bm.faces.ensure_lookup_table() + gross_area = sum([f.calc_area() for f in bm.faces if f.normal.z > 0.9]) + net_area = gross_area + gross_volume = bm.calc_volume() + net_volume = gross_volume + bm.free() + + properties={ + "Depth": round(depth, 2), + "Perimeter": round(perimeter, 2), + "GrossArea": round(gross_area, 2), + "NetArea": round(net_area, 2), + "GrossVolume": round(gross_volume, 2), + "NetVolume": round(net_volume, 2), + } + + if round(obj.dimensions[0] * obj.dimensions[1] * obj.dimensions[2], 2) == round(gross_volume, 2): + properties.update({ + "Length": round(length, 2), + "Width": round(width, 2), + }) + else: + properties.update({ + "Length": None, + "Width": None, + }) + + ifcopenshell.api.run( "pset.edit_qto", ifc_file, should_run_listeners=False, qto=qto, properties=properties) + PsetData.load(ifc_file, obj.BIMObjectProperties.ifc_definition_id) + + class DumbSlabGenerator: def __init__(self, relating_type): self.relating_type = relating_type