diff --git a/src/blenderbim/blenderbim/bim/module/owner/__init__.py b/src/blenderbim/blenderbim/bim/module/owner/__init__.py index 14bc0b1c95..9b676a586d 100644 --- a/src/blenderbim/blenderbim/bim/module/owner/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/owner/__init__.py @@ -20,6 +20,7 @@ import bpy from . import ui, prop, operator classes = ( + operator.AddActor, operator.AddAddress, operator.AddAddressAttribute, operator.AddOrganisation, @@ -28,18 +29,22 @@ classes = ( operator.AddPersonAttribute, operator.AddRole, operator.ClearUser, + operator.DisableEditingActor, operator.DisableEditingAddress, operator.DisableEditingOrganisation, operator.DisableEditingPerson, operator.DisableEditingRole, + operator.EditActor, operator.EditAddress, operator.EditOrganisation, operator.EditPerson, operator.EditRole, + operator.EnableEditingActor, operator.EnableEditingAddress, operator.EnableEditingOrganisation, operator.EnableEditingPerson, operator.EnableEditingRole, + operator.RemoveActor, operator.RemoveAddress, operator.RemoveAddressAttribute, operator.RemoveOrganisation, @@ -52,6 +57,7 @@ classes = ( ui.BIM_PT_people, ui.BIM_PT_organisations, ui.BIM_PT_owner, + ui.BIM_PT_actor, ) diff --git a/src/blenderbim/blenderbim/bim/module/owner/data.py b/src/blenderbim/blenderbim/bim/module/owner/data.py index 85fecf528a..3eae8fc574 100644 --- a/src/blenderbim/blenderbim/bim/module/owner/data.py +++ b/src/blenderbim/blenderbim/bim/module/owner/data.py @@ -24,6 +24,7 @@ def refresh(): PeopleData.is_loaded = False OrganisationsData.is_loaded = False OwnerData.is_loaded = False + ActorData.is_loaded = False class RolesAddressesData: @@ -202,3 +203,30 @@ class OwnerData: } ) return results + + +class ActorData: + data = {} + is_loaded = False + + @classmethod + def load(cls): + cls.data = { + "actor": cls.actor(), + "actors": cls.actors(), + } + cls.is_loaded = True + + @classmethod + def actor(cls): + ifc_class = bpy.context.scene.BIMOwnerProperties.actor_type + return [(str(p.id()), p[0] or "Unnamed", "") for p in tool.Ifc.get().by_type(ifc_class)] + + @classmethod + def actors(cls): + actors = [] + props = bpy.context.scene.BIMOwnerProperties + for actor in tool.Ifc.get().by_type(props.actor_class, include_subtypes=False): + is_editing = props.active_actor_id == actor.id() + actors.append({"id": actor.id(), "name": actor.Name or "Unnamed", "is_editing": is_editing}) + return actors diff --git a/src/blenderbim/blenderbim/bim/module/owner/operator.py b/src/blenderbim/blenderbim/bim/module/owner/operator.py index 45b9c7f503..d678369ac2 100644 --- a/src/blenderbim/blenderbim/bim/module/owner/operator.py +++ b/src/blenderbim/blenderbim/bim/module/owner/operator.py @@ -306,3 +306,52 @@ class ClearUser(bpy.types.Operator, Operator): def _execute(self, context): core.clear_user(tool.Owner) + + +class AddActor(bpy.types.Operator, Operator): + bl_idname = "bim.add_actor" + bl_label = "Add Actor" + bl_options = {"REGISTER", "UNDO"} + + def _execute(self, context): + props = bpy.context.scene.BIMOwnerProperties + if props.actor: + core.add_actor(tool.Ifc, ifc_class=props.actor_class, actor=tool.Ifc.get().by_id(int(props.actor))) + + +class EnableEditingActor(bpy.types.Operator, Operator): + bl_idname = "bim.enable_editing_actor" + bl_label = "Enable Editing Actor" + bl_options = {"REGISTER", "UNDO"} + actor: bpy.props.IntProperty() + + def _execute(self, context): + core.enable_editing_actor(tool.Owner, actor=tool.Ifc.get().by_id(self.actor)) + + +class DisableEditingActor(bpy.types.Operator, Operator): + bl_idname = "bim.disable_editing_actor" + bl_label = "Disable Editing Actor" + bl_options = {"REGISTER", "UNDO"} + + def _execute(self, context): + core.disable_editing_actor(tool.Owner) + + +class EditActor(bpy.types.Operator, Operator): + bl_idname = "bim.edit_actor" + bl_label = "Edit Actor" + bl_options = {"REGISTER", "UNDO"} + + def _execute(self, context): + core.edit_actor(tool.Ifc, tool.Owner) + + +class RemoveActor(bpy.types.Operator, Operator): + bl_idname = "bim.remove_actor" + bl_label = "Remove Actor" + bl_options = {"REGISTER", "UNDO"} + actor: bpy.props.IntProperty() + + def _execute(self, context): + core.remove_actor(tool.Ifc, actor=tool.Ifc.get().by_id(self.actor)) diff --git a/src/blenderbim/blenderbim/bim/module/owner/prop.py b/src/blenderbim/blenderbim/bim/module/owner/prop.py index 23a2e8d413..49759be4bc 100644 --- a/src/blenderbim/blenderbim/bim/module/owner/prop.py +++ b/src/blenderbim/blenderbim/bim/module/owner/prop.py @@ -18,7 +18,7 @@ import bpy from blenderbim.bim.prop import StrProperty, Attribute -from blenderbim.bim.module.owner.data import OwnerData +from blenderbim.bim.module.owner.data import OwnerData, ActorData from bpy.types import PropertyGroup from bpy.props import ( PointerProperty, @@ -44,6 +44,20 @@ def get_user_organisation(self, context): return OwnerData.data["user_organisation"] +def get_actor(self, context): + if not ActorData.is_loaded: + ActorData.load() + return ActorData.data["actor"] + + +def update_actor_type(self, context): + ActorData.data["actor"] = ActorData.actor() + + +def update_actor_class(self, context): + ActorData.data["actors"] = ActorData.actors() + + class BIMOwnerProperties(PropertyGroup): active_person_id: IntProperty(name="Active Person Id") person_attributes: CollectionProperty(name="Person Attributes", type=Attribute) @@ -64,3 +78,20 @@ class BIMOwnerProperties(PropertyGroup): user_person: EnumProperty(items=get_user_person, name="Person") user_organisation: EnumProperty(items=get_user_organisation, name="Organisation") active_user_id: IntProperty(name="Active User Id") + active_actor_id: IntProperty(name="Active Actor Id") + actor_attributes: CollectionProperty(name="Actor Attributes", type=Attribute) + actor_class: EnumProperty( + items=(("IfcActor", "Actor", ""), ("IfcOccupant", "Occupant", "")), + name="Actor Type", + update=update_actor_class, + ) + actor_type: EnumProperty( + items=( + ("IfcPerson", "Person", ""), + ("IfcOrganization", "Organisation", ""), + ("IfcPersonAndOrganization", "User", ""), + ), + name="Actor Type", + update=update_actor_type, + ) + actor: EnumProperty(items=get_actor, name="Actor") diff --git a/src/blenderbim/blenderbim/bim/module/owner/ui.py b/src/blenderbim/blenderbim/bim/module/owner/ui.py index 2d6c9c39de..e3902775c8 100644 --- a/src/blenderbim/blenderbim/bim/module/owner/ui.py +++ b/src/blenderbim/blenderbim/bim/module/owner/ui.py @@ -19,7 +19,7 @@ import bpy import blenderbim.bim.helper import blenderbim.tool as tool -from blenderbim.bim.module.owner.data import PeopleData, OrganisationsData, OwnerData +from blenderbim.bim.module.owner.data import PeopleData, OrganisationsData, OwnerData, ActorData def draw_roles(box, parent): @@ -227,3 +227,52 @@ class BIM_PT_owner(bpy.types.Panel): row.operator("bim.set_user", icon="KEYFRAME_HLT", text="").user = user["id"] op = row.operator("bim.remove_person_and_organisation", icon="X", text="") op.person_and_organisation = user["id"] + + +class BIM_PT_actor(bpy.types.Panel): + bl_label = "IFC Actor" + bl_idname = "BIM_PT_actor" + bl_options = {"DEFAULT_CLOSED"} + bl_space_type = "PROPERTIES" + bl_region_type = "WINDOW" + bl_context = "scene" + bl_parent_id = "BIM_PT_project_setup" + + @classmethod + def poll(cls, context): + return tool.Ifc.get() + + def draw(self, context): + if not ActorData.is_loaded: + ActorData.load() + + self.props = context.scene.BIMOwnerProperties + + self.layout.use_property_split = True + self.layout.use_property_decorate = False + + row = self.layout.row(align=True) + row.prop(self.props, "actor_class", text="") + row.prop(self.props, "actor_type", text="") + if ActorData.data["actor"]: + row = self.layout.row(align=True) + row.prop(self.props, "actor", text="") + row.operator("bim.add_actor", icon="ADD", text="") + else: + self.layout.label(text="No users found.") + + for actor in ActorData.data["actors"]: + self.draw_actor(actor) + + def draw_actor(self, actor): + if actor["is_editing"]: + box = self.layout.box() + row = box.row(align=True) + row.operator("bim.edit_actor", icon="CHECKMARK") + row.operator("bim.disable_editing_actor", icon="CANCEL", text="") + blenderbim.bim.helper.draw_attributes(self.props.actor_attributes, box) + else: + row = self.layout.row(align=True) + row.label(text=actor["name"]) + row.operator("bim.enable_editing_actor", icon="GREASEPENCIL", text="").actor = actor["id"] + row.operator("bim.remove_actor", icon="X", text="").actor = actor["id"] diff --git a/src/blenderbim/blenderbim/core/owner.py b/src/blenderbim/blenderbim/core/owner.py index 077c840325..65b28cac39 100644 --- a/src/blenderbim/blenderbim/core/owner.py +++ b/src/blenderbim/blenderbim/core/owner.py @@ -143,3 +143,25 @@ def get_user(owner): def clear_user(owner): owner.clear_user() + + +def add_actor(ifc, ifc_class=None, actor=None): + return ifc.run("owner.add_actor", ifc_class=ifc_class, actor=actor) + + +def remove_actor(ifc, actor=None): + ifc.run("owner.remove_actor", actor=actor) + + +def enable_editing_actor(owner, actor=None): + owner.set_actor(actor) + owner.import_actor_attributes(actor) + + +def disable_editing_actor(owner): + owner.clear_actor() + + +def edit_actor(ifc, owner): + ifc.run("owner.edit_actor", actor=owner.get_actor(), attributes=owner.export_actor_attributes()) + disable_editing_actor(owner) diff --git a/src/blenderbim/blenderbim/core/tool.py b/src/blenderbim/blenderbim/core/tool.py index f1676b4b4f..2acf081f77 100644 --- a/src/blenderbim/blenderbim/core/tool.py +++ b/src/blenderbim/blenderbim/core/tool.py @@ -271,26 +271,31 @@ class Patch: class Owner: def add_address_attribute(cls, name): pass def add_person_attribute(cls, name): pass + def clear_actor(cls): pass def clear_address(cls): pass def clear_organisation(cls): pass def clear_person(cls): pass def clear_role(cls): pass def clear_user(cls): pass + def export_actor_attributes(cls): pass def export_address_attributes(cls): pass def export_organisation_attributes(cls): pass def export_person_attributes(cls): pass def export_role_attributes(cls): pass + def get_actor(cls): pass def get_address(cls): pass def get_organisation(cls): pass def get_person(cls): pass def get_role(cls): pass def get_user(cls): pass + def import_actor_attributes(cls, actor): pass def import_address_attributes(cls): pass def import_organisation_attributes(cls): pass def import_person_attributes(cls): pass def import_role_attributes(cls): pass def remove_address_attribute(cls, name, id): pass def remove_person_attribute(cls, name, id): pass + def set_actor(cls, actor): pass def set_address(cls, address): pass def set_organisation(cls, organisation): pass def set_person(cls, person): pass diff --git a/src/blenderbim/blenderbim/tool/owner.py b/src/blenderbim/blenderbim/tool/owner.py index 0a3ede8b66..bd5f068adc 100644 --- a/src/blenderbim/blenderbim/tool/owner.py +++ b/src/blenderbim/blenderbim/tool/owner.py @@ -234,3 +234,27 @@ class Owner(blenderbim.core.tool.Owner): @classmethod def export_role_attributes(cls): return blenderbim.bim.helper.export_attributes(bpy.context.scene.BIMOwnerProperties.role_attributes) + + @classmethod + def set_actor(cls, actor): + bpy.context.scene.BIMOwnerProperties.active_actor_id = actor.id() + + @classmethod + def import_actor_attributes(cls, actor): + props = bpy.context.scene.BIMOwnerProperties + props.actor_attributes.clear() + blenderbim.bim.helper.import_attributes2(actor, props.actor_attributes) + + @classmethod + def clear_actor(cls): + bpy.context.scene.BIMOwnerProperties.active_actor_id = 0 + + @classmethod + def export_actor_attributes(cls): + props = bpy.context.scene.BIMOwnerProperties + attributes = blenderbim.bim.helper.export_attributes(props.actor_attributes) + return attributes + + @classmethod + def get_actor(cls): + return tool.Ifc().get().by_id(bpy.context.scene.BIMOwnerProperties.active_actor_id) diff --git a/src/blenderbim/test/bim/feature/owner.feature b/src/blenderbim/test/bim/feature/owner.feature index 383edabd5f..3e8f13513f 100644 --- a/src/blenderbim/test/bim/feature/owner.feature +++ b/src/blenderbim/test/bim/feature/owner.feature @@ -237,3 +237,43 @@ Scenario: Clear user Given an empty IFC project When I press "bim.clear_user(user={user})" Then nothing happens + +Scenario: Add actor + Given an empty IFC project + And I press "bim.add_person" + When I press "bim.add_actor" + Then nothing happens + +Scenario: Remove actor + Given an empty IFC project + And I press "bim.add_person" + And I press "bim.add_actor" + And the variable "actor" is "{ifc}.by_type('IfcActor')[-1].id()" + When I press "bim.remove_actor(actor={actor})" + Then nothing happens + +Scenario: Enable editing actor + Given an empty IFC project + And I press "bim.add_person" + And I press "bim.add_actor" + And the variable "actor" is "{ifc}.by_type('IfcActor')[0].id()" + When I press "bim.enable_editing_actor(actor={actor})" + Then "scene.BIMOwnerProperties.active_actor_id" is "{actor}" + +Scenario: Disable editing actor + Given an empty IFC project + And I press "bim.add_person" + And I press "bim.add_actor" + And the variable "actor" is "{ifc}.by_type('IfcActor')[0].id()" + And I press "bim.enable_editing_actor(actor={actor})" + When I press "bim.disable_editing_actor" + Then "scene.BIMOwnerProperties.active_actor_id" is "0" + +Scenario: Edit actor + Given an empty IFC project + And I press "bim.add_person" + And I press "bim.add_actor" + And the variable "actor" is "{ifc}.by_type('IfcActor')[0].id()" + And I press "bim.enable_editing_actor(actor={actor})" + When I press "bim.edit_actor" + Then "scene.BIMOwnerProperties.active_actor_id" is "0" diff --git a/src/blenderbim/test/core/test_owner.py b/src/blenderbim/test/core/test_owner.py index 62beb32bd1..91e23281c6 100644 --- a/src/blenderbim/test/core/test_owner.py +++ b/src/blenderbim/test/core/test_owner.py @@ -225,3 +225,37 @@ class TestClearUser: def test_run(self, owner): owner.clear_user().should_be_called() subject.clear_user(owner) + + +class TestAddActor: + def test_run(self, ifc): + ifc.run("owner.add_actor", ifc_class="IfcActor", actor="person").should_be_called().will_return("actor") + assert subject.add_actor(ifc, ifc_class="IfcActor", actor="person") == "actor" + + +class TestRemoveActor: + def test_run(self, ifc): + ifc.run("owner.remove_actor", actor="actor").should_be_called() + subject.remove_actor(ifc, actor="actor") + + +class TestEnableEditingActor: + def test_run(self, owner): + owner.set_actor("actor").should_be_called() + owner.import_actor_attributes("actor").should_be_called() + subject.enable_editing_actor(owner, actor="actor") + + +class TestDisableEditingActor: + def test_run(self, owner): + owner.clear_actor().should_be_called() + subject.disable_editing_actor(owner) + + +class TestEditActor: + def test_run(self, ifc, owner): + owner.get_actor().should_be_called().will_return("actor") + owner.export_actor_attributes().should_be_called().will_return("attributes") + ifc.run("owner.edit_actor", actor="actor", attributes="attributes").should_be_called() + owner.clear_actor().should_be_called() + subject.edit_actor(ifc, owner) diff --git a/src/blenderbim/test/tool/test_owner.py b/src/blenderbim/test/tool/test_owner.py index 41d398f93a..c8ec43a6bf 100644 --- a/src/blenderbim/test/tool/test_owner.py +++ b/src/blenderbim/test/tool/test_owner.py @@ -29,13 +29,234 @@ class TestImplementsTool(NewFile): assert isinstance(subject(), blenderbim.core.tool.Owner) -class TestSetUser(NewFile): +class TestAddAddressAttribute(NewFile): + def test_run(self): + subject().add_address_attribute("AddressLines") + subject().add_address_attribute("TelephoneNumbers") + subject().add_address_attribute("FacsimileNumbers") + subject().add_address_attribute("ElectronicMailAddresses") + subject().add_address_attribute("MessagingIDs") + props = bpy.context.scene.BIMOwnerProperties + assert len(props.address_lines) == 1 + assert len(props.telephone_numbers) == 1 + assert len(props.facsimile_numbers) == 1 + assert len(props.electronic_mail_addresses) == 1 + assert len(props.messaging_ids) == 1 + + +class TestAddPersonAttribute(NewFile): + def test_run(self): + subject().add_person_attribute("MiddleNames") + subject().add_person_attribute("PrefixTitles") + subject().add_person_attribute("SuffixTitles") + props = bpy.context.scene.BIMOwnerProperties + assert len(props.middle_names) == 1 + assert len(props.prefix_titles) == 1 + assert len(props.suffix_titles) == 1 + + +class TestClearActor(NewFile): def test_run(self): ifc = ifcopenshell.file() - tool.Ifc.set(ifc) - user = ifc.createIfcPersonAndOrganization() - subject.set_user(user) - assert bpy.context.scene.BIMOwnerProperties.active_user_id == user.id() + actor = ifc.createIfcActor() + subject().set_actor(actor) + subject().clear_actor() + assert bpy.context.scene.BIMOwnerProperties.active_actor_id == 0 + + +class TestClearAddress(NewFile): + def test_run(self): + ifc = ifcopenshell.file() + address = ifc.createIfcPostalAddress() + subject().set_address(address) + subject().clear_address() + assert bpy.context.scene.BIMOwnerProperties.active_address_id == 0 + + +class TestClearOrganisation(NewFile): + def test_run(self): + props = bpy.context.scene.BIMOwnerProperties + props.active_organisation_id = 1 + subject().clear_organisation() + assert props.active_organisation_id == 0 + + +class TestClearPerson(NewFile): + def test_run(self): + props = bpy.context.scene.BIMOwnerProperties + props.active_person_id = 1 + subject().clear_person() + assert props.active_person_id == 0 + + +class TestClearRole(NewFile): + def test_run(self): + role = ifcopenshell.file().createIfcActorRole() + subject().set_role(role) + subject().clear_role() + assert bpy.context.scene.BIMOwnerProperties.active_role_id == 0 + + +class TestClearUser(NewFile): + def test_run(self): + TestSetUser().test_run() + subject.clear_user() + assert bpy.context.scene.BIMOwnerProperties.active_user_id == 0 + + +class TestExportActorAttributes(NewFile): + def test_exporting_an_actor(self): + TestImportActorAttributes().test_importing_an_actor() + assert subject().export_actor_attributes() == { + "GlobalId": "GlobalId", + "Name": "Name", + "Description": "Description", + "ObjectType": "ObjectType", + } + + def test_exporting_an_occupant(self): + TestImportActorAttributes().test_importing_an_occupant() + assert subject().export_actor_attributes() == { + "GlobalId": "GlobalId", + "Name": "Name", + "Description": "Description", + "ObjectType": "ObjectType", + "PredefinedType": "TENANT", + } + + +class TestExportAddressAttributes(NewFile): + def test_exporting_a_postal_address(self): + TestImportAddressAttributes().test_importing_a_postal_address() + assert subject().export_address_attributes() == { + "Purpose": "USERDEFINED", + "Description": "Description", + "UserDefinedPurpose": "UserDefinedPurpose", + "InternalLocation": "InternalLocation", + "AddressLines": ["Address", "Lines"], + "PostalBox": "PostalBox", + "Town": "Town", + "Region": "Region", + "PostalCode": "PostalCode", + "Country": "Country", + } + + def test_exporting_a_telecom_address(self): + TestImportAddressAttributes().test_importing_a_telecom_address() + assert subject().export_address_attributes() == { + "Purpose": "USERDEFINED", + "Description": "Description", + "UserDefinedPurpose": "UserDefinedPurpose", + "TelephoneNumbers": ["Telephone", "Numbers"], + "FacsimileNumbers": ["Facsimile", "Numbers"], + "PagerNumber": "PagerNumber", + "ElectronicMailAddresses": ["Electronic", "Mail", "Addresses"], + "WWWHomePageURL": "WWWHomePageURL", + "MessagingIDs": ["Messaging", "IDs"], + } + + +class TestExportOrganisationAttributes(NewFile): + def test_run(self): + TestImportOrganisationAttributes().test_run() + assert subject().export_organisation_attributes() == { + "Identification": "Identification", + "Name": "Name", + "Description": "Description", + } + + +class TestExportPersonAttributes(NewFile): + def test_run(self): + ifc = ifcopenshell.file() + tool.Ifc().set(ifc) + person = ifc.createIfcPerson() + person.Identification = "identification" + person.GivenName = "given_name" + person.FamilyName = "family_name" + person.MiddleNames = ("middle", "names") + person.PrefixTitles = ("prefix", "titles") + person.SuffixTitles = ("suffix", "titles") + subject().set_person(person) + subject().import_person_attributes() + assert subject().export_person_attributes() == { + "Identification": "identification", + "GivenName": "given_name", + "FamilyName": "family_name", + "MiddleNames": ["middle", "names"], + "PrefixTitles": ["prefix", "titles"], + "SuffixTitles": ["suffix", "titles"], + } + + def test_getting_empty_list_attributes_as_none(self): + ifc = ifcopenshell.file() + tool.Ifc().set(ifc) + result = subject().export_person_attributes() + assert result["MiddleNames"] is None + assert result["PrefixTitles"] is None + assert result["SuffixTitles"] is None + + +class TestExportRoleAttributes(NewFile): + def test_run(self): + ifc = ifcopenshell.file() + tool.Ifc().set(ifc) + role = ifc.createIfcActorRole() + role.Role = "USERDEFINED" + role.UserDefinedRole = "UserDefinedRole" + role.Description = "Description" + subject().set_role(role) + subject().import_role_attributes() + assert subject().export_role_attributes() == { + "Role": "USERDEFINED", + "UserDefinedRole": "UserDefinedRole", + "Description": "Description", + } + + +class TestGetActor(NewFile): + def test_run(self): + ifc = ifcopenshell.file() + tool.Ifc().set(ifc) + actor = ifc.createIfcActor() + subject().set_actor(actor) + assert subject().get_actor() == actor + + +class TestGetAddress(NewFile): + def test_run(self): + ifc = ifcopenshell.file() + tool.Ifc().set(ifc) + address = ifc.createIfcPostalAddress() + subject().set_address(address) + assert subject().get_address() == address + + +class TestGetOrganisation(NewFile): + def test_run(self): + ifc = ifcopenshell.file() + tool.Ifc().set(ifc) + organisation = ifc.createIfcOrganization() + subject().set_organisation(organisation) + assert subject().get_organisation() == organisation + + +class TestGetPerson(NewFile): + def test_run(self): + ifc = ifcopenshell.file() + tool.Ifc().set(ifc) + person = ifc.createIfcPerson() + subject().set_person(person) + assert subject().get_person() == person + + +class TestGetRole(NewFile): + def test_run(self): + ifc = ifcopenshell.file() + tool.Ifc().set(ifc) + role = ifc.createIfcActorRole() + subject().set_role(role) + assert subject().get_role() == role class TestGetUser(NewFile): @@ -56,19 +277,40 @@ class TestGetUser(NewFile): assert subject.get_user() == user2 -class TestClearUser(NewFile): - def test_run(self): - TestSetUser().test_run() - subject.clear_user() - assert bpy.context.scene.BIMOwnerProperties.active_user_id == 0 - - -class TestSetAddress(NewFile): - def test_run(self): +class TestImportActorAttributes(NewFile): + def test_importing_an_actor(self): ifc = ifcopenshell.file() - address = ifc.createIfcPostalAddress() - subject().set_address(address) - assert bpy.context.scene.BIMOwnerProperties.active_address_id == address.id() + tool.Ifc().set(ifc) + actor = ifc.createIfcActor() + actor.GlobalId = "GlobalId" + actor.Name = "Name" + actor.Description = "Description" + actor.ObjectType = "ObjectType" + subject.set_actor(actor) + subject.import_actor_attributes(actor) + props = bpy.context.scene.BIMOwnerProperties + assert props.actor_attributes.get("GlobalId").string_value == "GlobalId" + assert props.actor_attributes.get("Name").string_value == "Name" + assert props.actor_attributes.get("Description").string_value == "Description" + assert props.actor_attributes.get("ObjectType").string_value == "ObjectType" + + def test_importing_an_occupant(self): + ifc = ifcopenshell.file() + tool.Ifc().set(ifc) + actor = ifc.createIfcOccupant() + actor.GlobalId = "GlobalId" + actor.Name = "Name" + actor.Description = "Description" + actor.ObjectType = "ObjectType" + actor.PredefinedType = "TENANT" + subject.set_actor(actor) + subject.import_actor_attributes(actor) + props = bpy.context.scene.BIMOwnerProperties + assert props.actor_attributes.get("GlobalId").string_value == "GlobalId" + assert props.actor_attributes.get("Name").string_value == "Name" + assert props.actor_attributes.get("Description").string_value == "Description" + assert props.actor_attributes.get("ObjectType").string_value == "ObjectType" + assert props.actor_attributes.get("PredefinedType").enum_value == "TENANT" class TestImportAddressAttributes(NewFile): @@ -152,92 +394,6 @@ class TestImportAddressAttributes(NewFile): assert len(props.messaging_ids) == 0 -class TestClearAddress(NewFile): - def test_run(self): - ifc = ifcopenshell.file() - address = ifc.createIfcPostalAddress() - subject().set_address(address) - subject().clear_address() - assert bpy.context.scene.BIMOwnerProperties.active_address_id == 0 - - -class TestGetAddress(NewFile): - def test_run(self): - ifc = ifcopenshell.file() - tool.Ifc().set(ifc) - address = ifc.createIfcPostalAddress() - subject().set_address(address) - assert subject().get_address() == address - - -class TestExportAttributes(NewFile): - def test_exporting_a_postal_address(self): - TestImportAddressAttributes().test_importing_a_postal_address() - assert subject().export_address_attributes() == { - "Purpose": "USERDEFINED", - "Description": "Description", - "UserDefinedPurpose": "UserDefinedPurpose", - "InternalLocation": "InternalLocation", - "AddressLines": ["Address", "Lines"], - "PostalBox": "PostalBox", - "Town": "Town", - "Region": "Region", - "PostalCode": "PostalCode", - "Country": "Country", - } - - def test_exporting_a_telecom_address(self): - TestImportAddressAttributes().test_importing_a_telecom_address() - assert subject().export_address_attributes() == { - "Purpose": "USERDEFINED", - "Description": "Description", - "UserDefinedPurpose": "UserDefinedPurpose", - "TelephoneNumbers": ["Telephone", "Numbers"], - "FacsimileNumbers": ["Facsimile", "Numbers"], - "PagerNumber": "PagerNumber", - "ElectronicMailAddresses": ["Electronic", "Mail", "Addresses"], - "WWWHomePageURL": "WWWHomePageURL", - "MessagingIDs": ["Messaging", "IDs"], - } - - -class TestAddAddressAttribute(NewFile): - def test_run(self): - subject().add_address_attribute("AddressLines") - subject().add_address_attribute("TelephoneNumbers") - subject().add_address_attribute("FacsimileNumbers") - subject().add_address_attribute("ElectronicMailAddresses") - subject().add_address_attribute("MessagingIDs") - props = bpy.context.scene.BIMOwnerProperties - assert len(props.address_lines) == 1 - assert len(props.telephone_numbers) == 1 - assert len(props.facsimile_numbers) == 1 - assert len(props.electronic_mail_addresses) == 1 - assert len(props.messaging_ids) == 1 - - -class TestRemoveAddressAttribute(NewFile): - TestAddAddressAttribute().test_run() - subject().remove_address_attribute("AddressLines", 0) - subject().remove_address_attribute("TelephoneNumbers", 0) - subject().remove_address_attribute("FacsimileNumbers", 0) - subject().remove_address_attribute("ElectronicMailAddresses", 0) - subject().remove_address_attribute("MessagingIDs", 0) - props = bpy.context.scene.BIMOwnerProperties - assert len(props.address_lines) == 0 - assert len(props.telephone_numbers) == 0 - assert len(props.facsimile_numbers) == 0 - assert len(props.electronic_mail_addresses) == 0 - assert len(props.messaging_ids) == 0 - - -class TestSetOrganisation(NewFile): - def test_run(self): - organisation = ifcopenshell.file().createIfcOrganization() - subject().set_organisation(organisation) - assert bpy.context.scene.BIMOwnerProperties.active_organisation_id == organisation.id() - - class TestImportOrganisationAttributes(NewFile): def test_run(self): ifc = ifcopenshell.file() @@ -269,40 +425,6 @@ class TestImportOrganisationAttributes(NewFile): assert props.organisation_attributes.get("Description").string_value == "" -class TestClearOrganisation(NewFile): - def test_run(self): - props = bpy.context.scene.BIMOwnerProperties - props.active_organisation_id = 1 - subject().clear_organisation() - assert props.active_organisation_id == 0 - - -class TestExportOrganisationAttributes(NewFile): - def test_run(self): - TestImportOrganisationAttributes().test_run() - assert subject().export_organisation_attributes() == { - "Identification": "Identification", - "Name": "Name", - "Description": "Description", - } - - -class TestGetOrganisation(NewFile): - def test_run(self): - ifc = ifcopenshell.file() - tool.Ifc().set(ifc) - organisation = ifc.createIfcOrganization() - subject().set_organisation(organisation) - assert subject().get_organisation() == organisation - - -class TestSetPerson(NewFile): - def test_run(self): - person = ifcopenshell.file().createIfcPerson() - subject().set_person(person) - assert bpy.context.scene.BIMOwnerProperties.active_person_id == person.id() - - class TestImportPersonAttributes(NewFile): def test_run(self): ifc = ifcopenshell.file() @@ -346,86 +468,6 @@ class TestImportPersonAttributes(NewFile): assert props.person_attributes.get("GivenName").string_value == "" -class TestClearPerson(NewFile): - def test_run(self): - props = bpy.context.scene.BIMOwnerProperties - props.active_person_id = 1 - subject().clear_person() - assert props.active_person_id == 0 - - -class TestExportPersonAttributes(NewFile): - def test_run(self): - ifc = ifcopenshell.file() - tool.Ifc().set(ifc) - person = ifc.createIfcPerson() - person.Identification = "identification" - person.GivenName = "given_name" - person.FamilyName = "family_name" - person.MiddleNames = ("middle", "names") - person.PrefixTitles = ("prefix", "titles") - person.SuffixTitles = ("suffix", "titles") - subject().set_person(person) - subject().import_person_attributes() - assert subject().export_person_attributes() == { - "Identification": "identification", - "GivenName": "given_name", - "FamilyName": "family_name", - "MiddleNames": ["middle", "names"], - "PrefixTitles": ["prefix", "titles"], - "SuffixTitles": ["suffix", "titles"], - } - - def test_getting_empty_list_attributes_as_none(self): - ifc = ifcopenshell.file() - tool.Ifc().set(ifc) - result = subject().export_person_attributes() - assert result["MiddleNames"] is None - assert result["PrefixTitles"] is None - assert result["SuffixTitles"] is None - - -class TestGetPerson(NewFile): - def test_run(self): - ifc = ifcopenshell.file() - tool.Ifc().set(ifc) - person = ifc.createIfcPerson() - subject().set_person(person) - assert subject().get_person() == person - - -class TestAddPersonAttribute(NewFile): - def test_run(self): - subject().add_person_attribute("MiddleNames") - subject().add_person_attribute("PrefixTitles") - subject().add_person_attribute("SuffixTitles") - props = bpy.context.scene.BIMOwnerProperties - assert len(props.middle_names) == 1 - assert len(props.prefix_titles) == 1 - assert len(props.suffix_titles) == 1 - - -class TestRemovePersonAttribute(NewFile): - def test_run(self): - subject().add_person_attribute("MiddleNames") - subject().remove_person_attribute("MiddleNames", 0) - subject().add_person_attribute("PrefixTitles") - subject().remove_person_attribute("PrefixTitles", 0) - subject().add_person_attribute("SuffixTitles") - subject().remove_person_attribute("SuffixTitles", 0) - props = bpy.context.scene.BIMOwnerProperties - assert len(props.middle_names) == 0 - assert len(props.prefix_titles) == 0 - assert len(props.suffix_titles) == 0 - - -class TestSetRole(NewFile): - def test_run(self): - role = ifcopenshell.file().createIfcActorRole() - subject().set_role(role) - assert bpy.context.scene.BIMOwnerProperties.active_role_id == role.id() - - class TestImportRoleAttributes(NewFile): def test_run(self): ifc = ifcopenshell.file() @@ -454,35 +496,76 @@ class TestImportRoleAttributes(NewFile): assert props.role_attributes.get("Role").enum_value == "ARCHITECT" -class TestClearRole(NewFile): +class TestRemoveAddressAttribute(NewFile): + TestAddAddressAttribute().test_run() + subject().remove_address_attribute("AddressLines", 0) + subject().remove_address_attribute("TelephoneNumbers", 0) + subject().remove_address_attribute("FacsimileNumbers", 0) + subject().remove_address_attribute("ElectronicMailAddresses", 0) + subject().remove_address_attribute("MessagingIDs", 0) + props = bpy.context.scene.BIMOwnerProperties + assert len(props.address_lines) == 0 + assert len(props.telephone_numbers) == 0 + assert len(props.facsimile_numbers) == 0 + assert len(props.electronic_mail_addresses) == 0 + assert len(props.messaging_ids) == 0 + + +class TestRemovePersonAttribute(NewFile): + def test_run(self): + subject().add_person_attribute("MiddleNames") + subject().remove_person_attribute("MiddleNames", 0) + subject().add_person_attribute("PrefixTitles") + subject().remove_person_attribute("PrefixTitles", 0) + subject().add_person_attribute("SuffixTitles") + subject().remove_person_attribute("SuffixTitles", 0) + props = bpy.context.scene.BIMOwnerProperties + assert len(props.middle_names) == 0 + assert len(props.prefix_titles) == 0 + assert len(props.suffix_titles) == 0 + + +class TestSetActor(NewFile): + def test_run(self): + ifc = ifcopenshell.file() + actor = ifc.createIfcActor() + subject().set_actor(actor) + assert bpy.context.scene.BIMOwnerProperties.active_actor_id == actor.id() + + +class TestSetAddress(NewFile): + def test_run(self): + ifc = ifcopenshell.file() + address = ifc.createIfcPostalAddress() + subject().set_address(address) + assert bpy.context.scene.BIMOwnerProperties.active_address_id == address.id() + + +class TestSetOrganisation(NewFile): + def test_run(self): + organisation = ifcopenshell.file().createIfcOrganization() + subject().set_organisation(organisation) + assert bpy.context.scene.BIMOwnerProperties.active_organisation_id == organisation.id() + + +class TestSetPerson(NewFile): + def test_run(self): + person = ifcopenshell.file().createIfcPerson() + subject().set_person(person) + assert bpy.context.scene.BIMOwnerProperties.active_person_id == person.id() + + +class TestSetRole(NewFile): def test_run(self): role = ifcopenshell.file().createIfcActorRole() subject().set_role(role) - subject().clear_role() - assert bpy.context.scene.BIMOwnerProperties.active_role_id == 0 + assert bpy.context.scene.BIMOwnerProperties.active_role_id == role.id() -class TestGetRole(NewFile): +class TestSetUser(NewFile): def test_run(self): ifc = ifcopenshell.file() - tool.Ifc().set(ifc) - role = ifc.createIfcActorRole() - subject().set_role(role) - assert subject().get_role() == role - - -class TestExportRoleAttributes(NewFile): - def test_run(self): - ifc = ifcopenshell.file() - tool.Ifc().set(ifc) - role = ifc.createIfcActorRole() - role.Role = "USERDEFINED" - role.UserDefinedRole = "UserDefinedRole" - role.Description = "Description" - subject().set_role(role) - subject().import_role_attributes() - assert subject().export_role_attributes() == { - "Role": "USERDEFINED", - "UserDefinedRole": "UserDefinedRole", - "Description": "Description", - } + tool.Ifc.set(ifc) + user = ifc.createIfcPersonAndOrganization() + subject.set_user(user) + assert bpy.context.scene.BIMOwnerProperties.active_user_id == user.id()