mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-24 17:29:57 +00:00
New formwork area calculation feature
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import bpy
|
||||||
import bmesh
|
import bmesh
|
||||||
|
|
||||||
|
|
||||||
@@ -11,3 +12,50 @@ def calculate_volume(obj):
|
|||||||
result = bm.calc_volume()
|
result = bm.calc_volume()
|
||||||
bm.free()
|
bm.free()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def calculate_formwork_area(objs):
|
||||||
|
"""
|
||||||
|
Formwork is defined as the surface area required to cover all exposed
|
||||||
|
surfaces of one or more objects, excluding top surfaces (i.e. that have a
|
||||||
|
face normal with a significant Z component).
|
||||||
|
"""
|
||||||
|
copied_objs = []
|
||||||
|
result = 0
|
||||||
|
|
||||||
|
for obj in objs:
|
||||||
|
new_obj = obj.copy()
|
||||||
|
new_obj.data = obj.data.copy()
|
||||||
|
new_obj.animation_data_clear()
|
||||||
|
bpy.context.collection.objects.link(new_obj)
|
||||||
|
copied_objs.append(new_obj)
|
||||||
|
|
||||||
|
context_override = {}
|
||||||
|
context_override["object"] = context_override["active_object"] = copied_objs[0]
|
||||||
|
context_override["selected_objects"] = context_override["selected_editable_objects"] = copied_objs
|
||||||
|
bpy.ops.object.join(context_override)
|
||||||
|
|
||||||
|
copied_objs[0].name = "Formwork"
|
||||||
|
copied_objs[0].BIMObjectProperties.ifc_definition_id = 0
|
||||||
|
modifier = copied_objs[0].modifiers.new("Formwork", "REMESH")
|
||||||
|
modifier.mode = "SHARP"
|
||||||
|
# This hardcoded value may be optimised through a better understanding of the octree division.
|
||||||
|
# These values are based off some trial and error heuristics I've learned through experience.
|
||||||
|
max_dim = max(copied_objs[0].dimensions)
|
||||||
|
if max_dim > 45:
|
||||||
|
modifier.octree_depth = 9
|
||||||
|
elif max_dim > 35:
|
||||||
|
modifier.octree_depth = 8
|
||||||
|
elif max_dim > 12:
|
||||||
|
modifier.octree_depth = 7
|
||||||
|
elif max_dim > 5:
|
||||||
|
modifier.octree_depth = 6
|
||||||
|
else:
|
||||||
|
modifier.octree_depth = 5
|
||||||
|
|
||||||
|
mesh = copied_objs[0].evaluated_get(bpy.context.evaluated_depsgraph_get()).to_mesh()
|
||||||
|
for polygon in mesh.polygons:
|
||||||
|
if polygon.normal.z > 0.5:
|
||||||
|
continue
|
||||||
|
result += polygon.area
|
||||||
|
return result
|
||||||
|
|||||||
@@ -69,6 +69,8 @@ class ExecuteQtoMethod(bpy.types.Operator):
|
|||||||
elif props.qto_methods == "VOLUME":
|
elif props.qto_methods == "VOLUME":
|
||||||
for obj in bpy.context.selected_objects:
|
for obj in bpy.context.selected_objects:
|
||||||
result += helper.calculate_volume(obj)
|
result += helper.calculate_volume(obj)
|
||||||
|
elif props.qto_methods == "FORMWORK":
|
||||||
|
result = helper.calculate_formwork_area(bpy.context.selected_objects)
|
||||||
props.qto_result = str(round(result, 3))
|
props.qto_result = str(round(result, 3))
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
@@ -88,6 +90,8 @@ class QuantifyObjects(bpy.types.Operator):
|
|||||||
result = helper.calculate_height(obj)
|
result = helper.calculate_height(obj)
|
||||||
elif props.qto_methods == "VOLUME":
|
elif props.qto_methods == "VOLUME":
|
||||||
result = helper.calculate_volume(obj)
|
result = helper.calculate_volume(obj)
|
||||||
|
elif props.qto_methods == "FORMWORK":
|
||||||
|
result = helper.calculate_formwork_area([obj])
|
||||||
if not result:
|
if not result:
|
||||||
continue
|
continue
|
||||||
result = round(result, 3)
|
result = round(result, 3)
|
||||||
|
|||||||
Reference in New Issue
Block a user