Fix #2850. Splitting walls now reassigns voids and fills to the appropriate split portion.

This commit is contained in:
Dion Moult
2023-03-11 15:08:26 +11:00
parent 381570cd9e
commit 7041a4a4a9
@@ -34,6 +34,7 @@ import blenderbim.tool as tool
from blenderbim.bim.ifc import IfcStore from blenderbim.bim.ifc import IfcStore
from math import pi, sin, cos, degrees, radians from math import pi, sin, cos, degrees, radians
from mathutils import Vector, Matrix from mathutils import Vector, Matrix
from blenderbim.bim.module.model.opening import FilledOpeningGenerator
def element_listener(element, obj): def element_listener(element, obj):
@@ -759,10 +760,10 @@ class DumbWallJoiner:
return return
axis1 = tool.Model.get_wall_axis(wall1) axis1 = tool.Model.get_wall_axis(wall1)
axis2 = copy.deepcopy(axis1) axis2 = copy.deepcopy(axis1)
intersect, connection = mathutils.geometry.intersect_point_line(target.to_2d(), *axis1["reference"]) intersect, cut_percentage = mathutils.geometry.intersect_point_line(target.to_2d(), *axis1["reference"])
if connection < 0 or connection > 1 or tool.Cad.is_x(connection, (0, 1)): if cut_percentage < 0 or cut_percentage > 1 or tool.Cad.is_x(cut_percentage, (0, 1)):
return return
connection = "ATEND" if connection > 0.5 else "ATSTART" connection = "ATEND" if cut_percentage > 0.5 else "ATSTART"
wall2 = self.duplicate_wall(wall1) wall2 = self.duplicate_wall(wall1)
element2 = tool.Ifc.get_entity(wall2) element2 = tool.Ifc.get_entity(wall2)
@@ -770,6 +771,40 @@ class DumbWallJoiner:
ifcopenshell.api.run("geometry.disconnect_path", tool.Ifc.get(), element=element1, connection_type="ATEND") ifcopenshell.api.run("geometry.disconnect_path", tool.Ifc.get(), element=element1, connection_type="ATEND")
ifcopenshell.api.run("geometry.disconnect_path", tool.Ifc.get(), element=element2, connection_type="ATSTART") ifcopenshell.api.run("geometry.disconnect_path", tool.Ifc.get(), element=element2, connection_type="ATSTART")
# During the duplication process, unfilled voids are copied, so we need
# to check openings on both element1 and element2. Let's check element1
# first.
for opening in [
r.RelatedOpeningElement for r in element1.HasOpenings if not r.RelatedOpeningElement.HasFillings
]:
opening_matrix = Matrix(ifcopenshell.util.placement.get_local_placement(opening.ObjectPlacement).tolist())
opening_location = opening_matrix.col[3].to_3d()
_, opening_position = mathutils.geometry.intersect_point_line(opening_location.to_2d(), *axis1["reference"])
if opening_position > cut_percentage:
# The opening should be removed from element1.
ifcopenshell.api.run("void.remove_opening", tool.Ifc.get(), opening=opening)
# Now let's check element2.
for opening in [
r.RelatedOpeningElement for r in element2.HasOpenings if not r.RelatedOpeningElement.HasFillings
]:
opening_matrix = Matrix(ifcopenshell.util.placement.get_local_placement(opening.ObjectPlacement).tolist())
opening_location = opening_matrix.col[3].to_3d()
_, opening_position = mathutils.geometry.intersect_point_line(opening_location.to_2d(), *axis1["reference"])
if opening_position < cut_percentage:
# The opening should be removed from element2.
ifcopenshell.api.run("void.remove_opening", tool.Ifc.get(), opening=opening)
# During the duplication process, filled voids are not copied. So we
# only need to check fillings on the original element1.
for opening in [r.RelatedOpeningElement for r in element1.HasOpenings if r.RelatedOpeningElement.HasFillings]:
filling_obj = tool.Ifc.get_object(opening.HasFillings[0].RelatedBuildingElement)
filling_location = filling_obj.matrix_world.translation
_, filling_position = mathutils.geometry.intersect_point_line(filling_location.to_2d(), *axis1["reference"])
if filling_position > cut_percentage:
# The filling should be moved from element1 to element2.
FilledOpeningGenerator().generate(filling_obj, wall2, target=filling_obj.matrix_world.translation)
axis1["reference"][1] = intersect axis1["reference"][1] = intersect
axis2["reference"][0] = intersect axis2["reference"][0] = intersect
self.recreate_wall(element1, wall1, axis1["reference"], axis1["reference"]) self.recreate_wall(element1, wall1, axis1["reference"], axis1["reference"])