mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-16 13:46:54 +00:00
Purge/merge IfcPersonAndOrganizations
This commit is contained in:
@@ -766,10 +766,12 @@ class PurgeUnusedObjects(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
purged = core.purge_unused_elements(tool.Ifc, tool.Debug, "IfcApplication")
|
purged = core.purge_unused_elements(tool.Ifc, tool.Debug, "IfcApplication")
|
||||||
elif object_type == "PERSON":
|
elif object_type == "PERSON":
|
||||||
purged = core.purge_unused_elements(tool.Ifc, tool.Debug, "IfcPerson")
|
purged = core.purge_unused_elements(tool.Ifc, tool.Debug, "IfcPerson")
|
||||||
|
elif object_type == "PERSON_AND_ORGANIZATION":
|
||||||
|
purged = core.purge_unused_elements(tool.Ifc, tool.Debug, "IfcPersonAndOrganization")
|
||||||
else:
|
else:
|
||||||
assert_never(object_type)
|
assert_never(object_type)
|
||||||
|
|
||||||
self.report({"INFO"}, f"{purged} unused {object_type.lower()}s were purged.")
|
self.report({"INFO"}, f"{purged} unused {object_type.replace('_', ' ').lower()}s were purged.")
|
||||||
|
|
||||||
if purged == 0:
|
if purged == 0:
|
||||||
return
|
return
|
||||||
@@ -798,7 +800,7 @@ class MergeIdenticalObjects(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
return {"CANCELLED"}
|
return {"CANCELLED"}
|
||||||
|
|
||||||
merged_data = tool.Debug.merge_identical_objects(object_type)
|
merged_data = tool.Debug.merge_identical_objects(object_type)
|
||||||
plural_object_type = f"{object_type.lower()}s"
|
plural_object_type = f"{object_type.lower().replace('_', ' ')}s"
|
||||||
if merged_data:
|
if merged_data:
|
||||||
for element_type, element_names in merged_data.items():
|
for element_type, element_names in merged_data.items():
|
||||||
print(f"- {element_type}:")
|
print(f"- {element_type}:")
|
||||||
|
|||||||
@@ -635,10 +635,17 @@ class BIM_PT_purge(Panel):
|
|||||||
layout.operator("bim.purge_unused_objects", text="Purge Unused Types").object_type = "TYPE"
|
layout.operator("bim.purge_unused_objects", text="Purge Unused Types").object_type = "TYPE"
|
||||||
layout.operator("bim.purge_unused_openings", text="Purge Unused Openings in Selected Objects")
|
layout.operator("bim.purge_unused_openings", text="Purge Unused Openings in Selected Objects")
|
||||||
|
|
||||||
MERGEABLE_OBJECT_TYPES = ("MATERIAL", "STYLE", "ORGANIZATION", "APPLICATION", "PERSON")
|
MERGEABLE_OBJECT_TYPES = (
|
||||||
|
"MATERIAL",
|
||||||
|
"STYLE",
|
||||||
|
"ORGANIZATION",
|
||||||
|
"APPLICATION",
|
||||||
|
"PERSON",
|
||||||
|
"PERSON_AND_ORGANIZATION",
|
||||||
|
)
|
||||||
|
|
||||||
for object_type in MERGEABLE_OBJECT_TYPES:
|
for object_type in MERGEABLE_OBJECT_TYPES:
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.label(text=f"{object_type.capitalize()}:")
|
row.label(text=f"{object_type.replace('_', ' ').capitalize()}:")
|
||||||
row.operator("bim.purge_unused_objects", text="Purge Unused").object_type = object_type
|
row.operator("bim.purge_unused_objects", text="Purge Unused").object_type = object_type
|
||||||
row.operator("bim.merge_identical_objects", text="Merge Identical").object_type = object_type
|
row.operator("bim.merge_identical_objects", text="Merge Identical").object_type = object_type
|
||||||
|
|||||||
@@ -44,6 +44,9 @@ def purge_unused_elements(ifc: type[tool.Ifc], debug: type[tool.Debug], ifc_clas
|
|||||||
elif ifc_class == "IfcPerson":
|
elif ifc_class == "IfcPerson":
|
||||||
for element in unused_elements:
|
for element in unused_elements:
|
||||||
ifc.run("owner.remove_person", person=element)
|
ifc.run("owner.remove_person", person=element)
|
||||||
|
elif ifc_class == "IfcPersonAndOrganization":
|
||||||
|
for element in unused_elements:
|
||||||
|
ifc.run("owner.remove_person_and_organisation", person_and_organisation=element)
|
||||||
else:
|
else:
|
||||||
debug.remove_unused_elements(unused_elements)
|
debug.remove_unused_elements(unused_elements)
|
||||||
return unused_elements_amount
|
return unused_elements_amount
|
||||||
|
|||||||
@@ -125,7 +125,14 @@ class Debug(bonsai.core.tool.Debug):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def merge_identical_objects(
|
def merge_identical_objects(
|
||||||
cls,
|
cls,
|
||||||
object_type: Literal["STYLE", "MATERIAL", "ORGANIZATION", "APPLICATION", "PERSON"],
|
object_type: Literal[
|
||||||
|
"STYLE",
|
||||||
|
"MATERIAL",
|
||||||
|
"ORGANIZATION",
|
||||||
|
"APPLICATION",
|
||||||
|
"PERSON",
|
||||||
|
"PERSON_AND_ORGANIZATION",
|
||||||
|
],
|
||||||
) -> dict[str, list[str]]:
|
) -> dict[str, list[str]]:
|
||||||
"""Merge identical objects.
|
"""Merge identical objects.
|
||||||
|
|
||||||
@@ -137,6 +144,9 @@ class Debug(bonsai.core.tool.Debug):
|
|||||||
if object_type == "APPLICATION":
|
if object_type == "APPLICATION":
|
||||||
# To avoid disruption let user merge organizations separately.
|
# To avoid disruption let user merge organizations separately.
|
||||||
data["ApplicationDeveloper"] = element.ApplicationDeveloper.id()
|
data["ApplicationDeveloper"] = element.ApplicationDeveloper.id()
|
||||||
|
elif object_type == "PERSON_AND_ORGANIZATION":
|
||||||
|
data["ThePerson"] = element.ThePerson.id()
|
||||||
|
data["TheOrganization"] = element.TheOrganization.id()
|
||||||
return hash(json.dumps(data, sort_keys=True))
|
return hash(json.dumps(data, sort_keys=True))
|
||||||
|
|
||||||
ifc_file = tool.Ifc.get()
|
ifc_file = tool.Ifc.get()
|
||||||
@@ -155,9 +165,14 @@ class Debug(bonsai.core.tool.Debug):
|
|||||||
element_types = ["IfcApplication"]
|
element_types = ["IfcApplication"]
|
||||||
elif object_type == "PERSON":
|
elif object_type == "PERSON":
|
||||||
element_types = ["IfcPerson"]
|
element_types = ["IfcPerson"]
|
||||||
|
elif object_type == "PERSON_AND_ORGANIZATION":
|
||||||
|
element_types = ["IfcPersonAndOrganization"]
|
||||||
else:
|
else:
|
||||||
assert_never(object_type)
|
assert_never(object_type)
|
||||||
|
|
||||||
|
def get_person_name(person: ifcopenshell.entity_instance) -> str:
|
||||||
|
return f"{person.Identification} / {person.FamilyName} / {person.GivenName}"
|
||||||
|
|
||||||
for element_type in element_types:
|
for element_type in element_types:
|
||||||
elements = ifc_file.by_type(element_type, include_subtypes=False)
|
elements = ifc_file.by_type(element_type, include_subtypes=False)
|
||||||
|
|
||||||
@@ -167,9 +182,11 @@ class Debug(bonsai.core.tool.Debug):
|
|||||||
# Except for styles, ignore unnamed elements as they may be not safe to merge
|
# Except for styles, ignore unnamed elements as they may be not safe to merge
|
||||||
merge_optional_names = ("STYLE", "PERSON")
|
merge_optional_names = ("STYLE", "PERSON")
|
||||||
not_optional_name = ("APPLICATION", "ORGANIZATION")
|
not_optional_name = ("APPLICATION", "ORGANIZATION")
|
||||||
|
has_no_name = ("PERSON_AND_ORGANIZATION",)
|
||||||
if (
|
if (
|
||||||
object_type not in merge_optional_names
|
object_type not in merge_optional_names
|
||||||
and object_type not in not_optional_name
|
and object_type not in not_optional_name
|
||||||
|
and object_type not in has_no_name
|
||||||
and not element.Name
|
and not element.Name
|
||||||
):
|
):
|
||||||
continue
|
continue
|
||||||
@@ -216,11 +233,15 @@ class Debug(bonsai.core.tool.Debug):
|
|||||||
elif object_type == "PERSON":
|
elif object_type == "PERSON":
|
||||||
for person in elements[1:]:
|
for person in elements[1:]:
|
||||||
ifcopenshell.util.element.replace_element(person, main_element)
|
ifcopenshell.util.element.replace_element(person, main_element)
|
||||||
merged_elements_names.append(
|
merged_elements_names.append(get_person_name(person))
|
||||||
f"{person.Identification} / {person.FamilyName} / {person.GivenName}"
|
|
||||||
)
|
|
||||||
ifcopenshell.api.owner.remove_person(ifc_file, person)
|
ifcopenshell.api.owner.remove_person(ifc_file, person)
|
||||||
|
|
||||||
|
elif object_type == "PERSON_AND_ORGANIZATION":
|
||||||
|
for pao in elements[1:]:
|
||||||
|
ifcopenshell.util.element.replace_element(pao, main_element)
|
||||||
|
merged_elements_names.append(f"{get_person_name(pao.ThePerson)} / {pao.TheOrganization.Name}")
|
||||||
|
ifcopenshell.api.owner.remove_person_and_organisation(ifc_file, pao)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
assert_never(object_type)
|
assert_never(object_type)
|
||||||
|
|
||||||
@@ -228,7 +249,16 @@ class Debug(bonsai.core.tool.Debug):
|
|||||||
merged_element_types[element_type] = merged_elements_names
|
merged_element_types[element_type] = merged_elements_names
|
||||||
return merged_element_types
|
return merged_element_types
|
||||||
|
|
||||||
PurgeMergeObjectType = Literal["TYPE", "PROFILE", "STYLE", "MATERIAL", "ORGANIZATION", "APPLICATION", "PERSON"]
|
PurgeMergeObjectType = Literal[
|
||||||
|
"TYPE",
|
||||||
|
"PROFILE",
|
||||||
|
"STYLE",
|
||||||
|
"MATERIAL",
|
||||||
|
"ORGANIZATION",
|
||||||
|
"APPLICATION",
|
||||||
|
"PERSON",
|
||||||
|
"PERSON_AND_ORGANIZATION",
|
||||||
|
]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def refresh_ui_after_purge_merge(cls, object_type: PurgeMergeObjectType) -> None:
|
def refresh_ui_after_purge_merge(cls, object_type: PurgeMergeObjectType) -> None:
|
||||||
@@ -258,5 +288,9 @@ class Debug(bonsai.core.tool.Debug):
|
|||||||
props = tool.Owner.get_owner_props()
|
props = tool.Owner.get_owner_props()
|
||||||
if tool.Ifc.get_entity_by_id(props.active_person_id) is None:
|
if tool.Ifc.get_entity_by_id(props.active_person_id) is None:
|
||||||
tool.Owner.clear_person()
|
tool.Owner.clear_person()
|
||||||
|
elif object_type == "PERSON_AND_ORGANIZATION":
|
||||||
|
props = tool.Owner.get_owner_props()
|
||||||
|
if tool.Ifc.get_entity_by_id(props.active_person_id) is None:
|
||||||
|
tool.Owner.clear_user()
|
||||||
else:
|
else:
|
||||||
assert_never(object_type)
|
assert_never(object_type)
|
||||||
|
|||||||
Reference in New Issue
Block a user