option to set active system

Now it's possible to set in UI active system (currently it's done "select" button next to the system).

Also changed the elements that are going to be decorated with system decorator. Previously it was decorating all the mep elements in the projects which was very performance heavy on large projects.
This commit is contained in:
Andrej730
2023-10-20 14:02:26 +05:00
parent b318509cba
commit 0d43ef0736
9 changed files with 85 additions and 39 deletions
@@ -162,7 +162,9 @@ class SystemDecorationData:
@classmethod
def load(cls):
cls.data = {}
cls.data = {
"decorated_elements": cls.decorated_elements(),
}
cls.is_loaded = True
cls.elements_ports_positions = {}
@@ -189,6 +191,29 @@ class SystemDecorationData:
cls.elements_ports_positions[element] = ports_data
return cls.elements_ports_positions[element]
@classmethod
def decorated_elements(cls):
if not ObjectSystemData.is_loaded:
ObjectSystemData.load()
# Priority:
# 1. currently selected systems
# 2. active system
# 3. if previous steps didn't worked - decorate connected elements
decorated_elements = set()
if ObjectSystemData.data["systems"]:
for system in ObjectSystemData.data["systems"]:
system = tool.Ifc.get().by_id(system["id"])
decorated_elements.update(ifcopenshell.util.system.get_system_elements(system))
elif active_system := tool.System.get_active_system():
decorated_elements = set(ifcopenshell.util.system.get_system_elements(active_system))
if not decorated_elements:
decorated_elements += ObjectSystemData.data["connected_elements"]
return decorated_elements
class ZonesData:
data = {}
@@ -196,7 +221,7 @@ class ZonesData:
@classmethod
def load(cls):
cls.data = { "total_zones": cls.total_zones() }
cls.data = {"total_zones": cls.total_zones()}
cls.is_loaded = True
@classmethod
@@ -210,7 +235,7 @@ class ActiveObjectZonesData:
@classmethod
def load(cls):
cls.data = { "zones": cls.zones() }
cls.data = {"zones": cls.zones()}
cls.is_loaded = True
@classmethod
@@ -68,7 +68,7 @@ class EditSystem(bpy.types.Operator, Operator):
def _execute(self, context):
core.edit_system(
tool.Ifc, tool.System, system=tool.Ifc.get().by_id(context.scene.BIMSystemProperties.active_system_id)
tool.Ifc, tool.System, system=tool.Ifc.get().by_id(context.scene.BIMSystemProperties.edited_system_id)
)
@@ -64,7 +64,8 @@ class BIMSystemProperties(PropertyGroup):
is_adding: BoolProperty(name="Is Adding", default=False)
systems: CollectionProperty(name="Systems", type=System)
active_system_index: IntProperty(name="Active System Index")
active_system_id: IntProperty(name="Active System Id", description="Id of the currrently edited system")
active_system_id: IntProperty(name="Active System Id")
edited_system_id: IntProperty(name="Edited System Id")
system_class: EnumProperty(items=get_system_class, name="Class")
should_draw_decorations: BoolProperty(
name="Should Draw Decorations", description="Toggle system decorations", update=toggle_decorations
@@ -59,21 +59,34 @@ class BIM_PT_systems(Panel):
if not ObjectSystemData.is_loaded:
ObjectSystemData.load()
self.props = context.scene.BIMSystemProperties
def draw_system_ui(row, system_id, system_name, system_class):
row = self.layout.row(align=True)
row.label(text=system_name, icon=SYSTEM_ICONS[system_class])
op = row.operator("bim.select_system_products", text="", icon="RESTRICT_SELECT_OFF")
op.system = system_id
op = row.operator("bim.unassign_system", text="", icon="X")
op.system = system_id
self.props = context.scene.BIMSystemProperties
row = self.layout.row(align=True)
row.prop(self.props, "should_draw_decorations")
for system in ObjectSystemData.data["systems"]:
row = self.layout.row()
if active_system := tool.System.get_active_system():
row.label(text=f"Active system:")
row = self.layout.row(align=True)
row.label(text=system["name"], icon=SYSTEM_ICONS[system["ifc_class"]])
op = row.operator("bim.select_system_products", text="", icon="RESTRICT_SELECT_OFF")
op.system = system["id"]
op = row.operator("bim.unassign_system", text="", icon="X")
op.system = system["id"]
draw_system_ui(row, active_system.id(), active_system.Name, active_system.is_a())
else:
row.label(text="No active system is selected")
if not ObjectSystemData.data["systems"]:
self.layout.label(text="No System associated with Active Object")
if ObjectSystemData.data["systems"]:
row = self.layout.row()
row.label(text="Active object systems:")
for system in ObjectSystemData.data["systems"]:
row = self.layout.row(align=True)
draw_system_ui(row, system["id"], system["name"], system["ifc_class"])
else:
self.layout.label(text="No System associated with active object")
row = self.layout.row(align=True)
row.label(text="{} Systems Found in Project".format(SystemData.data["total_systems"]), icon="OUTLINER")
@@ -96,7 +109,7 @@ class BIM_PT_systems(Panel):
"active_system_index",
)
if self.props.active_system_id:
if self.props.edited_system_id:
self.draw_editable_ui(context)
def draw_editable_ui(self, context):
@@ -316,7 +329,6 @@ class BIM_PT_active_object_zones(Panel):
def poll(cls, context):
return tool.Ifc.get() and context.active_object and tool.Ifc.get_entity(context.active_object)
def draw(self, context):
if not ActiveObjectZonesData.is_loaded:
ActiveObjectZonesData.load()
@@ -338,12 +350,12 @@ class BIM_UL_systems(UIList):
row.label(text=item.name, icon=SYSTEM_ICONS[item.ifc_class])
system_id = item.ifc_definition_id
row.operator("bim.assign_system", text="", icon="ADD").system = item.ifc_definition_id
if context.scene.BIMSystemProperties.active_system_id == system_id:
if context.scene.BIMSystemProperties.edited_system_id == system_id:
op = row.operator("bim.select_system_products", text="", icon="RESTRICT_SELECT_OFF")
op.system = system_id
row.operator("bim.edit_system", text="", icon="CHECKMARK")
row.operator("bim.disable_editing_system", text="", icon="CANCEL")
elif context.scene.BIMSystemProperties.active_system_id:
elif context.scene.BIMSystemProperties.edited_system_id:
op = row.operator("bim.select_system_products", text="", icon="RESTRICT_SELECT_OFF")
op.system = system_id
op = row.operator("bim.remove_system", text="", icon="X")
+2 -1
View File
@@ -47,7 +47,7 @@ def remove_system(ifc, system_tool, system=None):
def enable_editing_system(system_tool, system=None):
system_tool.import_system_attributes(system)
system_tool.set_active_system(system)
system_tool.set_active_edited_system(system)
def disable_editing_system(system):
@@ -64,6 +64,7 @@ def unassign_system(ifc, system=None, product=None):
def select_system_products(system_tool, system=None):
system_tool.select_system_products(system)
system_tool.set_active_system(system)
def show_ports(ifc, system, spatial, element=None):
+1
View File
@@ -916,6 +916,7 @@ class System:
def run_geometry_edit_object_placement(cls, obj=None): pass
def run_root_assign_class(cls, obj=None, ifc_class=None, predefined_type=None, should_add_representation=True, context=None, ifc_representation_class=None): pass
def select_system_products(cls, system): pass
def set_active_edited_system(cls, system): pass
def set_active_system(cls, system): pass
+20 -15
View File
@@ -80,7 +80,7 @@ class System(blenderbim.core.tool.System):
@classmethod
def disable_editing_system(cls):
bpy.context.scene.BIMSystemProperties.active_system_id = 0
bpy.context.scene.BIMSystemProperties.edited_system_id = 0
@classmethod
def disable_system_editing_ui(cls):
@@ -191,10 +191,19 @@ class System(blenderbim.core.tool.System):
def select_system_products(cls, system):
tool.Spatial.select_products(ifcopenshell.util.system.get_system_elements(system))
@classmethod
def set_active_edited_system(cls, system):
bpy.context.scene.BIMSystemProperties.edited_system_id = system.id()
@classmethod
def set_active_system(cls, system):
bpy.context.scene.BIMSystemProperties.active_system_id = system.id()
@classmethod
def get_active_system(cls):
system_props = bpy.context.scene.BIMSystemProperties
return tool.Ifc.get_entity_by_id(system_props.active_system_id)
@classmethod
def get_decoration_data(cls):
all_vertices = []
@@ -220,33 +229,29 @@ class System(blenderbim.core.tool.System):
if not SystemDecorationData.is_loaded:
SystemDecorationData.load()
object_system_data = ObjectSystemData.data
selected_elements = object_system_data["connected_elements"]
class FlowDirection(Enum):
BACKWARD = -1
FORWARD = 1
BOTH = 2
AMBIGUOUS = 0
# TODO: get only objects visible in viewport
objects = set(bpy.data.objects) - set(bpy.data.collections["Types"].objects)
for obj in objects:
connected_elements = ObjectSystemData.data["connected_elements"]
for element in SystemDecorationData.data["decorated_elements"]:
start_vert_i = len(all_vertices)
obj = tool.Ifc.get_object(element)
# skip stuff without objects, like distribution ports
if not obj:
continue
if obj.hide_get():
continue
if not isinstance(obj.data, bpy.types.Mesh):
continue
element = tool.Ifc.get_entity(obj)
if not element:
continue
if not cls.is_mep_element(element):
continue
selected_element = element in selected_elements
selected_element = element in connected_elements
verts_pos = []
port_data = SystemDecorationData.get_element_ports_data(element)
+2 -1
View File
@@ -62,7 +62,7 @@ class TestRemoveSystem:
class TestEnableEditingSystem:
def test_run(self, system):
system.import_system_attributes("system").should_be_called()
system.set_active_system("system").should_be_called()
system.set_active_edited_system("system").should_be_called()
subject.enable_editing_system(system, system="system")
@@ -87,6 +87,7 @@ class TestUnassignSystem:
class TestSelectSystemProducts:
def test_run(self, system):
system.select_system_products("system").should_be_called()
system.set_active_system("system").should_be_called()
subject.select_system_products(system, system="system")
+4 -4
View File
@@ -53,9 +53,9 @@ class TestDeleteElementObjects(NewFile):
class TestDisableEditingSystem(NewFile):
def test_run(self):
bpy.context.scene.BIMSystemProperties.active_system_id = 10
bpy.context.scene.BIMSystemProperties.edited_system_id = 10
subject.disable_editing_system()
assert bpy.context.scene.BIMSystemProperties.active_system_id == 0
assert bpy.context.scene.BIMSystemProperties.edited_system_id == 0
class TestDisableSystemEditingUI(NewFile):
@@ -219,5 +219,5 @@ class TestSetActiveSystem(NewFile):
ifc = ifcopenshell.file()
tool.Ifc().set(ifc)
system = ifcopenshell.api.run("system.add_system", ifc, ifc_class="IfcSystem")
subject.set_active_system(system)
assert bpy.context.scene.BIMSystemProperties.active_system_id == system.id()
subject.set_active_edited_system(system)
assert bpy.context.scene.BIMSystemProperties.edited_system_id == system.id()