diff --git a/src/blenderbim/blenderbim/bim/module/system/data.py b/src/blenderbim/blenderbim/bim/module/system/data.py index 9dd348fe13..3ba63ae1f7 100644 --- a/src/blenderbim/blenderbim/bim/module/system/data.py +++ b/src/blenderbim/blenderbim/bim/module/system/data.py @@ -102,12 +102,13 @@ class PortData: "port_connected_object": cls.port_connected_object() if is_port else None, "port_relating_object": cls.port_relating_object() if is_port else None, } + # AFTER located_ports_data + cls.data["selected_objects_flow_direction"] = cls.selected_objects_flow_direction() if not is_port else None cls.is_loaded = True @classmethod def total_ports(cls): - element = tool.Ifc.get_entity(bpy.context.active_object) - return len(ifcopenshell.util.system.get_ports(element)) + return len(ifcopenshell.util.system.get_ports(cls.element)) @classmethod def is_port(cls): @@ -127,21 +128,26 @@ class PortData: @classmethod def located_ports_data(cls): - element = tool.Ifc.get_entity(bpy.context.active_object) - ports = ifcopenshell.util.system.get_ports(element) + ports = ifcopenshell.util.system.get_ports(cls.element) data = [] for port in ports: port_obj = tool.Ifc.get_object(port) connected_port = tool.System.get_connected_port(port) if connected_port: - connected_element = tool.Ifc.get_object(tool.System.get_port_relating_element(connected_port)) + connected_obj = tool.Ifc.get_object(tool.System.get_port_relating_element(connected_port)) else: - connected_element = None + connected_obj = None - data.append((port, port_obj, connected_element)) + data.append((port, port_obj, connected_obj)) return data + @classmethod + def selected_objects_flow_direction(cls): + for port, port_obj, connected_obj in cls.data["located_ports_data"]: + if connected_obj in bpy.context.selected_objects: + return port.FlowDirection + class SystemDecorationData: data = {} diff --git a/src/blenderbim/blenderbim/bim/module/system/operator.py b/src/blenderbim/blenderbim/bim/module/system/operator.py index 0b703495b3..4d40d9c36d 100644 --- a/src/blenderbim/blenderbim/bim/module/system/operator.py +++ b/src/blenderbim/blenderbim/bim/module/system/operator.py @@ -270,12 +270,59 @@ class SetFlowDirection(bpy.types.Operator, Operator): bl_options = {"REGISTER", "UNDO"} direction: bpy.props.StringProperty() + @classmethod + def description(cls, context, operator): + if not PortData.is_loaded: + PortData.load() + + port = PortData.data["is_port"] + if port: + return f"Set port flow direction to {operator.direction}" + else: + return f"Set flow direction to {operator.direction} for active element relatively to the selected" + + @classmethod + def poll(cls, context): + if not PortData.is_loaded: + PortData.load() + + port = PortData.data["is_port"] + if not port and not len(context.selected_objects) == 2: + cls.poll_message_set("Need to select port or 2 connected objects.") + return False + return True + def _execute(self, context): - port = tool.Ifc.get_entity(context.active_object) - second_port = tool.System.get_connected_port(port) - if not second_port: - self.report({"ERROR"}, "To set flow direction port has to be connected to another one.") - return - core.set_flow_direction( - tool.Ifc, tool.System, port=tool.Ifc.get_entity(context.active_object), direction=self.direction - ) + element = tool.Ifc.get_entity(context.active_object) + + if element.is_a("IfcDistributionPort"): + second_port = tool.System.get_connected_port(element) + if not second_port: + self.report({"ERROR"}, "To set flow direction port has to be connected to another one.") + return + core.set_flow_direction(tool.Ifc, tool.System, port=element, direction=self.direction) + return {"FINISHED"} + + selected_elements = [ + entity + for entity in (tool.Ifc.get_entity(o) for o in context.selected_objects) + if entity and tool.System.is_mep_element(element) + ] + + if len(selected_elements) != 2: + self.report({"ERROR"}, "To set flow direction selected two connected MEP elements or just 1 port.") + return {"CANCELLED"} + + other_element = selected_elements[selected_elements[0] == element] + active_element_ports = tool.System.get_ports(element) + other_element_ports = tool.System.get_ports(other_element) + + for port in active_element_ports: + connected_port = tool.System.get_connected_port(port) + if connected_port in other_element_ports: + core.set_flow_direction(tool.Ifc, tool.System, port=port, direction=self.direction) + tool.Blender.update_viewport() + return {"FINISHED"} + + self.report({"ERROR"}, "Selected elements are not connected to set the flow direction") + return {"CANCELLED"} diff --git a/src/blenderbim/blenderbim/bim/module/system/ui.py b/src/blenderbim/blenderbim/bim/module/system/ui.py index d8e6b764c6..6e20514bac 100644 --- a/src/blenderbim/blenderbim/bim/module/system/ui.py +++ b/src/blenderbim/blenderbim/bim/module/system/ui.py @@ -24,10 +24,10 @@ from blenderbim.bim.module.system.data import SystemData, ObjectSystemData, Port FLOW_DIRECTION_TO_ICON = { - "SOURCE": "FORWARD", - "SINK": "BACK", + "SOURCE": "REMOVE", + "SINK": "ADD", "SOURCEANDSINK": "ARROW_LEFTRIGHT", - "NOTDEFINED": "RESTRICT_INSTANCED_ON", + "NOTDEFINED": "CHECKBOX_DEHLT", } @@ -179,6 +179,19 @@ class BIM_PT_ports(Panel): if total_ports == 0: return + row = self.layout.row(align=True) + row.label(text="Change Flow Direction:") + + current_flow_direction = PortData.data["selected_objects_flow_direction"] + for flow_direction in FLOW_DIRECTION_TO_ICON.keys(): + row.operator( + "bim.set_flow_direction", + icon=FLOW_DIRECTION_TO_ICON[flow_direction], + depress=flow_direction == current_flow_direction, + text="", + ).direction = flow_direction + row.enabled = len(context.selected_objects) == 2 + row = self.layout.row(align=True) row.label(text="Ports located on object and connected objects:") row = self.layout.row(align=True) @@ -270,16 +283,15 @@ class BIM_PT_port(Panel): else: row.label(text="Port is not connected to any element") - # TODO: replace with enum property? row = layout.row(align=True) row.label(text="Change Flow Direction:") for flow_direction in FLOW_DIRECTION_TO_ICON.keys(): - row = layout.row() row.operator( - "bim.set_flow_direction", icon=FLOW_DIRECTION_TO_ICON[flow_direction], text=flow_direction + "bim.set_flow_direction", + icon=FLOW_DIRECTION_TO_ICON[flow_direction], + depress=flow_direction == current_flow_direction, + text="", ).direction = flow_direction - if flow_direction == current_flow_direction: - row.enabled = False class BIM_UL_systems(UIList):