Fix #2489. Prevent openings from being added twice and only save changed openings.

This commit is contained in:
Dion Moult
2022-10-09 15:19:42 +11:00
parent cd27d48701
commit 3ee4b1f0e3
5 changed files with 20 additions and 10 deletions
@@ -36,7 +36,7 @@ classes = (
wall.RecalculateWall,
wall.SplitWall,
opening.AddBoolean,
opening.AddElementOpening,
opening.AddFilledOpening,
opening.AddPotentialHalfSpaceSolid,
opening.AddPotentialOpening,
opening.EditOpenings,
@@ -36,9 +36,9 @@ from gpu.types import GPUShader, GPUBatch, GPUIndexBuf, GPUVertBuf, GPUVertForma
from gpu_extras.batch import batch_for_shader
class AddElementOpening(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.add_element_opening"
bl_label = "Add Element Opening"
class AddFilledOpening(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.add_filled_opening"
bl_label = "Add Filled Opening"
bl_options = {"REGISTER", "UNDO"}
voided_obj: bpy.props.StringProperty()
filling_obj: bpy.props.StringProperty()
@@ -65,7 +65,7 @@ class AddElementOpening(bpy.types.Operator, tool.Ifc.Operator):
# In this prototype, we assume openings are only added to axis-based elements
new_matrix = voided_obj.matrix_world.copy()
new_matrix.col[3] = tool.Cad.point_on_edge(target, axis).to_4d()
if filling.is_a("IfcWindow"):
if not filling.is_a("IfcDoor"):
new_matrix[2][3] = target[2]
filling_obj.matrix_world = new_matrix
bpy.context.view_layer.update()
@@ -510,7 +510,12 @@ class EditOpenings(Operator, tool.Ifc.Operator):
for opening in openings:
opening_obj = tool.Ifc.get_object(opening)
if opening_obj:
tool.Geometry.run_geometry_update_representation(obj=opening_obj)
if tool.Ifc.is_edited(opening_obj):
tool.Geometry.run_geometry_update_representation(obj=opening_obj)
elif tool.Ifc.is_moved(opening_obj):
blenderbim.core.geometry.edit_object_placement(
tool.Ifc, tool.Geometry, tool.Surveyor, obj=opening_obj
)
tool.Ifc.unlink(element=opening, obj=opening_obj)
bpy.data.objects.remove(opening_obj)
@@ -147,7 +147,7 @@ class AddConstrTypeInstance(bpy.types.Operator):
):
if instance_class in ["IfcWindow", "IfcDoor"]:
# TODO For now we are hardcoding windows and doors as a prototype
bpy.ops.bim.add_element_opening(voided_obj=building_obj.name, filling_obj=obj.name)
bpy.ops.bim.add_filled_opening(voided_obj=building_obj.name, filling_obj=obj.name)
elif self.link_to_scene:
if collection_obj and collection_obj.BIMObjectProperties.ifc_definition_id:
obj.location[2] = collection_obj.location[2] - min([v[2] for v in obj.bound_box])
@@ -407,6 +407,6 @@ class Hotkey(bpy.types.Operator, tool.Ifc.Operator):
def hotkey_A_O(self):
if AuthoringData.data["has_visible_openings"]:
bpy.ops.bim.hide_openings()
bpy.ops.bim.edit_openings()
else:
bpy.ops.bim.show_openings()
@@ -38,10 +38,15 @@ class AddOpening(bpy.types.Operator, tool.Ifc.Operator):
element1 = tool.Ifc.get_entity(obj1)
element2 = tool.Ifc.get_entity(obj2)
if type(element1) == type(element2):
if element1 and element2:
if (
element1
and element2
and not element1.is_a("IfcOpeningElement")
and not element2.is_a("IfcOpeningElement")
):
if element1.is_a("IfcWindow") or element1.is_a("IfcDoor"):
obj1, obj2 = obj2, obj1
bpy.ops.bim.add_element_opening(voided_obj=obj1.name, filling_obj=obj2.name)
bpy.ops.bim.add_filled_opening(voided_obj=obj1.name, filling_obj=obj2.name)
return {"FINISHED"}
if element2 and not element1:
obj1, obj2 = obj2, obj1