UI for linked aggregate (#4271)

* initial ui

* changed the group name

* groups counter in ui

* added operators for selection and breaking link in the ui

* small removal

* changed IFC operators to _execute
This commit is contained in:
Bruno Perdigão
2024-02-23 17:56:28 -03:00
parent ed7b337a40
commit a4eeae2872
4 changed files with 140 additions and 0 deletions
@@ -28,8 +28,11 @@ classes = (
operator.BIM_OT_select_aggregate,
operator.BIM_OT_select_parts,
operator.BIM_OT_aggregate_unassign_object,
operator.BIM_OT_break_link_to_other_aggregates,
operator.BIM_OT_select_linked_aggregates,
prop.BIMObjectAggregateProperties,
ui.BIM_PT_aggregate,
ui.BIM_PT_linked_aggregate,
)
@@ -37,6 +37,7 @@ class AggregateData:
"has_related_objects": cls.has_related_objects(),
"total_parts": cls.total_parts(),
"ifc_class": cls.ifc_class(),
"total_linked_aggregate": cls.total_linked_aggregate(),
}
cls.is_loaded = True
@@ -72,3 +73,26 @@ class AggregateData:
element = tool.Ifc.get_entity(bpy.context.active_object)
if element:
return element.is_a()
@classmethod
def total_linked_aggregate(cls):
element = tool.Ifc.get_entity(bpy.context.active_object)
aggregate = ifcopenshell.util.element.get_aggregate(element)
if not aggregate:
return []
if not element:
return []
product_linked_agg_group = [
r
for r in getattr(aggregate, "HasAssignments", []) or []
if r.is_a("IfcRelAssignsToGroup")
if "BBIM_Linked_Aggregate" in r.RelatingGroup.Name
]
if not product_linked_agg_group:
return []
total = len(product_linked_agg_group[0].RelatedObjects)
return total
@@ -89,6 +89,12 @@ class BIM_OT_aggregate_unassign_object(bpy.types.Operator, Operator):
relating_obj=tool.Ifc.get_object(aggregate),
related_obj=tool.Ifc.get_object(element),
)
# Removes Pset related to Linked Aggregates
pset = ifcopenshell.util.element.get_pset(element, 'BBIM_Linked_Aggregate')
if pset:
pset = tool.Ifc.get().by_id(pset["id"])
ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), pset=pset)
class BIM_OT_enable_editing_aggregate(bpy.types.Operator, Operator):
@@ -230,3 +236,63 @@ class BIM_OT_add_part_to_object(bpy.types.Operator, Operator):
part_class=self.part_class,
part_name=self.part_name,
)
class BIM_OT_break_link_to_other_aggregates(bpy.types.Operator, Operator):
bl_idname = "bim.break_link_to_other_aggregates"
bl_label = "Break link to other aggregates"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
element = tool.Ifc.get_entity(bpy.context.active_object)
aggregate = ifcopenshell.util.element.get_aggregate(element)
if not aggregate:
return []
if not element:
return []
parts = ifcopenshell.util.element.get_parts(aggregate)
for part in parts:
pset = ifcopenshell.util.element.get_pset(part, 'BBIM_Linked_Aggregate')
pset = tool.Ifc.get().by_id(pset["id"])
ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), pset=pset)
linked_aggregate_group = [
r.RelatingGroup
for r in getattr(aggregate, "HasAssignments", []) or []
if r.is_a("IfcRelAssignsToGroup")
if "BBIM_Linked_Aggregate" in r.RelatingGroup.Name
]
tool.Ifc.run("group.unassign_group", group=linked_aggregate_group[0], product=aggregate)
return {"FINISHED"}
class BIM_OT_select_linked_aggregates(bpy.types.Operator, Operator):
bl_idname = "bim.select_linked_aggregates"
bl_label = "Select linked aggregates"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
element = tool.Ifc.get_entity(bpy.context.active_object)
aggregate = ifcopenshell.util.element.get_aggregate(element)
if not aggregate:
return []
if not element:
return []
linked_aggregate_group = [
r.RelatingGroup
for r in getattr(aggregate, "HasAssignments", []) or []
if r.is_a("IfcRelAssignsToGroup")
if "BBIM_Linked_Aggregate" in r.RelatingGroup.Name
]
for obj in context.selected_objects:
obj.select_set(False)
for rel in linked_aggregate_group[0].IsGroupedBy or []:
for element in rel.RelatedObjects:
obj = tool.Ifc.get_object(element)
obj.select_set(True)
return {"FINISHED"}
@@ -18,6 +18,7 @@
from bpy.types import Panel
from blenderbim.bim.module.aggregate.data import AggregateData
from blenderbim.bim.module.group.data import GroupsData, ObjectGroupsData
from blenderbim.bim.ifc import IfcStore
@@ -96,3 +97,49 @@ class BIM_PT_aggregate(Panel):
op = layout.operator("bim.add_part_to_object", text="Add " + part_class.lstrip("Ifc"))
op.part_class = part_class
op.obj = context.active_object.name
class BIM_PT_linked_aggregate(Panel):
bl_label = "Linked Aggregates"
bl_idname = "BIM_PT_linked_aggregate"
bl_options = {"DEFAULT_CLOSED"}
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "object"
bl_order = 2
bl_parent_id = "BIM_PT_aggregate"
@classmethod
def poll(cls, context):
if not context.active_object:
return False
props = context.active_object.BIMObjectProperties
if not props.ifc_definition_id:
return False
if not IfcStore.get_element(props.ifc_definition_id):
return False
if not IfcStore.get_file().by_id(props.ifc_definition_id).is_a("IfcObjectDefinition"):
return False
return True
def draw(self, context):
layout = self.layout
if not AggregateData.is_loaded:
AggregateData.load()
props = context.active_object.BIMObjectAggregateProperties
row = layout.row(align=True)
row.label(text="Advanced Users Only", icon="ERROR")
row = layout.row(align=True)
if type(AggregateData.data['total_linked_aggregate']) is int:
if AggregateData.data['total_linked_aggregate'] > 0:
row.label(text=f"{AggregateData.data['total_linked_aggregate']} Linked Aggregates")
row.operator("bim.select_linked_aggregates", text="", icon="RESTRICT_SELECT_OFF")
row.operator("bim.refresh_linked_aggregate", text="", icon="FILE_REFRESH")
op = row.operator("bim.break_link_to_other_aggregates", text="", icon="X")
else:
row.label(text="No Linked Aggregates")