Skip to content

Commit 29d4a8d

Browse files
committed
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
1 parent 2c1c13f commit 29d4a8d

File tree

3 files changed

+131
-25
lines changed

3 files changed

+131
-25
lines changed

src/blenderbim/blenderbim/bim/module/system/data.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,52 @@ class PortData:
9191

9292
@classmethod
9393
def load(cls):
94+
element = tool.Ifc.get_entity(bpy.context.active_object)
95+
cls.element = element
96+
is_port = cls.is_port()
9497
cls.data = {
9598
"total_ports": cls.total_ports(),
99+
"located_ports_data": cls.located_ports_data(),
100+
"is_port": is_port,
101+
"port_connected_object": cls.port_connected_object() if is_port else None,
102+
"port_relating_object": cls.port_relating_object() if is_port else None,
96103
}
97104
cls.is_loaded = True
98105

99106
@classmethod
100107
def total_ports(cls):
101108
element = tool.Ifc.get_entity(bpy.context.active_object)
102109
return len(ifcopenshell.util.system.get_ports(element))
110+
111+
@classmethod
112+
def is_port(cls):
113+
return cls.element and cls.element.is_a("IfcDistributionPort")
114+
115+
@classmethod
116+
def port_relating_object(cls):
117+
return tool.Ifc.get_object(tool.System.get_port_relating_element(cls.element))
118+
119+
@classmethod
120+
def port_connected_object(cls):
121+
connected_port = tool.System.get_connected_port(cls.element)
122+
if not connected_port:
123+
return
124+
connected_element = tool.System.get_port_relating_element(connected_port)
125+
return tool.Ifc.get_object(connected_element)
126+
127+
@classmethod
128+
def located_ports_data(cls):
129+
element = tool.Ifc.get_entity(bpy.context.active_object)
130+
ports = ifcopenshell.util.system.get_ports(element)
131+
132+
data = []
133+
for port in ports:
134+
port_obj = tool.Ifc.get_object(port)
135+
connected_port = tool.System.get_connected_port(port)
136+
if connected_port:
137+
connected_element = tool.Ifc.get_object(tool.System.get_port_relating_element(connected_port))
138+
else:
139+
connected_element = None
140+
141+
data.append((port, port_obj, connected_element))
142+
return data

src/blenderbim/blenderbim/bim/module/system/operator.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,14 @@ class DisconnectPort(bpy.types.Operator, Operator):
205205
bl_label = "Disconnect Ports"
206206
bl_options = {"REGISTER", "UNDO"}
207207

208+
element_id: bpy.props.IntProperty(default=0, options={"SKIP_SAVE"})
209+
208210
def _execute(self, context):
209-
core.disconnect_port(tool.Ifc, port=tool.Ifc.get_entity(context.active_object))
211+
if self.element_id != 0:
212+
element = tool.Ifc.get().by_id(self.element_id)
213+
else:
214+
element = tool.Ifc.get_entity(context.active_object)
215+
core.disconnect_port(tool.Ifc, port=element)
210216

211217

212218
class SetFlowDirection(bpy.types.Operator, Operator):

src/blenderbim/blenderbim/bim/module/system/ui.py

Lines changed: 84 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@
2323
from blenderbim.bim.module.system.data import SystemData, ObjectSystemData, PortData
2424

2525

26+
FLOW_DIRECTION_TO_ICON = {
27+
"SOURCE": "FORWARD",
28+
"SINK": "BACK",
29+
"SOURCEANDSINK": "ARROW_LEFTRIGHT",
30+
"NOTDEFINED": "RESTRICT_INSTANCED_ON",
31+
}
32+
33+
2634
class BIM_PT_systems(Panel):
2735
bl_label = "Systems"
2836
bl_idname = "BIM_PT_systems"
@@ -156,11 +164,43 @@ def draw(self, context):
156164
self.props = context.scene.BIMSystemProperties
157165

158166
row = self.layout.row(align=True)
159-
row.label(text=f"{PortData.data['total_ports']} Ports Found", icon="PLUGIN")
167+
total_ports = PortData.data["total_ports"]
168+
row.label(text=f"{total_ports} Ports Found", icon="PLUGIN")
160169
row.operator("bim.show_ports", icon="HIDE_OFF", text="")
161170
row.operator("bim.hide_ports", icon="HIDE_ON", text="")
162171
row.operator("bim.add_port", icon="ADD", text="")
163172

173+
if total_ports == 0:
174+
return
175+
176+
row = self.layout.row(align=True)
177+
row.label(text="Ports located on object and connected objects:")
178+
row = self.layout.row(align=True)
179+
cols = [row.column(align=True) for i in range(6)]
180+
181+
for i, port_data in enumerate(PortData.data["located_ports_data"]):
182+
port, port_obj, connected_obj = port_data
183+
flow_direction_icon = FLOW_DIRECTION_TO_ICON[port.FlowDirection or "NOTDEFINED"]
184+
if port_obj:
185+
cols[0].label(text="", icon=flow_direction_icon)
186+
cols[1].operator("bim.select_entity", text="", icon="RESTRICT_SELECT_OFF").ifc_id = port.id()
187+
cols[2].label(text=port_obj.name)
188+
else:
189+
cols[0].label(text="", icon=flow_direction_icon)
190+
cols[1].label(text="", icon="HIDE_ON")
191+
cols[2].label(text="Port is hidden")
192+
193+
if connected_obj:
194+
cols[3].operator("bim.disconnect_port", text="", icon="UNLINKED").element_id = port.id()
195+
cols[4].operator(
196+
"bim.select_entity", text="", icon="RESTRICT_SELECT_OFF"
197+
).ifc_id = connected_obj.BIMObjectProperties.ifc_definition_id
198+
cols[5].label(text=f"{connected_obj.name}")
199+
else:
200+
cols[3].label(text="", icon="UNLINKED")
201+
cols[4].label(text="", icon="BLANK1")
202+
cols[5].label(text="Port is disconnected")
203+
164204

165205
class BIM_PT_port(Panel):
166206
bl_label = "Port"
@@ -184,36 +224,56 @@ def poll(cls, context):
184224
def draw(self, context):
185225
self.props = context.scene.BIMSystemProperties
186226

187-
element = tool.Ifc.get_entity(context.active_object)
188-
port_class = element.is_a()
189227
layout = self.layout
190228
row = layout.row(align=True)
191-
row.label(text=port_class)
229+
row.label(text="IfcDistributionPort")
192230
row.operator("bim.connect_port", icon="PLUGIN", text="")
193231
row.operator("bim.disconnect_port", icon="UNLINKED", text="")
194232
row.operator("bim.remove_port", icon="X", text="")
195233

196-
if port_class == "IfcDistributionPort":
197-
current_flow_direction = str(element.FlowDirection)
198-
row = layout.row(align=True)
199-
row.label(text="Flow Direction:")
200-
row.label(text=current_flow_direction)
201-
202-
# TODO: replace with enum property?
203-
flow_directions = (
204-
("SOURCE", "FORWARD"),
205-
("SINK", "BACK"),
206-
("SOURCEANDSINK", "ARROW_LEFTRIGHT"),
207-
("NOTDEFINED", "RESTRICT_INSTANCED_ON"),
208-
)
234+
if not PortData.is_loaded:
235+
PortData.load()
209236

210-
row = layout.row(align=True)
211-
row.label(text="Change Flow Direction:")
212-
for flow_direction, icon in flow_directions:
213-
row = layout.row()
214-
row.operator("bim.set_flow_direction", icon=icon, text=flow_direction).direction = flow_direction
215-
if flow_direction == current_flow_direction:
216-
row.enabled = False
237+
if not PortData.data["is_port"]:
238+
return
239+
240+
element = tool.Ifc.get_entity(context.active_object)
241+
current_flow_direction = str(element.FlowDirection)
242+
row = layout.row(align=True)
243+
row.label(text="Flow Direction:")
244+
row.label(text=current_flow_direction)
245+
246+
# port located on
247+
row = layout.row(align=True)
248+
relating_object = PortData.data["port_relating_object"]
249+
row.label(text="Port located on:")
250+
row.label(text=relating_object.name)
251+
row.operator(
252+
"bim.select_entity", text="", icon="RESTRICT_SELECT_OFF"
253+
).ifc_id = relating_object.BIMObjectProperties.ifc_definition_id
254+
255+
# object connected to the port
256+
row = layout.row(align=True)
257+
connected_object = PortData.data["port_connected_object"]
258+
if connected_object:
259+
row.label(text="Port connected to:")
260+
row.label(text=connected_object.name)
261+
row.operator(
262+
"bim.select_entity", text="", icon="RESTRICT_SELECT_OFF"
263+
).ifc_id = connected_object.BIMObjectProperties.ifc_definition_id
264+
else:
265+
row.label(text="Port is not connected to any element")
266+
267+
# TODO: replace with enum property?
268+
row = layout.row(align=True)
269+
row.label(text="Change Flow Direction:")
270+
for flow_direction in FLOW_DIRECTION_TO_ICON.keys():
271+
row = layout.row()
272+
row.operator(
273+
"bim.set_flow_direction", icon=FLOW_DIRECTION_TO_ICON[flow_direction], text=flow_direction
274+
).direction = flow_direction
275+
if flow_direction == current_flow_direction:
276+
row.enabled = False
217277

218278

219279
class BIM_UL_systems(UIList):

0 commit comments

Comments
 (0)