Fix #3673. Bug where a split wall broke flipped doors.

Instead of regenerating fills upon splitting walls, placements are
preserved exactly.
This commit is contained in:
Dion Moult
2025-04-17 16:28:05 +10:00
parent c45e3b0099
commit 5a6476a57f
3 changed files with 100 additions and 3 deletions
+62
View File
@@ -224,6 +224,68 @@ Scenario: Regenerate a wall - after doing nothing interesting
And the object "IfcWall/Wall" dimensions are "1,0.1,3"
And the object "IfcWall/Wall" bottom left corner is at "0,0,0"
Scenario: Insert door into wall
Given an empty IFC project
And I load the demo construction library
And I set "scene.BIMModelProperties.ifc_class" to "IfcWallType"
And the variable "element_type" is "[e for e in {ifc}.by_type('IfcWallType') if e.Name == 'WAL100'][0].id()"
And I set "scene.BIMModelProperties.relating_type_id" to "{element_type}"
And I press "bim.add_occurrence"
And the object "IfcWall/Wall" is selected
And the cursor is at "10,0,0"
# Extend the wall
And I press "bim.hotkey(hotkey='S_E')"
When I set "scene.BIMModelProperties.ifc_class" to "IfcDoorType"
And the variable "element_type" is "[e for e in {ifc}.by_type('IfcDoorType') if e.Name == 'DT01'][0].id()"
And the cursor is at "7,0,0"
And I press "bim.add_occurrence"
Then the object "IfcDoor/Door" is at "7,0,0"
And the object "IfcWall/Wall" is filled by "IfcDoor/Door"
Scenario: Flip a door inserted in a wall
Given an empty IFC project
And I load the demo construction library
And I set "scene.BIMModelProperties.ifc_class" to "IfcWallType"
And the variable "element_type" is "[e for e in {ifc}.by_type('IfcWallType') if e.Name == 'WAL100'][0].id()"
And I set "scene.BIMModelProperties.relating_type_id" to "{element_type}"
And I press "bim.add_occurrence"
And the object "IfcWall/Wall" is selected
And the cursor is at "10,0,0"
# Extend the wall
And I press "bim.hotkey(hotkey='S_E')"
# Insert a door
And I set "scene.BIMModelProperties.ifc_class" to "IfcDoorType"
And the variable "element_type" is "[e for e in {ifc}.by_type('IfcDoorType') if e.Name == 'DT01'][0].id()"
And the cursor is at "7,0,0"
And I press "bim.add_occurrence"
When the object "IfcDoor/Door" is selected
And I press "bim.hotkey(hotkey='S_F')"
Then the object "IfcDoor/Door" is at "8.01,0.1,0"
Scenario: Split a wall which has a flipped door
Given an empty IFC project
And I load the demo construction library
And I set "scene.BIMModelProperties.ifc_class" to "IfcWallType"
And the variable "element_type" is "[e for e in {ifc}.by_type('IfcWallType') if e.Name == 'WAL100'][0].id()"
And I set "scene.BIMModelProperties.relating_type_id" to "{element_type}"
And I press "bim.add_occurrence"
And the object "IfcWall/Wall" is selected
And the cursor is at "10,0,0"
# Extend the wall
And I press "bim.hotkey(hotkey='S_E')"
# Insert a door
And I set "scene.BIMModelProperties.ifc_class" to "IfcDoorType"
And the variable "element_type" is "[e for e in {ifc}.by_type('IfcDoorType') if e.Name == 'DT01'][0].id()"
And the cursor is at "7,0,0"
And I press "bim.add_occurrence"
# Flip the door
And the object "IfcDoor/Door" is selected
And I press "bim.hotkey(hotkey='S_F')"
When the cursor is at "5,0,0"
And the object "IfcWall/Wall" is selected
And I press "bim.hotkey(hotkey='S_K')"
Then the object "IfcDoor/Door" is at "8.01,0.1,0"
Scenario: Add a slab
Given an empty IFC project
And I load the demo construction library
+20
View File
@@ -1057,6 +1057,25 @@ def the_object_name_has_number_vertices(name, number):
assert total == int(number), f"We found {total} vertices"
@then(parsers.parse('the object "{name}" is filled by "{name2}"'))
def the_object_name_is_filled_by_filling(name, name2):
ifc = tool.Ifc.get()
element = ifc.by_id(tool.Blender.get_ifc_definition_id(the_object_name_exists(name)))
debug = {}
for rel in ifcopenshell.util.element.get_openings(element):
filling = None
opening = rel.RelatedOpeningElement
for rel2 in opening.HasFillings or []:
filling = rel2.RelatedBuildingElement
break
debug[opening] = filling
filling_obj = tool.Ifc.get_object(filling)
if filling_obj and filling_obj.name == name2:
return True
debug = "\n".join([f"{k} filled by {v}" for k, v in debug.items()])
assert False, f"Object {name} is not filled by {name2}.\n{debug}"
@then(parsers.parse('the void "{name}" is filled by "{filling}"'))
def the_void_name_is_filled_by_filling(name, filling):
ifc = tool.Ifc.get()
@@ -1357,6 +1376,7 @@ def i_add_a_construction_library():
@given(parsers.parse('the cursor is at "{location}"'))
@when(parsers.parse('the cursor is at "{location}"'))
def the_cursor_is_at_location(location):
bpy.context.scene.cursor.location = [float(co) for co in location.split(",")]