Dumb walls now auto calculate length, width, height, and simple volume quantities when being updated

This commit is contained in:
Dion Moult
2021-05-24 19:28:47 +10:00
parent 1abf854f01
commit bfe9213f67
3 changed files with 52 additions and 7 deletions
@@ -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
@@ -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"}
@@ -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(