added the option to refresh different groups of linked aggregate

This commit is contained in:
Bruno Perdigão
2023-11-23 10:27:54 -03:00
parent f859c06858
commit 2fb8fafbb4
2 changed files with 77 additions and 62 deletions
@@ -927,6 +927,7 @@ class DuplicateMoveLinkedAggregate(bpy.types.Operator):
def _execute(self, context): def _execute(self, context):
return DuplicateMoveLinkedAggregate.execute_ifc_duplicate_linked_aggregate_operator(self, context) return DuplicateMoveLinkedAggregate.execute_ifc_duplicate_linked_aggregate_operator(self, context)
@staticmethod
def execute_ifc_duplicate_linked_aggregate_operator(self, context): def execute_ifc_duplicate_linked_aggregate_operator(self, context):
self.new_active_obj = None self.new_active_obj = None
self.group_name = "BBIM_Linked_Aggregate" self.group_name = "BBIM_Linked_Aggregate"
@@ -1064,48 +1065,65 @@ class RefreshLinkedAggregate(bpy.types.Operator):
else: else:
return None return None
def handle_selection(selected_objs):
selected_objs = context.selected_objects
selected_elements = [tool.Ifc.get_entity(selected_obj) for selected_obj in selected_objs] selected_elements = [tool.Ifc.get_entity(selected_obj) for selected_obj in selected_objs]
active_element = tool.Ifc.get_entity(context.active_object)
active_element = get_element_assembly(active_element)
working_selection = [] selected_parents = []
for selected_element in selected_elements: for selected_element in selected_elements:
selected_element = get_element_assembly(selected_element) selected_element = get_element_assembly(selected_element)
if not selected_element: if not selected_element:
self.report({"INFO"}, "Object is not part of a IfcElementAssembly.") self.report({"INFO"}, "Object is not part of a IfcElementAssembly.")
return {'FINISHED'} return {'FINISHED'}
working_selection.append(selected_element) selected_parents.append(selected_element)
working_selection = list(set(working_selection)) selected_parents = list(set(selected_parents))
working_ids = [e.id() for e in working_selection] linked_aggregate_groups = []
selection_group = [] for selected_element in selected_parents:
for selected_element in working_selection:
product_linked_agg_group = [ product_linked_agg_group = [
r.RelatingGroup r.RelatingGroup
for r in getattr(selected_element, "HasAssignments", []) or [] for r in getattr(selected_element, "HasAssignments", []) or []
if r.is_a("IfcRelAssignsToGroup") if r.is_a("IfcRelAssignsToGroup")
if self.group_name in r.RelatingGroup.Name if self.group_name in r.RelatingGroup.Name
] ]
selection_group.append(product_linked_agg_group[0].id()) linked_aggregate_groups.append(product_linked_agg_group[0].id())
if len(set(selection_group))> 1: return list(set(linked_aggregate_groups)), selected_parents
self.report({"INFO"}, "Objects are not part of the same Linked Aggregate")
selected_objs = context.selected_objects
selected_elements = [tool.Ifc.get_entity(selected_obj) for selected_obj in selected_objs]
active_element = tool.Ifc.get_entity(context.active_object)
active_element = get_element_assembly(active_element)
selected_objs = context.selected_objects
linked_aggregate_groups, selected_parents = handle_selection(selected_objs)
if len(linked_aggregate_groups) > 1:
if len(selected_parents) != len(linked_aggregate_groups):
self.report({"INFO"}, "Select only one object from each Linked Aggregate or multiple objects from the same Linked Aggregate.")
return {"FINISHED"} return {"FINISHED"}
elements = tool.Drawing.get_group_elements(tool.Ifc.get().by_id(selection_group[0])) for group in linked_aggregate_groups:
elements = tool.Drawing.get_group_elements(tool.Ifc.get().by_id(group))
if len(linked_aggregate_groups) > 1:
base_instance = [e for e in elements if e in selected_parents][0]
instances_to_refresh = elements
for element in elements: elif (len(linked_aggregate_groups) == 1) and (len(selected_parents) > 1):
if element.GlobalId == active_element.GlobalId: base_instance = active_element
continue instances_to_refresh = [element for element in elements if element in selected_parents]
if (len(working_selection) > 1) and not (element.id() in working_ids): else:
base_instance = active_element
instances_to_refresh = elements
for element in instances_to_refresh:
if element.GlobalId == base_instance.GlobalId:
continue continue
element_aggregate = ifcopenshell.util.element.get_aggregate(element) element_aggregate = ifcopenshell.util.element.get_aggregate(element)
selected_obj = tool.Ifc.get_object(active_element) selected_obj = tool.Ifc.get_object(base_instance)
selected_matrix = selected_obj.matrix_world selected_matrix = selected_obj.matrix_world
object_duplicate = tool.Ifc.get_object(element) object_duplicate = tool.Ifc.get_object(element)
duplicate_matrix = object_duplicate.matrix_world.decompose() duplicate_matrix = object_duplicate.matrix_world.decompose()
@@ -1115,20 +1133,19 @@ class RefreshLinkedAggregate(bpy.types.Operator):
for obj in context.selected_objects: for obj in context.selected_objects:
obj.select_set(False) obj.select_set(False)
tool.Ifc.get_object(active_element).select_set(True) tool.Ifc.get_object(base_instance).select_set(True)
old_to_new = DuplicateMoveLinkedAggregate.execute_ifc_duplicate_linked_aggregate_operator(self, context) old_to_new = DuplicateMoveLinkedAggregate.execute_ifc_duplicate_linked_aggregate_operator(self, context)
for old, new in old_to_new.items(): for old, new in old_to_new.items():
new_obj = tool.Ifc.get_object(new[0]) new_obj = tool.Ifc.get_object(new[0])
new_base_matrix = Matrix.LocRotScale(*duplicate_matrix) new_base_matrix = Matrix.LocRotScale(*duplicate_matrix)
matrix_diff = Matrix.inverted(selected_matrix) @ new_obj.matrix_world matrix_diff = Matrix.inverted(selected_matrix) @ new_obj.matrix_world
new_obj_matrix = new_base_matrix @ matrix_diff new_obj_matrix = new_base_matrix @ matrix_diff
new_obj.matrix_world = new_obj_matrix new_obj.matrix_world = new_obj_matrix
if element_aggregate and new[0].is_a("IfcElementAssembly"): if element_aggregate and new[0].is_a("IfcElementAssembly"):
new_aggregate = ifcopenshell.util.element.get_aggregate(new[0]) new_aggregate = ifcopenshell.util.element.get_aggregate(new[0])
if not new_aggregate: if not new_aggregate:
blenderbim.core.aggregate.assign_object( blenderbim.core.aggregate.assign_object(
tool.Ifc, tool.Ifc,
-2
View File
@@ -234,10 +234,8 @@ class Root(blenderbim.core.tool.Root):
@classmethod @classmethod
def recreate_aggregate(cls, old_to_new): def recreate_aggregate(cls, old_to_new):
print("O_T_N", old_to_new)
for old, new in old_to_new.items(): for old, new in old_to_new.items():
old_aggregate = ifcopenshell.util.element.get_aggregate(old) old_aggregate = ifcopenshell.util.element.get_aggregate(old)
print("Old", old_aggregate)
if old_aggregate: if old_aggregate:
try: try:
new_aggregate = old_to_new[old_aggregate] new_aggregate = old_to_new[old_aggregate]