New feature to merge aligned walls and retain parametric connections

This commit is contained in:
Dion Moult
2022-09-19 09:11:57 +10:00
parent 4842891fd7
commit fbd4177d08
4 changed files with 80 additions and 5 deletions
@@ -26,11 +26,12 @@ classes = (
product.AlignProduct,
product.DynamicallyVoidProduct,
workspace.Hotkey,
wall.JoinWall,
wall.AlignWall,
wall.FlipWall,
wall.SplitWall,
wall.JoinWall,
wall.MergeWall,
wall.RecalculateWall,
wall.SplitWall,
opening.AddElementOpening,
profile.ExtendProfile,
prop.BIMModelProperties,
@@ -61,9 +61,6 @@ def load_post(*args):
IfcStore.add_element_listener(slab.element_listener)
IfcStore.add_element_listener(profile.element_listener)
ifcopenshell.api.add_post_listener(
"geometry.add_representation", "BlenderBIM.DumbWall.GenerateAxis", wall.generate_axis
)
ifcopenshell.api.add_post_listener(
"geometry.add_representation", "BlenderBIM.DumbWall.CalculateQuantities", wall.calculate_quantities
)
@@ -185,6 +185,22 @@ class SplitWall(bpy.types.Operator):
return {"FINISHED"}
class MergeWall(bpy.types.Operator):
bl_idname = "bim.merge_wall"
bl_label = "Merge Wall"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return context.selected_objects
def execute(self, context):
selected_objs = [o for o in context.selected_objects if o.data and hasattr(o.data, "transform")]
if len(selected_objs) == 2:
DumbWallJoiner().merge([o for o in selected_objs if o != context.active_object][0], context.active_object)
return {"FINISHED"}
class RecalculateWall(bpy.types.Operator):
bl_idname = "bim.recalculate_wall"
bl_label = "Recalculate Wall"
@@ -754,6 +770,63 @@ class DumbWallJoiner:
self.recreate_wall(element1, wall1, axis1["reference"], axis1["reference"])
self.recreate_wall(element2, wall2, axis2["reference"], axis2["reference"])
def merge(self, wall1, wall2):
element1 = tool.Ifc.get_entity(wall1)
element2 = tool.Ifc.get_entity(wall2)
axis1 = self.get_wall_axis(wall1)
axis2 = self.get_wall_axis(wall2)
angle = tool.Cad.angle_edges(axis1["reference"], axis2["reference"], signed=False, degrees=True)
if not tool.Cad.is_x(angle, 0):
return
intersect1, connection1 = mathutils.geometry.intersect_point_line(axis2["reference"][0], *axis1["reference"])
if not tool.Cad.is_x((intersect1 - axis2["reference"][0]).length, 0):
return
intersect2, connection2 = mathutils.geometry.intersect_point_line(axis2["reference"][1], *axis1["reference"])
if not tool.Cad.is_x((intersect2 - axis2["reference"][1]).length, 0):
return
changed_connections = set()
if connection1 < 0:
changed_connections.add("ATSTART")
axis1["reference"][0] = intersect2 if connection2 < connection1 else intersect1
elif connection1 > 1:
changed_connections.add("ATEND")
axis1["reference"][1] = intersect2 if connection2 > connection1 else intersect1
for connection in changed_connections:
ifcopenshell.api.run("geometry.disconnect_path", tool.Ifc.get(), element=element1, connection_type=connection)
for rel in element2.ConnectedTo:
if rel.RelatingConnectionType in changed_connections:
other = tool.Ifc.get_object(rel.RelatedElement)
ifcopenshell.api.run(
"geometry.connect_path",
tool.Ifc.get(),
relating_element=element1,
related_element=rel.RelatedElement,
relating_connection=rel.RelatingConnectionType,
related_connection=rel.RelatedConnectionType,
)
for rel in element2.ConnectedFrom:
if rel.RelatedConnectionType in changed_connections:
ifcopenshell.api.run(
"geometry.connect_path",
tool.Ifc.get(),
relating_element=rel.RelatingElement,
related_element=element1,
relating_connection=rel.RelatingConnectionType,
related_connection=rel.RelatedConnectionType,
)
self.recreate_wall(element1, wall1, axis1["reference"], axis1["reference"])
bpy.data.objects.remove(wall2)
def duplicate_wall(self, wall1):
wall2 = wall1.copy()
wall2.data = wall2.data.copy()
@@ -43,6 +43,7 @@ class BimTool(WorkSpaceTool):
("bim.hotkey", {"type": "E", "value": "PRESS", "shift": True}, {"properties": [("hotkey", "S_E")]}),
("bim.join_wall", {"type": "T", "value": "PRESS", "shift": True}, {"properties": [("join_type", "L")]}),
("bim.recalculate_wall", {"type": "Y", "value": "PRESS", "shift": True}, {"properties": []}),
("bim.merge_wall", {"type": "M", "value": "PRESS", "shift": True}, {"properties": []}),
("bim.flip_wall", {"type": "F", "value": "PRESS", "shift": True}, {"properties": []}),
("bim.split_wall", {"type": "S", "value": "PRESS", "shift": True}, {"properties": []}),
("bim.hotkey", {"type": "X", "value": "PRESS", "shift": True}, {"properties": [("hotkey", "S_X")]}),
@@ -141,6 +142,9 @@ class BimTool(WorkSpaceTool):
row = layout.row(align=True)
row.label(text="", icon="EVENT_SHIFT")
row.label(text="Regen Connections", icon="EVENT_Y")
row = layout.row(align=True)
row.label(text="", icon="EVENT_SHIFT")
row.label(text="Merge", icon="EVENT_M")
row = layout.row()
row.label(text="Wall Tools")