Merge pull request #4440 from brunoperdigao/fix-normal-duplication-of-linked-aggregate

Fix normal duplication of linked aggregate
This commit is contained in:
Bruno Perdigão
2024-04-30 17:01:44 -03:00
committed by GitHub
2 changed files with 84 additions and 54 deletions
@@ -96,12 +96,13 @@ class BIM_OT_aggregate_unassign_object(bpy.types.Operator, Operator):
) )
# Removes Pset related to Linked Aggregates # Removes Pset related to Linked Aggregates
pset = ifcopenshell.util.element.get_pset(element, "BBIM_Linked_Aggregate") if not element.is_a('IfcElementAssembly'):
if pset: pset = ifcopenshell.util.element.get_pset(element, 'BBIM_Linked_Aggregate')
pset = tool.Ifc.get().by_id(pset["id"]) if pset:
ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), pset=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): class BIM_OT_enable_editing_aggregate(bpy.types.Operator, Operator):
"""Enable editing aggregation relationship""" """Enable editing aggregation relationship"""
@@ -843,7 +843,7 @@ class OverrideDuplicateMove(bpy.types.Operator):
# Recreate decompositions # Recreate decompositions
tool.Root.recreate_decompositions(decomposition_relationships, old_to_new) tool.Root.recreate_decompositions(decomposition_relationships, old_to_new)
OverrideDuplicateMove.handle_linked_aggregates(old_to_new) OverrideDuplicateMove.remove_linked_aggregate_data(old_to_new)
blenderbim.bim.handler.refresh_ui_data() blenderbim.bim.handler.refresh_ui_data()
return old_to_new return old_to_new
@@ -896,25 +896,21 @@ class OverrideDuplicateMove(bpy.types.Operator):
if entity in old_to_new.keys(): if entity in old_to_new.keys():
core.remove_connection(tool.Geometry, connection=connection) core.remove_connection(tool.Geometry, connection=connection)
@staticmethod def remove_linked_aggregate_data(old_to_new):
def handle_linked_aggregates(old_to_new):
for old, new in old_to_new.items(): for old, new in old_to_new.items():
pset = ifcopenshell.util.element.get_pset(new[0], "BBIM_Linked_Aggregate") pset = ifcopenshell.util.element.get_pset(new[0], "BBIM_Linked_Aggregate")
if pset: if pset:
old_aggregate = ifcopenshell.util.element.get_aggregate(old) pset = tool.Ifc.get().by_id(pset["id"])
new_aggregate = ifcopenshell.util.element.get_aggregate(new[0]) ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), pset=pset)
if old_aggregate == new_aggregate:
parts = ifcopenshell.util.element.get_parts(new_aggregate) if new[0].is_a("IfcElementAssembly"):
if parts: linked_aggregate_group = [
index = DuplicateMoveLinkedAggregate.get_max_index(parts) r.RelatingGroup
index += 1 for r in getattr(new[0], "HasAssignments", []) or []
pset = tool.Ifc.get().by_id(pset["id"]) if r.is_a("IfcRelAssignsToGroup")
ifcopenshell.api.run( if "BBIM_Linked_Aggregate" in r.RelatingGroup.Name
"pset.edit_pset", ]
tool.Ifc.get(), tool.Ifc.run("group.unassign_group", group=linked_aggregate_group[0], product=new[0])
pset=pset,
properties={"Index": index},
)
class OverrideDuplicateMoveLinkedMacro(bpy.types.Macro): class OverrideDuplicateMoveLinkedMacro(bpy.types.Macro):
@@ -975,16 +971,16 @@ class DuplicateMoveLinkedAggregate(bpy.types.Operator):
obj.select_set(True) obj.select_set(True)
parts = ifcopenshell.util.element.get_parts(element) parts = ifcopenshell.util.element.get_parts(element)
if parts: if parts:
index = DuplicateMoveLinkedAggregate.get_max_index(parts) index = get_max_index(parts)
add_linked_aggregate_pset(element, index) add_linked_aggregate_pset(element, index)
index += 1 index += 1
for part in parts: for part in parts:
if part.is_a("IfcElementAssembly"): if part.is_a("IfcElementAssembly"):
select_objects_and_add_data(part) select_objects_and_add_data(part)
else: else:
add_linked_aggregate_pset(part, index) index = add_linked_aggregate_pset(part, index)
index += 1 # index += 1
obj = tool.Ifc.get_object(part) obj = tool.Ifc.get_object(part)
obj.select_set(True) obj.select_set(True)
@@ -1000,6 +996,8 @@ class DuplicateMoveLinkedAggregate(bpy.types.Operator):
pset=pset, pset=pset,
properties={"Index": index}, properties={"Index": index},
) )
index += 1
else: else:
pass pass
@@ -1042,6 +1040,40 @@ class DuplicateMoveLinkedAggregate(bpy.types.Operator):
if re.findall(pattern2, new_obj.name): if re.findall(pattern2, new_obj.name):
split_name = new_obj.name.split(".") split_name = new_obj.name.split(".")
new_obj.name = split_name[0] + "_" + number new_obj.name = split_name[0] + "_" + number
def get_max_index(parts):
psets = [ifcopenshell.util.element.get_pset(p, "BBIM_Linked_Aggregate") for p in parts]
index = [i['Index'] for i in psets if i]
if len(index) > 0:
index = max(index)
return index
else:
return 0
def copy_linked_aggregate_data(old_to_new):
for old, new in old_to_new.items():
pset = ifcopenshell.util.element.get_pset(old, "BBIM_Linked_Aggregate")
if pset:
new_pset = ifcopenshell.api.run(
"pset.add_pset", tool.Ifc.get(), product=new[0], name=self.pset_name
)
ifcopenshell.api.run(
"pset.edit_pset",
tool.Ifc.get(),
pset=new_pset,
properties={"Index": pset["Index"]},
)
if new[0].is_a("IfcElementAssembly"):
linked_aggregate_group = [
r.RelatingGroup
for r in getattr(old, "HasAssignments", []) or []
if r.is_a("IfcRelAssignsToGroup")
if "BBIM_Linked_Aggregate" in r.RelatingGroup.Name
]
tool.Ifc.run("group.assign_group", group=linked_aggregate_group[0], products=new)
if len(context.selected_objects) != 1: if len(context.selected_objects) != 1:
return {"FINISHED"} return {"FINISHED"}
@@ -1062,28 +1094,17 @@ class DuplicateMoveLinkedAggregate(bpy.types.Operator):
select_objects_and_add_data(selected_element) select_objects_and_add_data(selected_element)
old_to_new = OverrideDuplicateMove.execute_ifc_duplicate_operator(self, context, linked=True) old_to_new = OverrideDuplicateMove.execute_ifc_duplicate_operator(self, context, linked=True)
tool.Root.recreate_aggregate(old_to_new)
copy_linked_aggregate_data(old_to_new)
custom_incremental_naming_for_element_assembly(old_to_new) custom_incremental_naming_for_element_assembly(old_to_new)
# Recreate aggregate relationship
for old in old_to_new.keys():
if old.is_a("IfcElementAssembly"):
tool.Root.recreate_aggregate(old_to_new)
blenderbim.bim.handler.refresh_ui_data() blenderbim.bim.handler.refresh_ui_data()
return old_to_new return old_to_new
@staticmethod
def get_max_index(parts):
psets = [ifcopenshell.util.element.get_pset(p, "BBIM_Linked_Aggregate") for p in parts]
index = [i["Index"] for i in psets if i]
if len(index) > 0:
index = max(index)
return index
else:
return 0
class RefreshLinkedAggregate(bpy.types.Operator): class RefreshLinkedAggregate(bpy.types.Operator):
bl_idname = "bim.refresh_linked_aggregate" bl_idname = "bim.refresh_linked_aggregate"
@@ -1217,6 +1238,23 @@ class RefreshLinkedAggregate(bpy.types.Operator):
return list(set(linked_aggregate_groups)), selected_parents return list(set(linked_aggregate_groups)), selected_parents
def get_original_matrix(element, base_instance):
selected_obj = tool.Ifc.get_object(base_instance)
selected_matrix = selected_obj.matrix_world
object_duplicate = tool.Ifc.get_object(element)
duplicate_matrix = object_duplicate.matrix_world.decompose()
return selected_matrix, duplicate_matrix
def set_new_matrix(selected_matrix, duplicate_matrix, old_to_new):
for old, new in old_to_new.items():
new_obj = tool.Ifc.get_object(new[0])
new_base_matrix = Matrix.LocRotScale(*duplicate_matrix)
matrix_diff = Matrix.inverted(selected_matrix) @ new_obj.matrix_world
new_obj_matrix = new_base_matrix @ matrix_diff
new_obj.matrix_world = new_obj_matrix
active_element = tool.Ifc.get_entity(context.active_object) active_element = tool.Ifc.get_entity(context.active_object)
if not active_element: if not active_element:
self.report({"INFO"}, "Object has no Ifc metadata.") self.report({"INFO"}, "Object has no Ifc metadata.")
@@ -1256,10 +1294,7 @@ class RefreshLinkedAggregate(bpy.types.Operator):
element_aggregate = ifcopenshell.util.element.get_aggregate(element) element_aggregate = ifcopenshell.util.element.get_aggregate(element)
selected_obj = tool.Ifc.get_object(base_instance) selected_matrix, duplicate_matrix = get_original_matrix(element, base_instance)
selected_matrix = selected_obj.matrix_world
object_duplicate = tool.Ifc.get_object(element)
duplicate_matrix = object_duplicate.matrix_world.decompose()
original_names = get_original_names(element) original_names = get_original_names(element)
@@ -1270,15 +1305,9 @@ class RefreshLinkedAggregate(bpy.types.Operator):
tool.Ifc.get_object(base_instance).select_set(True) tool.Ifc.get_object(base_instance).select_set(True)
old_to_new = DuplicateMoveLinkedAggregate.execute_ifc_duplicate_linked_aggregate_operator( old_to_new = DuplicateMoveLinkedAggregate.execute_ifc_duplicate_linked_aggregate_operator(self, context)
self, context
) set_new_matrix(selected_matrix, duplicate_matrix, old_to_new)
for old, new in old_to_new.items():
new_obj = tool.Ifc.get_object(new[0])
new_base_matrix = Matrix.LocRotScale(*duplicate_matrix)
matrix_diff = Matrix.inverted(selected_matrix) @ new_obj.matrix_world
new_obj_matrix = new_base_matrix @ matrix_diff
new_obj.matrix_world = new_obj_matrix
for old, new in old_to_new.items(): for old, new in old_to_new.items():
if element_aggregate and new[0].is_a("IfcElementAssembly"): if element_aggregate and new[0].is_a("IfcElementAssembly"):