From 489a248e9a208fbc92f7647da430752db0a3e34f Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Thu, 25 Mar 2021 11:42:12 +1100 Subject: [PATCH] Refactor ownership history system to be simpler and just a usecase. See #1399. --- .../api/aggregate/assign_object.py | 10 +-- .../api/attribute/edit_attributes.py | 4 +- .../ifcopenshell/api/group/add_group.py | 4 +- .../ifcopenshell/api/group/assign_group.py | 8 +-- .../ifcopenshell/api/group/unassign_group.py | 4 +- .../api/owner/add_organisation.py | 10 ++- .../ifcopenshell/api/owner/add_person.py | 11 +++- .../ifcopenshell/api/owner/api.py | 62 ------------------- .../api/owner/create_owner_history.py | 15 ++--- .../ifcopenshell/api/owner/settings.py | 33 ++++++++++ .../api/owner/update_owner_history.py | 14 ++--- .../ifcopenshell/api/root/create_product.py | 4 +- .../add_structural_analysis_model.py | 4 +- .../assign_structural_analysis_model.py | 8 +-- .../unassign_structural_analysis_model.py | 4 +- 15 files changed, 86 insertions(+), 109 deletions(-) delete mode 100644 src/ifcopenshell-python/ifcopenshell/api/owner/api.py create mode 100644 src/ifcopenshell-python/ifcopenshell/api/owner/settings.py diff --git a/src/ifcopenshell-python/ifcopenshell/api/aggregate/assign_object.py b/src/ifcopenshell-python/ifcopenshell/api/aggregate/assign_object.py index 5247eef42b..68c02513da 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/aggregate/assign_object.py +++ b/src/ifcopenshell-python/ifcopenshell/api/aggregate/assign_object.py @@ -1,6 +1,6 @@ import ifcopenshell -from ifcopenshell.api.owner.api import create_owner_history -from ifcopenshell.api.owner.api import update_owner_history +import ifcopenshell.api.owner.create_owner_history as create_owner_history +import ifcopenshell.api.owner.update_owner_history as update_owner_history class Usecase: @@ -32,7 +32,7 @@ class Usecase: related_objects.remove(self.settings["product"]) if related_objects: decomposes.RelatedObjects = related_objects - update_owner_history(decomposes) + update_owner_history.Usecase(self.file, {"element": decomposes}).execute() else: self.file.remove(decomposes) @@ -40,13 +40,13 @@ class Usecase: related_objects = list(is_decomposed_by.RelatedObjects) related_objects.append(self.settings["product"]) is_decomposed_by.RelatedObjects = related_objects - update_owner_history(is_decomposed_by) + update_owner_history.Usecase(self.file, {"element": is_decomposed_by}).execute() else: is_decomposed_by = self.file.create_entity( "IfcRelAggregates", **{ "GlobalId": ifcopenshell.guid.new(), - "OwnerHistory": create_owner_history(), + "OwnerHistory": create_owner_history.Usecase(self.file).execute(), "RelatedObjects": [self.settings["product"]], "RelatingObject": self.settings["relating_object"], } diff --git a/src/ifcopenshell-python/ifcopenshell/api/attribute/edit_attributes.py b/src/ifcopenshell-python/ifcopenshell/api/attribute/edit_attributes.py index 608474f37e..f16baf4323 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/attribute/edit_attributes.py +++ b/src/ifcopenshell-python/ifcopenshell/api/attribute/edit_attributes.py @@ -1,4 +1,4 @@ -from ifcopenshell.api.owner.api import update_owner_history +import ifcopenshell.api.owner.update_owner_history as update_owner_history class Usecase(): @@ -15,4 +15,4 @@ class Usecase(): for name, value in self.settings["attributes"].items(): setattr(self.settings["product"], name, value) if hasattr(self.settings["product"], "OwnerHistory"): - update_owner_history(self.settings["product"]) + update_owner_history.Usecase(self.file, {"element": self.settings["product"]}).execute() diff --git a/src/ifcopenshell-python/ifcopenshell/api/group/add_group.py b/src/ifcopenshell-python/ifcopenshell/api/group/add_group.py index ac24f9cdab..6195f74a26 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/group/add_group.py +++ b/src/ifcopenshell-python/ifcopenshell/api/group/add_group.py @@ -1,5 +1,5 @@ import ifcopenshell -from ifcopenshell.api.owner.api import create_owner_history +import ifcopenshell.api.owner.create_owner_history as create_owner_history class Usecase: @@ -12,6 +12,6 @@ class Usecase: def execute(self): return self.file.create_entity("IfcGroup", **{ "GlobalId": ifcopenshell.guid.new(), - "OwnerHistory": create_owner_history(), + "OwnerHistory": create_owner_history.Usecase(self.file).execute(), "Name": "Unnamed" }) diff --git a/src/ifcopenshell-python/ifcopenshell/api/group/assign_group.py b/src/ifcopenshell-python/ifcopenshell/api/group/assign_group.py index 109899c2cc..3a796ec5aa 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/group/assign_group.py +++ b/src/ifcopenshell-python/ifcopenshell/api/group/assign_group.py @@ -1,6 +1,6 @@ import ifcopenshell -from ifcopenshell.api.owner.api import create_owner_history -from ifcopenshell.api.owner.api import update_owner_history +import ifcopenshell.api.owner.create_owner_history as create_owner_history +import ifcopenshell.api.owner.update_owner_history as update_owner_history class Usecase: @@ -17,7 +17,7 @@ class Usecase: if not self.settings["group"].IsGroupedBy: return self.file.create_entity("IfcRelAssignsToGroup", **{ "GlobalId": ifcopenshell.guid.new(), - "OwnerHistory": create_owner_history(), + "OwnerHistory": create_owner_history.Usecase(self.file).execute(), "RelatedObjects": [self.settings["product"]], "RelatingGroup": self.settings["group"] }) @@ -25,4 +25,4 @@ class Usecase: related_objects = set(rel.RelatedObjects) or set() related_objects.add(self.settings["product"]) rel.RelatedObjects = list(related_objects) - update_owner_history(rel) + update_owner_history.Usecase(self.file, {"element": rel}).execute() diff --git a/src/ifcopenshell-python/ifcopenshell/api/group/unassign_group.py b/src/ifcopenshell-python/ifcopenshell/api/group/unassign_group.py index 7f66f4bd85..e6e7f4e633 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/group/unassign_group.py +++ b/src/ifcopenshell-python/ifcopenshell/api/group/unassign_group.py @@ -1,5 +1,5 @@ import ifcopenshell -from ifcopenshell.api.owner.api import update_owner_history +import ifcopenshell.api.owner.update_owner_history as update_owner_history class Usecase: @@ -20,6 +20,6 @@ class Usecase: related_objects.remove(self.settings["product"]) if len(related_objects): rel.RelatedObjects = list(related_objects) - update_owner_history(rel) + update_owner_history.Usecase(self.file, {"element": rel}).execute() else: self.file.remove(rel) diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/add_organisation.py b/src/ifcopenshell-python/ifcopenshell/api/owner/add_organisation.py index d9c8cd2a65..5b373d5043 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/owner/add_organisation.py +++ b/src/ifcopenshell-python/ifcopenshell/api/owner/add_organisation.py @@ -1,6 +1,12 @@ class Usecase: - def __init__(self, file): + def __init__(self, file, settings={}): self.file = file + self.settings = { + "Identification": "APTR", + "Name": "Aperture Science", + } + for key, value in settings.items(): + self.settings[key] = value def execute(self): - self.file.createIfcOrganization("APTR", "Aperture Science") + return self.file.create_entity("IfcOrganization", **self.settings) diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/add_person.py b/src/ifcopenshell-python/ifcopenshell/api/owner/add_person.py index 0772105757..9ab1712fb2 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/owner/add_person.py +++ b/src/ifcopenshell-python/ifcopenshell/api/owner/add_person.py @@ -1,6 +1,13 @@ class Usecase: - def __init__(self, file): + def __init__(self, file, settings={}): self.file = file + self.settings = { + "Identification": "HSeldon", + "FamilyName": "Seldon", + "GivenName": "Hari", + } + for key, value in settings.items(): + self.settings[key] = value def execute(self): - self.file.createIfcPerson("HSeldon", "Seldon", "Hari") + return self.file.create_entity("IfcPerson", **self.settings) diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/api.py b/src/ifcopenshell-python/ifcopenshell/api/owner/api.py deleted file mode 100644 index 4eb7c32110..0000000000 --- a/src/ifcopenshell-python/ifcopenshell/api/owner/api.py +++ /dev/null @@ -1,62 +0,0 @@ -import bpy -import time -import addon_utils -import ifcopenshell.api.owner.create_owner_history as create_owner_history_usecase -import ifcopenshell.api.owner.update_owner_history as update_owner_history_usecase -from blenderbim.bim.ifc import IfcStore - - -def update_owner_history(element, change_action=None): - if not element.OwnerHistory: - element.OwnerHistory = create_owner_history() - return - file = IfcStore.get_file() - return update_owner_history_usecase.Usecase( - file, - { - "element": element, - "person": file.by_id(int(bpy.context.scene.BIMOwnerProperties.user_person)), - "organisation": file.by_id(int(bpy.context.scene.BIMOwnerProperties.user_organisation)), - "ApplicationIdentifier": "BlenderBIM", - "ApplicationFullName": "BlenderBIM Add-on", - "Version": get_application_version(), - "ChangeAction": change_action or "MODIFIED", - }, - ).execute() - - -def create_owner_history(change_action=None): - file = IfcStore.get_file() - - if ( - not bpy.context.scene.BIMOwnerProperties.user_person - or not bpy.context.scene.BIMOwnerProperties.user_organisation - ): - if file.schema == "IFC2X3": - assert False, "A person and organisation is required in IFC2X3." - return None - - return create_owner_history_usecase.Usecase( - file, - { - "person": file.by_id(int(bpy.context.scene.BIMOwnerProperties.user_person)), - "organisation": file.by_id(int(bpy.context.scene.BIMOwnerProperties.user_organisation)), - "ApplicationIdentifier": "BlenderBIM", - "ApplicationFullName": "BlenderBIM Add-on", - "Version": get_application_version(), - "ChangeAction": change_action or "ADDED", - }, - ).execute() - - -def get_application_version(): - return ".".join( - [ - str(x) - for x in [ - addon.bl_info.get("version", (-1, -1, -1)) - for addon in addon_utils.modules() - if addon.bl_info["name"] == "BlenderBIM" - ][0] - ] - ) diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/create_owner_history.py b/src/ifcopenshell-python/ifcopenshell/api/owner/create_owner_history.py index 2648bb5a9c..bd1c7585b2 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/owner/create_owner_history.py +++ b/src/ifcopenshell-python/ifcopenshell/api/owner/create_owner_history.py @@ -1,22 +1,19 @@ import time import ifcopenshell +import ifcopenshell.api.owner.settings class Usecase: def __init__(self, file, settings={}): self.file = file - self.settings = { - "person": None, - "organisation": None, - "ApplicationIdentifier": "", - "ApplicationFullName": "", - "Version": "", - "ChangeAction": "NOTDEFINED", - } + self.settings = ifcopenshell.api.owner.settings.settings for key, value in settings.items(): self.settings[key] = value def execute(self): + if self.file.schema != "IFC2X3": + if not self.settings["person"] or not self.settings["organisation"]: + return user = self.get_user() application = self.get_application() return self.file.create_entity( @@ -25,7 +22,7 @@ class Usecase: "OwningUser": user, "OwningApplication": application, "State": "READWRITE", - "ChangeAction": self.settings["ChangeAction"], + "ChangeAction": self.settings["ChangeAction"] or "ADDED", "LastModifiedDate": int(time.time()), "LastModifyingUser": user, "LastModifyingApplication": application, diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/settings.py b/src/ifcopenshell-python/ifcopenshell/api/owner/settings.py new file mode 100644 index 0000000000..20c310efbf --- /dev/null +++ b/src/ifcopenshell-python/ifcopenshell/api/owner/settings.py @@ -0,0 +1,33 @@ +# import bpy +# import addon_utils + +settings = { + "person": None, + "organisation": None, + "ApplicationIdentifier": "", + "ApplicationFullName": "", + "Version": "", + "ChangeAction": "NOTDEFINED", +} + + +# settings = { +# "person": file.by_id(int(bpy.context.scene.BIMOwnerProperties.user_person)), +# "organisation": file.by_id(int(bpy.context.scene.BIMOwnerProperties.user_organisation)), +# "ApplicationIdentifier": "BlenderBIM", +# "ApplicationFullName": "BlenderBIM Add-on", +# "Version": get_application_version(), +# } +# +# +# def get_application_version(): +# return ".".join( +# [ +# str(x) +# for x in [ +# addon.bl_info.get("version", (-1, -1, -1)) +# for addon in addon_utils.modules() +# if addon.bl_info["name"] == "BlenderBIM" +# ][0] +# ] +# ) diff --git a/src/ifcopenshell-python/ifcopenshell/api/owner/update_owner_history.py b/src/ifcopenshell-python/ifcopenshell/api/owner/update_owner_history.py index f3be648180..603014aa45 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/owner/update_owner_history.py +++ b/src/ifcopenshell-python/ifcopenshell/api/owner/update_owner_history.py @@ -1,23 +1,19 @@ import time import ifcopenshell +import ifcopenshell.api.owner.create_owner_history as create_owner_history class Usecase: def __init__(self, file, settings={}): self.file = file - self.settings = { - "OwnerHistory": None, - "person": None, - "organisation": None, - "ApplicationIdentifier": "", - "ApplicationFullName": "", - "Version": "", - "ChangeAction": "NOTDEFINED", - } + self.settings = ifcopenshell.api.owner.settings.settings for key, value in settings.items(): self.settings[key] = value def execute(self): + if not self.settings["element"].OwnerHistory: + self.settings["element"].OwnerHistory = create_owner_history.Usecase(self.file, self.settings).execute() + return if len(self.file.get_inverse(self.settings["element"].OwnerHistory)) > 1: old_history = self.settings["element"].OwnerHistory self.settings["element"].OwnerHistory = self.file.create_entity("IfcOwnerHistory") diff --git a/src/ifcopenshell-python/ifcopenshell/api/root/create_product.py b/src/ifcopenshell-python/ifcopenshell/api/root/create_product.py index 028d5066fd..bd9852a506 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/root/create_product.py +++ b/src/ifcopenshell-python/ifcopenshell/api/root/create_product.py @@ -1,5 +1,5 @@ import ifcopenshell -from ifcopenshell.api.owner.api import create_owner_history +import ifcopenshell.api.owner.create_owner_history as create_owner_history class Usecase: @@ -16,7 +16,7 @@ class Usecase: def execute(self): element = self.file.create_entity(self.settings["ifc_class"], **{ "GlobalId": ifcopenshell.guid.new(), - "OwnerHistory": create_owner_history() + "OwnerHistory": create_owner_history.Usecase(self.file).execute() }) element.Name = self.settings["name"] or None if self.settings["predefined_type"]: diff --git a/src/ifcopenshell-python/ifcopenshell/api/structural/add_structural_analysis_model.py b/src/ifcopenshell-python/ifcopenshell/api/structural/add_structural_analysis_model.py index 1f2adca6f0..2fcee43e98 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/structural/add_structural_analysis_model.py +++ b/src/ifcopenshell-python/ifcopenshell/api/structural/add_structural_analysis_model.py @@ -1,5 +1,5 @@ import ifcopenshell -from ifcopenshell.api.owner.api import create_owner_history +import ifcopenshell.api.owner.create_owner_history as create_owner_history class Usecase: @@ -12,7 +12,7 @@ class Usecase: def execute(self): return self.file.create_entity("IfcStructuralAnalysisModel", **{ "GlobalId": ifcopenshell.guid.new(), - "OwnerHistory": create_owner_history(), + "OwnerHistory": create_owner_history.Usecase(self.file).execute(), "Name": "Unnamed", "PredefinedType": "LOADING_3D" }) diff --git a/src/ifcopenshell-python/ifcopenshell/api/structural/assign_structural_analysis_model.py b/src/ifcopenshell-python/ifcopenshell/api/structural/assign_structural_analysis_model.py index ee619d87dc..f6a93d1f86 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/structural/assign_structural_analysis_model.py +++ b/src/ifcopenshell-python/ifcopenshell/api/structural/assign_structural_analysis_model.py @@ -1,6 +1,6 @@ import ifcopenshell -from ifcopenshell.api.owner.api import create_owner_history -from ifcopenshell.api.owner.api import update_owner_history +import ifcopenshell.api.owner.create_owner_history as create_owner_history +import ifcopenshell.api.owner.update_owner_history as update_owner_history class Usecase: @@ -17,7 +17,7 @@ class Usecase: if not self.settings["structural_analysis_model"].IsGroupedBy: return self.file.create_entity("IfcRelAssignsToGroup", **{ "GlobalId": ifcopenshell.guid.new(), - "OwnerHistory": create_owner_history(), + "OwnerHistory": create_owner_history.Usecase(self.file).execute(), "RelatedObjects": [self.settings["product"]], "RelatingGroup": self.settings["structural_analysis_model"] }) @@ -25,4 +25,4 @@ class Usecase: related_objects = set(rel.RelatedObjects) or set() related_objects.add(self.settings["product"]) rel.RelatedObjects = list(related_objects) - update_owner_history(rel) + update_owner_history.Usecase(self.file, {"element": rel}).execute() diff --git a/src/ifcopenshell-python/ifcopenshell/api/structural/unassign_structural_analysis_model.py b/src/ifcopenshell-python/ifcopenshell/api/structural/unassign_structural_analysis_model.py index b2c367a2d5..21abe36004 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/structural/unassign_structural_analysis_model.py +++ b/src/ifcopenshell-python/ifcopenshell/api/structural/unassign_structural_analysis_model.py @@ -1,5 +1,5 @@ import ifcopenshell -from ifcopenshell.api.owner.api import update_owner_history +import ifcopenshell.api.owner.update_owner_history as update_owner_history class Usecase: @@ -20,6 +20,6 @@ class Usecase: related_objects.remove(self.settings["product"]) if len(related_objects): rel.RelatedObjects = list(related_objects) - update_owner_history(rel) + update_owner_history.Usecase(self.file, {"element": rel}).execute() else: self.file.remove(rel)