mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
Dumb walls now auto calculate length, width, height, and simple volume quantities when being updated
This commit is contained in:
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user