More Ports UI

Created more UI for ports.

Now you can see the list of ports from UI and what objects they are connected to, you can quickly select any ports/connected objects or disconnect objects.

From port UI you can see what object's it located on and what object it's connected to and quickly jump across them.

Demo - https://imgur.com/a/Gu4Vz7V
This commit is contained in:
Andrej730
2023-08-09 11:16:57 +05:00
parent 86b63242d8
commit dbc482dfee
3 changed files with 130 additions and 24 deletions
@@ -91,8 +91,15 @@ class PortData:
@classmethod @classmethod
def load(cls): def load(cls):
element = tool.Ifc.get_entity(bpy.context.active_object)
cls.element = element
is_port = cls.is_port()
cls.data = { cls.data = {
"total_ports": cls.total_ports(), "total_ports": cls.total_ports(),
"located_ports_data": cls.located_ports_data(),
"is_port": is_port,
"port_connected_object": cls.port_connected_object() if is_port else None,
"port_relating_object": cls.port_relating_object() if is_port else None,
} }
cls.is_loaded = True cls.is_loaded = True
@@ -100,3 +107,36 @@ class PortData:
def total_ports(cls): def total_ports(cls):
element = tool.Ifc.get_entity(bpy.context.active_object) element = tool.Ifc.get_entity(bpy.context.active_object)
return len(ifcopenshell.util.system.get_ports(element)) return len(ifcopenshell.util.system.get_ports(element))
@classmethod
def is_port(cls):
return cls.element and cls.element.is_a("IfcDistributionPort")
@classmethod
def port_relating_object(cls):
return tool.Ifc.get_object(tool.System.get_port_relating_element(cls.element))
@classmethod
def port_connected_object(cls):
connected_port = tool.System.get_connected_port(cls.element)
if not connected_port:
return
connected_element = tool.System.get_port_relating_element(connected_port)
return tool.Ifc.get_object(connected_element)
@classmethod
def located_ports_data(cls):
element = tool.Ifc.get_entity(bpy.context.active_object)
ports = ifcopenshell.util.system.get_ports(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))
else:
connected_element = None
data.append((port, port_obj, connected_element))
return data
@@ -205,8 +205,14 @@ class DisconnectPort(bpy.types.Operator, Operator):
bl_label = "Disconnect Ports" bl_label = "Disconnect Ports"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
element_id: bpy.props.IntProperty(default=0, options={"SKIP_SAVE"})
def _execute(self, context): def _execute(self, context):
core.disconnect_port(tool.Ifc, port=tool.Ifc.get_entity(context.active_object)) if self.element_id != 0:
element = tool.Ifc.get().by_id(self.element_id)
else:
element = tool.Ifc.get_entity(context.active_object)
core.disconnect_port(tool.Ifc, port=element)
class SetFlowDirection(bpy.types.Operator, Operator): class SetFlowDirection(bpy.types.Operator, Operator):
@@ -23,6 +23,14 @@ from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.module.system.data import SystemData, ObjectSystemData, PortData from blenderbim.bim.module.system.data import SystemData, ObjectSystemData, PortData
FLOW_DIRECTION_TO_ICON = {
"SOURCE": "FORWARD",
"SINK": "BACK",
"SOURCEANDSINK": "ARROW_LEFTRIGHT",
"NOTDEFINED": "RESTRICT_INSTANCED_ON",
}
class BIM_PT_systems(Panel): class BIM_PT_systems(Panel):
bl_label = "Systems" bl_label = "Systems"
bl_idname = "BIM_PT_systems" bl_idname = "BIM_PT_systems"
@@ -156,11 +164,43 @@ class BIM_PT_ports(Panel):
self.props = context.scene.BIMSystemProperties self.props = context.scene.BIMSystemProperties
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.label(text=f"{PortData.data['total_ports']} Ports Found", icon="PLUGIN") total_ports = PortData.data["total_ports"]
row.label(text=f"{total_ports} Ports Found", icon="PLUGIN")
row.operator("bim.show_ports", icon="HIDE_OFF", text="") row.operator("bim.show_ports", icon="HIDE_OFF", text="")
row.operator("bim.hide_ports", icon="HIDE_ON", text="") row.operator("bim.hide_ports", icon="HIDE_ON", text="")
row.operator("bim.add_port", icon="ADD", text="") row.operator("bim.add_port", icon="ADD", text="")
if total_ports == 0:
return
row = self.layout.row(align=True)
row.label(text="Ports located on object and connected objects:")
row = self.layout.row(align=True)
cols = [row.column(align=True) for i in range(6)]
for i, port_data in enumerate(PortData.data["located_ports_data"]):
port, port_obj, connected_obj = port_data
flow_direction_icon = FLOW_DIRECTION_TO_ICON[port.FlowDirection or "NOTDEFINED"]
if port_obj:
cols[0].label(text="", icon=flow_direction_icon)
cols[1].operator("bim.select_entity", text="", icon="RESTRICT_SELECT_OFF").ifc_id = port.id()
cols[2].label(text=port_obj.name)
else:
cols[0].label(text="", icon=flow_direction_icon)
cols[1].label(text="", icon="HIDE_ON")
cols[2].label(text="Port is hidden")
if connected_obj:
cols[3].operator("bim.disconnect_port", text="", icon="UNLINKED").element_id = port.id()
cols[4].operator(
"bim.select_entity", text="", icon="RESTRICT_SELECT_OFF"
).ifc_id = connected_obj.BIMObjectProperties.ifc_definition_id
cols[5].label(text=f"{connected_obj.name}")
else:
cols[3].label(text="", icon="UNLINKED")
cols[4].label(text="", icon="BLANK1")
cols[5].label(text="Port is disconnected")
class BIM_PT_port(Panel): class BIM_PT_port(Panel):
bl_label = "Port" bl_label = "Port"
@@ -184,36 +224,56 @@ class BIM_PT_port(Panel):
def draw(self, context): def draw(self, context):
self.props = context.scene.BIMSystemProperties self.props = context.scene.BIMSystemProperties
element = tool.Ifc.get_entity(context.active_object)
port_class = element.is_a()
layout = self.layout layout = self.layout
row = layout.row(align=True) row = layout.row(align=True)
row.label(text=port_class) row.label(text="IfcDistributionPort")
row.operator("bim.connect_port", icon="PLUGIN", text="") row.operator("bim.connect_port", icon="PLUGIN", text="")
row.operator("bim.disconnect_port", icon="UNLINKED", text="") row.operator("bim.disconnect_port", icon="UNLINKED", text="")
row.operator("bim.remove_port", icon="X", text="") row.operator("bim.remove_port", icon="X", text="")
if port_class == "IfcDistributionPort": if not PortData.is_loaded:
current_flow_direction = str(element.FlowDirection) PortData.load()
row = layout.row(align=True)
row.label(text="Flow Direction:")
row.label(text=current_flow_direction)
# TODO: replace with enum property? if not PortData.data["is_port"]:
flow_directions = ( return
("SOURCE", "FORWARD"),
("SINK", "BACK"),
("SOURCEANDSINK", "ARROW_LEFTRIGHT"),
("NOTDEFINED", "RESTRICT_INSTANCED_ON"),
)
row = layout.row(align=True) element = tool.Ifc.get_entity(context.active_object)
row.label(text="Change Flow Direction:") current_flow_direction = str(element.FlowDirection)
for flow_direction, icon in flow_directions: row = layout.row(align=True)
row = layout.row() row.label(text="Flow Direction:")
row.operator("bim.set_flow_direction", icon=icon, text=flow_direction).direction = flow_direction row.label(text=current_flow_direction)
if flow_direction == current_flow_direction:
row.enabled = False # port located on
row = layout.row(align=True)
relating_object = PortData.data["port_relating_object"]
row.label(text="Port located on:")
row.label(text=relating_object.name)
row.operator(
"bim.select_entity", text="", icon="RESTRICT_SELECT_OFF"
).ifc_id = relating_object.BIMObjectProperties.ifc_definition_id
# object connected to the port
row = layout.row(align=True)
connected_object = PortData.data["port_connected_object"]
if connected_object:
row.label(text="Port connected to:")
row.label(text=connected_object.name)
row.operator(
"bim.select_entity", text="", icon="RESTRICT_SELECT_OFF"
).ifc_id = connected_object.BIMObjectProperties.ifc_definition_id
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
).direction = flow_direction
if flow_direction == current_flow_direction:
row.enabled = False
class BIM_UL_systems(UIList): class BIM_UL_systems(UIList):