mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 22:50:21 +00:00
Merge pull request #4440 from brunoperdigao/fix-normal-duplication-of-linked-aggregate
Fix normal duplication of linked aggregate
This commit is contained in:
@@ -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"):
|
||||||
|
|||||||
Reference in New Issue
Block a user