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( ifcopenshell.api.add_post_listener(
"geometry.add_representation", "BlenderBIM.DumbSlab.GenerateFootprint", slab.generate_footprint "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( ifcopenshell.api.add_pre_listener(
"material.edit_layer", "BlenderBIM.DumbSlab.RegenerateFromLayer", slab.DumbSlabPlaner().regenerate_from_layer "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 blenderbim.bim.ifc import IfcStore
from math import pi, degrees from math import pi, degrees
from mathutils import Vector, Matrix from mathutils import Vector, Matrix
from ifcopenshell.api.pset.data import Data as PsetData
from ifcopenshell.api.material.data import Data as MaterialData from ifcopenshell.api.material.data import Data as MaterialData
from blenderbim.bim.module.geometry.helper import Helper 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) 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: class DumbSlabGenerator:
def __init__(self, relating_type): def __init__(self, relating_type):
self.relating_type = relating_type self.relating_type = relating_type