From b8ab478416d0e0d93894d4ef74fd3c8b42a360d9 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Fri, 29 Jan 2021 21:19:20 +1100 Subject: [PATCH] Editing attributes now stores a modified owner history --- .../bim/module/attribute/edit_attributes.py | 5 + .../blenderbim/bim/module/owner/api.py | 21 ++++ .../bim/module/owner/update_owner_history.py | 99 +++++++++++++++++++ .../bim/module/root/create_product.py | 4 +- .../blenderbim/bim/module/root/operator.py | 2 - 5 files changed, 127 insertions(+), 4 deletions(-) create mode 100644 src/ifcblenderexport/blenderbim/bim/module/owner/update_owner_history.py diff --git a/src/ifcblenderexport/blenderbim/bim/module/attribute/edit_attributes.py b/src/ifcblenderexport/blenderbim/bim/module/attribute/edit_attributes.py index 9e0c38d346..4e45c6b61b 100644 --- a/src/ifcblenderexport/blenderbim/bim/module/attribute/edit_attributes.py +++ b/src/ifcblenderexport/blenderbim/bim/module/attribute/edit_attributes.py @@ -1,3 +1,6 @@ +from blenderbim.bim.module.owner.api import update_owner_history + + class Usecase(): def __init__(self, file, settings=None): self.file = file @@ -11,3 +14,5 @@ class Usecase(): def execute(self): 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"]) diff --git a/src/ifcblenderexport/blenderbim/bim/module/owner/api.py b/src/ifcblenderexport/blenderbim/bim/module/owner/api.py index 851234ccf4..85bd8dc07f 100644 --- a/src/ifcblenderexport/blenderbim/bim/module/owner/api.py +++ b/src/ifcblenderexport/blenderbim/bim/module/owner/api.py @@ -1,9 +1,30 @@ import bpy +import time import addon_utils import blenderbim.bim.module.owner.create_owner_history as create_owner_history_usecase +import blenderbim.bim.module.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() return create_owner_history_usecase.Usecase( diff --git a/src/ifcblenderexport/blenderbim/bim/module/owner/update_owner_history.py b/src/ifcblenderexport/blenderbim/bim/module/owner/update_owner_history.py new file mode 100644 index 0000000000..7456e4c19b --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/owner/update_owner_history.py @@ -0,0 +1,99 @@ +import time +import ifcopenshell + + +class Usecase: + def __init__(self, file, settings=None): + self.file = file + self.settings = { + "OwnerHistory": None, + "person": None, + "organisation": None, + "ApplicationIdentifier": "", + "ApplicationFullName": "", + "Version": "", + "ChangeAction": "NOTDEFINED", + } + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + 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") + for i, attribute in enumerate(old_history): + self.settings["element"].OwnerHistory[i] = attribute + user = self.get_user() + application = self.get_application() + self.settings["element"].OwnerHistory.ChangeAction = self.settings["ChangeAction"] + self.settings["element"].OwnerHistory.LastModifiedDate = int(time.time()) + self.settings["element"].OwnerHistory.LastModifyingUser = user + self.settings["element"].OwnerHistory.LastModifyingApplication = application + return self.settings["OwnerHistory"] + + def get_user(self): + for element in self.file.by_type("IfcPersonAndOrganization"): + if ( + element.ThePerson == self.settings["person"] + and element.TheOrganization == self.settings["organisation"] + ): + return element + return self.file.create_entity( + "IfcPersonAndOrganization", + **{"ThePerson": self.settings["person"], "TheOrganization": self.settings["organisation"]}, + ) + + def get_application(self): + for element in self.file.by_type("IfcApplication"): + if element.ApplicationIdentifier == self.settings["ApplicationIdentifier"]: + return element + return self.file.create_entity( + "IfcApplication", + **{ + "ApplicationDeveloper": self.get_application_organisation(), + "Version": self.settings["Version"], + "ApplicationFullName": self.settings["ApplicationFullName"], + "ApplicationIdentifier": self.settings["ApplicationIdentifier"], + }, + ) + + def get_application_organisation(self): + return self.file.create_entity( + "IfcOrganization", + **{ + "Name": "IfcOpenShell", + "Description": "IfcOpenShell is an open source (LGPL) software library that helps users and software developers to work with the IFC file format.", + "Roles": [ + self.file.create_entity("IfcActorRole", **{"Role": "USERDEFINED", "UserDefinedRole": "CONTRIBUTOR"}) + ], + "Addresses": [ + self.file.create_entity( + "IfcTelecomAddress", + **{ + "Purpose": "USERDEFINED", + "UserDefinedPurpose": "WEBPAGE", + "Description": "The main webpage of the software collection.", + "WWWHomePageURL": "https://ifcopenshell.org", + }, + ), + self.file.create_entity( + "IfcTelecomAddress", + **{ + "Purpose": "USERDEFINED", + "UserDefinedPurpose": "WEBPAGE", + "Description": "The BlenderBIM Add-on webpage of the software collection.", + "WWWHomePageURL": "https://blenderbim.org", + }, + ), + self.file.create_entity( + "IfcTelecomAddress", + **{ + "Purpose": "USERDEFINED", + "UserDefinedPurpose": "REPOSITORY", + "Description": "The source code repository of the software collection.", + "WWWHomePageURL": "https://github.com/IfcOpenShell/IfcOpenShell.git", + }, + ), + ], + }, + ) diff --git a/src/ifcblenderexport/blenderbim/bim/module/root/create_product.py b/src/ifcblenderexport/blenderbim/bim/module/root/create_product.py index 6951854560..9c28729096 100644 --- a/src/ifcblenderexport/blenderbim/bim/module/root/create_product.py +++ b/src/ifcblenderexport/blenderbim/bim/module/root/create_product.py @@ -1,4 +1,5 @@ import ifcopenshell +from blenderbim.bim.module.owner.api import create_owner_history class Usecase: @@ -8,7 +9,6 @@ class Usecase: "ifc_class": "IfcBuildingElementProxy", "predefined_type": None, "name": None, - "OwnerHistory": None, } for key, value in settings.items(): self.settings[key] = value @@ -16,7 +16,7 @@ class Usecase: def execute(self): element = self.file.create_entity(self.settings["ifc_class"], **{ "GlobalId": ifcopenshell.guid.new(), - "OwnerHistory": self.settings["OwnerHistory"] + "OwnerHistory": create_owner_history() }) element.Name = self.settings["name"] or None if self.settings["predefined_type"] and hasattr(element, "PredefinedType"): diff --git a/src/ifcblenderexport/blenderbim/bim/module/root/operator.py b/src/ifcblenderexport/blenderbim/bim/module/root/operator.py index 16e6f0bf05..e65b38b983 100644 --- a/src/ifcblenderexport/blenderbim/bim/module/root/operator.py +++ b/src/ifcblenderexport/blenderbim/bim/module/root/operator.py @@ -6,7 +6,6 @@ import blenderbim.bim.module.root.create_product as create_product import blenderbim.bim.module.root.remove_product as remove_product import blenderbim.bim.module.root.reassign_class as reassign_class import blenderbim.bim.module.root.copy_class as copy_class -from blenderbim.bim.module.owner.api import create_owner_history from blenderbim.bim.ifc import IfcStore @@ -106,7 +105,6 @@ class AssignClass(bpy.types.Operator): "ifc_class": self.ifc_class, "predefined_type": self.predefined_type, "name": obj.name, - "OwnerHistory": create_owner_history() }, ).execute() obj.name = "{}/{}".format(product.is_a(), obj.name)