mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-26 18:21:59 +00:00
Formwork area calculation now unions objects before remeshing to account for overlapping geometry
This commit is contained in:
@@ -67,26 +67,27 @@ def calculate_formwork_area(objs, context):
|
|||||||
copied_objs = []
|
copied_objs = []
|
||||||
result = 0
|
result = 0
|
||||||
|
|
||||||
for obj in objs:
|
copied_obj = objs[0].copy()
|
||||||
new_obj = obj.copy()
|
copied_obj.data = objs[0].data.copy()
|
||||||
new_obj.data = obj.data.copy()
|
copied_obj.animation_data_clear()
|
||||||
new_obj.animation_data_clear()
|
context.collection.objects.link(copied_obj)
|
||||||
context.collection.objects.link(new_obj)
|
|
||||||
copied_objs.append(new_obj)
|
|
||||||
|
|
||||||
if len(objs) > 1:
|
if len(objs) > 1:
|
||||||
context_override = {}
|
for i, obj in enumerate(objs):
|
||||||
context_override["object"] = context_override["active_object"] = copied_objs[0]
|
if i == 0:
|
||||||
context_override["selected_objects"] = context_override["selected_editable_objects"] = copied_objs
|
continue
|
||||||
bpy.ops.object.join(context_override)
|
modifier = copied_obj.modifiers.new(type="BOOLEAN", name="Boolean")
|
||||||
|
modifier.operation = "UNION"
|
||||||
|
modifier.object = obj
|
||||||
|
bpy.ops.object.modifier_apply({"object": copied_obj}, modifier="Boolean")
|
||||||
|
|
||||||
copied_objs[0].name = "Formwork"
|
copied_obj.name = "Formwork"
|
||||||
copied_objs[0].BIMObjectProperties.ifc_definition_id = 0
|
copied_obj.BIMObjectProperties.ifc_definition_id = 0
|
||||||
modifier = copied_objs[0].modifiers.new("Formwork", "REMESH")
|
modifier = copied_obj.modifiers.new("Formwork", "REMESH")
|
||||||
modifier.mode = "SHARP"
|
modifier.mode = "SHARP"
|
||||||
# This hardcoded value may be optimised through a better understanding of the octree division.
|
# 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.
|
# These values are based off some trial and error heuristics I've learned through experience.
|
||||||
max_dim = max(copied_objs[0].dimensions)
|
max_dim = max(copied_obj.dimensions)
|
||||||
if max_dim > 45:
|
if max_dim > 45:
|
||||||
modifier.octree_depth = 9
|
modifier.octree_depth = 9
|
||||||
elif max_dim > 35:
|
elif max_dim > 35:
|
||||||
@@ -98,7 +99,7 @@ def calculate_formwork_area(objs, context):
|
|||||||
else:
|
else:
|
||||||
modifier.octree_depth = 5
|
modifier.octree_depth = 5
|
||||||
|
|
||||||
mesh = copied_objs[0].evaluated_get(context.evaluated_depsgraph_get()).to_mesh()
|
mesh = copied_obj.evaluated_get(context.evaluated_depsgraph_get()).to_mesh()
|
||||||
for polygon in mesh.polygons:
|
for polygon in mesh.polygons:
|
||||||
if polygon.normal.z > 0.5:
|
if polygon.normal.z > 0.5:
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -28,3 +28,13 @@ Scenario: Calculate object volumes
|
|||||||
And the object "Cube" is selected
|
And the object "Cube" is selected
|
||||||
When I press "bim.calculate_object_volumes"
|
When I press "bim.calculate_object_volumes"
|
||||||
Then "scene.BIMQtoProperties.qto_result" is "8.0"
|
Then "scene.BIMQtoProperties.qto_result" is "8.0"
|
||||||
|
|
||||||
|
Scenario: Calculate formwork areas
|
||||||
|
Given an empty Blender session
|
||||||
|
And I add a cube
|
||||||
|
And I add a cube of size "1" at "1,0,0"
|
||||||
|
And the object "Cube" is selected
|
||||||
|
And additionally the object "Cube.001" is selected
|
||||||
|
When I set "scene.BIMQtoProperties.qto_methods" to "FORMWORK"
|
||||||
|
And I press "bim.execute_qto_method"
|
||||||
|
Then "scene.BIMQtoProperties.qto_result" is "21.5"
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ def i_add_a_cube():
|
|||||||
bpy.ops.object.modifier_add(type="ARRAY")
|
bpy.ops.object.modifier_add(type="ARRAY")
|
||||||
|
|
||||||
|
|
||||||
|
@given(parsers.parse('I add a cube of size "{size}" at "{location}"'))
|
||||||
@when(parsers.parse('I add a cube of size "{size}" at "{location}"'))
|
@when(parsers.parse('I add a cube of size "{size}" at "{location}"'))
|
||||||
def i_add_a_cube_of_size_size_at_location(size, location):
|
def i_add_a_cube_of_size_size_at_location(size, location):
|
||||||
bpy.ops.mesh.primitive_cube_add(size=float(size), location=[float(co) for co in location.split(",")])
|
bpy.ops.mesh.primitive_cube_add(size=float(size), location=[float(co) for co in location.split(",")])
|
||||||
|
|||||||
Reference in New Issue
Block a user