Dumb slabs now auto calculate new quantities when edited

This commit is contained in:
Dion Moult
2021-06-07 15:53:12 +10:00
parent f3c1d1df31
commit 1a962a7f60
2 changed files with 77 additions and 0 deletions
@@ -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
)
@@ -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