From 1eb2b65268989a072bb994a73821c4ed7c2f1a51 Mon Sep 17 00:00:00 2001 From: falken10vdl Date: Mon, 12 Jan 2026 12:19:13 +0100 Subject: [PATCH] Add flow direction handling to port connection logic and UI updates --- src/bonsai/bonsai/bim/module/system/operator.py | 9 ++++++--- src/bonsai/bonsai/bim/module/system/prop.py | 4 ++-- src/bonsai/bonsai/bim/module/system/ui.py | 7 ++++--- src/bonsai/bonsai/core/system.py | 4 ++-- .../ifcopenshell/api/system/disconnect_port.py | 2 -- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/bonsai/bonsai/bim/module/system/operator.py b/src/bonsai/bonsai/bim/module/system/operator.py index 7f298064fc..049307b32f 100644 --- a/src/bonsai/bonsai/bim/module/system/operator.py +++ b/src/bonsai/bonsai/bim/module/system/operator.py @@ -259,7 +259,8 @@ class ConnectPort(bpy.types.Operator, tool.Ifc.Operator): def _execute(self, context): obj1 = context.active_object obj2 = context.selected_objects[0] if context.selected_objects[1] == obj1 else context.selected_objects[1] - core.connect_port(tool.Ifc, port1=tool.Ifc.get_entity(obj1), port2=tool.Ifc.get_entity(obj2)) + direction = tool.Ifc.get_entity(obj1).FlowDirection or "NOTDEFINED" + core.connect_port(tool.Ifc, port1=tool.Ifc.get_entity(obj1), port2=tool.Ifc.get_entity(obj2), direction=direction) class AddRelatedPortConnection(bpy.types.Operator, tool.Ifc.Operator): @@ -286,7 +287,8 @@ class AddRelatedPortConnection(bpy.types.Operator, tool.Ifc.Operator): related_port = tool.Ifc.get_entity(port_obj) relating_port = tool.Ifc.get().by_id(self.relating_port_id) - core.connect_port(tool.Ifc, port1=relating_port, port2=related_port) + direction = relating_port.FlowDirection or "NOTDEFINED" + core.connect_port(tool.Ifc, port1=relating_port, port2=related_port, direction=direction) PortData.is_loaded = False return {"FINISHED"} @@ -356,7 +358,8 @@ class MEPConnectElements(bpy.types.Operator, tool.Ifc.Operator): ports_distance[(port1, port2)] = distance closest_ports = min(ports_distance, key=lambda x: ports_distance[x]) - core.connect_port(tool.Ifc, *closest_ports) + direction = closest_ports[0].FlowDirection or "NOTDEFINED" + core.connect_port(tool.Ifc, *closest_ports, direction=direction) bpy.ops.bim.regenerate_distribution_element() return {"FINISHED"} diff --git a/src/bonsai/bonsai/bim/module/system/prop.py b/src/bonsai/bonsai/bim/module/system/prop.py index bb72fda1a9..e4e56a79a0 100644 --- a/src/bonsai/bonsai/bim/module/system/prop.py +++ b/src/bonsai/bonsai/bim/module/system/prop.py @@ -20,7 +20,7 @@ import bpy import bonsai.bim.handler import bonsai.tool as tool import bonsai.core.system as core -from bonsai.bim.module.system.data import SystemData, PortData +from bonsai.bim.module.system.data import SystemData import bonsai.bim.module.system.decorator as decorator from bonsai.bim.prop import StrProperty, Attribute from bpy.types import PropertyGroup @@ -34,7 +34,7 @@ from bpy.props import ( FloatVectorProperty, CollectionProperty, ) -from typing import TYPE_CHECKING, Union, Optional +from typing import TYPE_CHECKING, Union def get_system_class(self: "BIMSystemProperties", context: bpy.types.Context) -> list[tuple[str, str, str]]: diff --git a/src/bonsai/bonsai/bim/module/system/ui.py b/src/bonsai/bonsai/bim/module/system/ui.py index ad8d5b5c03..5e904a3206 100644 --- a/src/bonsai/bonsai/bim/module/system/ui.py +++ b/src/bonsai/bonsai/bim/module/system/ui.py @@ -275,8 +275,6 @@ class BIM_PT_port(Panel): relating_object_name = PortData.data["port_relating_object_name"] if PortData.data["is_port"] else "" row.label(text=f"IfcDistributionPort located in: {relating_object_name}") - row.operator("bim.connect_port", icon="PLUGIN", text="") - row.operator("bim.disconnect_port", icon="UNLINKED", text="") row.operator("bim.remove_port", icon="X", text="") if not PortData.is_loaded: @@ -290,6 +288,9 @@ class BIM_PT_port(Panel): row = layout.row(align=True) cols = [row.column(align=True) for i in range(9)] + cols[3].scale_x = 1.0 + cols[6].scale_x = 1.0 + cols[8].scale_x = 1.33 flow_direction_icon = FLOW_DIRECTION_TO_ICON[element.FlowDirection or "NOTDEFINED"] connected_port = tool.System.get_connected_port(element) @@ -299,7 +300,7 @@ class BIM_PT_port(Panel): op = cols[1].operator("bim.cycle_flow_direction", text="", icon=flow_direction_icon, emboss=True) op.port_id = element.id() else: - cols[0].label(text="", icon="BLANK1") + cols[0].operator("bim.connect_port", icon="PLUGIN", text="") op = cols[1].operator("bim.cycle_flow_direction", text="", icon=flow_direction_icon, emboss=True) op.port_id = element.id() diff --git a/src/bonsai/bonsai/core/system.py b/src/bonsai/bonsai/core/system.py index 7a1df28280..87a43307b7 100644 --- a/src/bonsai/bonsai/core/system.py +++ b/src/bonsai/bonsai/core/system.py @@ -132,8 +132,8 @@ def remove_port(ifc: type[tool.Ifc], system: type[tool.System], port: ifcopenshe ifc.run("root.remove_product", product=port) -def connect_port(ifc: type[tool.Ifc], port1: ifcopenshell.entity_instance, port2: ifcopenshell.entity_instance) -> None: - ifc.run("system.connect_port", port1=port1, port2=port2) +def connect_port(ifc: type[tool.Ifc], port1: ifcopenshell.entity_instance, port2: ifcopenshell.entity_instance, direction: str = "NOTDEFINED") -> None: + ifc.run("system.connect_port", port1=port1, port2=port2, direction=direction) def disconnect_port(ifc: type[tool.Ifc], port: ifcopenshell.entity_instance) -> None: diff --git a/src/ifcopenshell-python/ifcopenshell/api/system/disconnect_port.py b/src/ifcopenshell-python/ifcopenshell/api/system/disconnect_port.py index 8ffbfcf380..c53e4ae160 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/system/disconnect_port.py +++ b/src/ifcopenshell-python/ifcopenshell/api/system/disconnect_port.py @@ -66,8 +66,6 @@ def disconnect_port(file: ifcopenshell.file, port: ifcopenshell.entity_instance) rels += port.ConnectedFrom or () for rel in rels: - rel.RelatingPort.FlowDirection = None - rel.RelatedPort.FlowDirection = None history = rel.OwnerHistory file.remove(rel) if history: