diff --git a/src/ifcblenderexport/blenderbim/bim/module/owner/api.py b/src/ifcblenderexport/blenderbim/bim/module/owner/api.py new file mode 100644 index 0000000000..851234ccf4 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/owner/api.py @@ -0,0 +1,32 @@ +import bpy +import addon_utils +import blenderbim.bim.module.owner.create_owner_history as create_owner_history_usecase +from blenderbim.bim.ifc import IfcStore + + +def create_owner_history(change_action=None): + file = IfcStore.get_file() + 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/ifcblenderexport/blenderbim/bim/module/owner/create_owner_history.py b/src/ifcblenderexport/blenderbim/bim/module/owner/create_owner_history.py new file mode 100644 index 0000000000..f91b275375 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/owner/create_owner_history.py @@ -0,0 +1,101 @@ +import time +import ifcopenshell + + +class Usecase: + def __init__(self, file, settings=None): + self.file = file + self.settings = { + "person": None, + "organisation": None, + "ApplicationIdentifier": "", + "ApplicationFullName": "", + "Version": "", + "ChangeAction": "NOTDEFINED", + } + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + user = self.get_user() + application = self.get_application() + return self.file.create_entity( + "IfcOwnerHistory", + **{ + "OwningUser": user, + "OwningApplication": application, + "State": "READWRITE", + "ChangeAction": self.settings["ChangeAction"], + "LastModifiedDate": int(time.time()), + "LastModifyingUser": user, + "LastModifyingApplication": application, + "CreationDate": int(time.time()), + }, + ) + + 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/owner/prop.py b/src/ifcblenderexport/blenderbim/bim/module/owner/prop.py index 5140f1f4ce..da71f4b064 100644 --- a/src/ifcblenderexport/blenderbim/bim/module/owner/prop.py +++ b/src/ifcblenderexport/blenderbim/bim/module/owner/prop.py @@ -22,7 +22,7 @@ def getPersons(self, context): if "Id" in person: identifier = person["Id"] or "" else: - identifier = person["Identifier"] or "" + identifier = person["Identification"] or "" results.append((str(ifc_id), identifier, "")) return results diff --git a/src/ifcblenderexport/blenderbim/bim/module/owner/ui.py b/src/ifcblenderexport/blenderbim/bim/module/owner/ui.py index cae55b06cc..d0b82a39c0 100644 --- a/src/ifcblenderexport/blenderbim/bim/module/owner/ui.py +++ b/src/ifcblenderexport/blenderbim/bim/module/owner/ui.py @@ -110,6 +110,7 @@ class BIM_PT_people(Panel): self.file = IfcStore.get_file() self.layout.use_property_split = True + self.layout.use_property_decorate = False props = context.scene.BIMOwnerProperties row = self.layout.row() @@ -169,6 +170,7 @@ class BIM_PT_organisations(Panel): self.file = IfcStore.get_file() self.layout.use_property_split = True + self.layout.use_property_decorate = False props = context.scene.BIMOwnerProperties row = self.layout.row() @@ -216,6 +218,7 @@ class BIM_PT_owner(Panel): Data.load() self.layout.use_property_split = True + self.layout.use_property_decorate = False props = context.scene.BIMOwnerProperties if not Data.people: diff --git a/src/ifcblenderexport/blenderbim/bim/module/project/operator.py b/src/ifcblenderexport/blenderbim/bim/module/project/operator.py index 7f50b49a2b..b6ac9fbafe 100644 --- a/src/ifcblenderexport/blenderbim/bim/module/project/operator.py +++ b/src/ifcblenderexport/blenderbim/bim/module/project/operator.py @@ -2,9 +2,6 @@ import bpy import logging import ifcopenshell import blenderbim.bim.module.project.create_file as create_file -import blenderbim.bim.module.context.add_context as add_context -import blenderbim.bim.module.root.create_product as create_product -import blenderbim.bim.module.aggregate.assign_object as assign_object import bpy from blenderbim.bim.ifc import IfcStore @@ -23,6 +20,9 @@ class CreateProject(bpy.types.Operator): IfcStore.file = create_file.Usecase({"version": bpy.context.scene.BIMProperties.export_schema}).execute() self.file = IfcStore.get_file() + bpy.ops.bim.add_person() + bpy.ops.bim.add_organisation() + project = bpy.data.objects.new("My Project", None) site = bpy.data.objects.new("My Site", None) building = bpy.data.objects.new("My Building", None) @@ -50,15 +50,6 @@ class CreateProject(bpy.types.Operator): # Data.load() return {"FINISHED"} - def assign_object(self, product, relating_object): - assign_object.Usecase( - self.file, - { - "product": product, - "relating_object": relating_object, - }, - ).execute() - class ValidateIfcFile(bpy.types.Operator): bl_idname = "bim.validate_ifc_file" diff --git a/src/ifcblenderexport/blenderbim/bim/module/root/create_product.py b/src/ifcblenderexport/blenderbim/bim/module/root/create_product.py index b42b7e1a59..6951854560 100644 --- a/src/ifcblenderexport/blenderbim/bim/module/root/create_product.py +++ b/src/ifcblenderexport/blenderbim/bim/module/root/create_product.py @@ -8,12 +8,16 @@ class Usecase: "ifc_class": "IfcBuildingElementProxy", "predefined_type": None, "name": None, + "OwnerHistory": None, } for key, value in settings.items(): self.settings[key] = value def execute(self): - element = self.file.create_entity(self.settings["ifc_class"], **{"GlobalId": ifcopenshell.guid.new()}) + element = self.file.create_entity(self.settings["ifc_class"], **{ + "GlobalId": ifcopenshell.guid.new(), + "OwnerHistory": self.settings["OwnerHistory"] + }) element.Name = self.settings["name"] or None if self.settings["predefined_type"] and hasattr(element, "PredefinedType"): try: diff --git a/src/ifcblenderexport/blenderbim/bim/module/root/operator.py b/src/ifcblenderexport/blenderbim/bim/module/root/operator.py index 279af04897..d163a26642 100644 --- a/src/ifcblenderexport/blenderbim/bim/module/root/operator.py +++ b/src/ifcblenderexport/blenderbim/bim/module/root/operator.py @@ -5,6 +5,7 @@ import ifcopenshell.util.schema 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 +from blenderbim.bim.module.owner.api import create_owner_history from blenderbim.bim.ifc import IfcStore @@ -104,6 +105,7 @@ 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)