You can now manage IFC actors in Blender.

This commit is contained in:
Dion Moult
2022-02-04 18:21:53 +11:00
parent 60ea856e51
commit 6ce8a3621a
11 changed files with 615 additions and 244 deletions
@@ -20,6 +20,7 @@ import bpy
from . import ui, prop, operator from . import ui, prop, operator
classes = ( classes = (
operator.AddActor,
operator.AddAddress, operator.AddAddress,
operator.AddAddressAttribute, operator.AddAddressAttribute,
operator.AddOrganisation, operator.AddOrganisation,
@@ -28,18 +29,22 @@ classes = (
operator.AddPersonAttribute, operator.AddPersonAttribute,
operator.AddRole, operator.AddRole,
operator.ClearUser, operator.ClearUser,
operator.DisableEditingActor,
operator.DisableEditingAddress, operator.DisableEditingAddress,
operator.DisableEditingOrganisation, operator.DisableEditingOrganisation,
operator.DisableEditingPerson, operator.DisableEditingPerson,
operator.DisableEditingRole, operator.DisableEditingRole,
operator.EditActor,
operator.EditAddress, operator.EditAddress,
operator.EditOrganisation, operator.EditOrganisation,
operator.EditPerson, operator.EditPerson,
operator.EditRole, operator.EditRole,
operator.EnableEditingActor,
operator.EnableEditingAddress, operator.EnableEditingAddress,
operator.EnableEditingOrganisation, operator.EnableEditingOrganisation,
operator.EnableEditingPerson, operator.EnableEditingPerson,
operator.EnableEditingRole, operator.EnableEditingRole,
operator.RemoveActor,
operator.RemoveAddress, operator.RemoveAddress,
operator.RemoveAddressAttribute, operator.RemoveAddressAttribute,
operator.RemoveOrganisation, operator.RemoveOrganisation,
@@ -52,6 +57,7 @@ classes = (
ui.BIM_PT_people, ui.BIM_PT_people,
ui.BIM_PT_organisations, ui.BIM_PT_organisations,
ui.BIM_PT_owner, ui.BIM_PT_owner,
ui.BIM_PT_actor,
) )
@@ -24,6 +24,7 @@ def refresh():
PeopleData.is_loaded = False PeopleData.is_loaded = False
OrganisationsData.is_loaded = False OrganisationsData.is_loaded = False
OwnerData.is_loaded = False OwnerData.is_loaded = False
ActorData.is_loaded = False
class RolesAddressesData: class RolesAddressesData:
@@ -202,3 +203,30 @@ class OwnerData:
} }
) )
return results 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
@@ -306,3 +306,52 @@ class ClearUser(bpy.types.Operator, Operator):
def _execute(self, context): def _execute(self, context):
core.clear_user(tool.Owner) 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))
@@ -18,7 +18,7 @@
import bpy import bpy
from blenderbim.bim.prop import StrProperty, Attribute 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.types import PropertyGroup
from bpy.props import ( from bpy.props import (
PointerProperty, PointerProperty,
@@ -44,6 +44,20 @@ def get_user_organisation(self, context):
return OwnerData.data["user_organisation"] 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): class BIMOwnerProperties(PropertyGroup):
active_person_id: IntProperty(name="Active Person Id") active_person_id: IntProperty(name="Active Person Id")
person_attributes: CollectionProperty(name="Person Attributes", type=Attribute) 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_person: EnumProperty(items=get_user_person, name="Person")
user_organisation: EnumProperty(items=get_user_organisation, name="Organisation") user_organisation: EnumProperty(items=get_user_organisation, name="Organisation")
active_user_id: IntProperty(name="Active User Id") 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")
@@ -19,7 +19,7 @@
import bpy import bpy
import blenderbim.bim.helper import blenderbim.bim.helper
import blenderbim.tool as tool 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): 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"] row.operator("bim.set_user", icon="KEYFRAME_HLT", text="").user = user["id"]
op = row.operator("bim.remove_person_and_organisation", icon="X", text="") op = row.operator("bim.remove_person_and_organisation", icon="X", text="")
op.person_and_organisation = user["id"] 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"]
+22
View File
@@ -143,3 +143,25 @@ def get_user(owner):
def clear_user(owner): def clear_user(owner):
owner.clear_user() 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)
+5
View File
@@ -271,26 +271,31 @@ class Patch:
class Owner: class Owner:
def add_address_attribute(cls, name): pass def add_address_attribute(cls, name): pass
def add_person_attribute(cls, name): pass def add_person_attribute(cls, name): pass
def clear_actor(cls): pass
def clear_address(cls): pass def clear_address(cls): pass
def clear_organisation(cls): pass def clear_organisation(cls): pass
def clear_person(cls): pass def clear_person(cls): pass
def clear_role(cls): pass def clear_role(cls): pass
def clear_user(cls): pass def clear_user(cls): pass
def export_actor_attributes(cls): pass
def export_address_attributes(cls): pass def export_address_attributes(cls): pass
def export_organisation_attributes(cls): pass def export_organisation_attributes(cls): pass
def export_person_attributes(cls): pass def export_person_attributes(cls): pass
def export_role_attributes(cls): pass def export_role_attributes(cls): pass
def get_actor(cls): pass
def get_address(cls): pass def get_address(cls): pass
def get_organisation(cls): pass def get_organisation(cls): pass
def get_person(cls): pass def get_person(cls): pass
def get_role(cls): pass def get_role(cls): pass
def get_user(cls): pass def get_user(cls): pass
def import_actor_attributes(cls, actor): pass
def import_address_attributes(cls): pass def import_address_attributes(cls): pass
def import_organisation_attributes(cls): pass def import_organisation_attributes(cls): pass
def import_person_attributes(cls): pass def import_person_attributes(cls): pass
def import_role_attributes(cls): pass def import_role_attributes(cls): pass
def remove_address_attribute(cls, name, id): pass def remove_address_attribute(cls, name, id): pass
def remove_person_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_address(cls, address): pass
def set_organisation(cls, organisation): pass def set_organisation(cls, organisation): pass
def set_person(cls, person): pass def set_person(cls, person): pass
+24
View File
@@ -234,3 +234,27 @@ class Owner(blenderbim.core.tool.Owner):
@classmethod @classmethod
def export_role_attributes(cls): def export_role_attributes(cls):
return blenderbim.bim.helper.export_attributes(bpy.context.scene.BIMOwnerProperties.role_attributes) 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)
@@ -237,3 +237,43 @@ Scenario: Clear user
Given an empty IFC project Given an empty IFC project
When I press "bim.clear_user(user={user})" When I press "bim.clear_user(user={user})"
Then nothing happens 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"
+34
View File
@@ -225,3 +225,37 @@ class TestClearUser:
def test_run(self, owner): def test_run(self, owner):
owner.clear_user().should_be_called() owner.clear_user().should_be_called()
subject.clear_user(owner) 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)
+325 -242
View File
@@ -29,13 +29,234 @@ class TestImplementsTool(NewFile):
assert isinstance(subject(), blenderbim.core.tool.Owner) 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): def test_run(self):
ifc = ifcopenshell.file() ifc = ifcopenshell.file()
tool.Ifc.set(ifc) actor = ifc.createIfcActor()
user = ifc.createIfcPersonAndOrganization() subject().set_actor(actor)
subject.set_user(user) subject().clear_actor()
assert bpy.context.scene.BIMOwnerProperties.active_user_id == user.id() 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): class TestGetUser(NewFile):
@@ -56,19 +277,40 @@ class TestGetUser(NewFile):
assert subject.get_user() == user2 assert subject.get_user() == user2
class TestClearUser(NewFile): class TestImportActorAttributes(NewFile):
def test_run(self): def test_importing_an_actor(self):
TestSetUser().test_run()
subject.clear_user()
assert bpy.context.scene.BIMOwnerProperties.active_user_id == 0
class TestSetAddress(NewFile):
def test_run(self):
ifc = ifcopenshell.file() ifc = ifcopenshell.file()
address = ifc.createIfcPostalAddress() tool.Ifc().set(ifc)
subject().set_address(address) actor = ifc.createIfcActor()
assert bpy.context.scene.BIMOwnerProperties.active_address_id == address.id() 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): class TestImportAddressAttributes(NewFile):
@@ -152,92 +394,6 @@ class TestImportAddressAttributes(NewFile):
assert len(props.messaging_ids) == 0 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): class TestImportOrganisationAttributes(NewFile):
def test_run(self): def test_run(self):
ifc = ifcopenshell.file() ifc = ifcopenshell.file()
@@ -269,40 +425,6 @@ class TestImportOrganisationAttributes(NewFile):
assert props.organisation_attributes.get("Description").string_value == "" 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): class TestImportPersonAttributes(NewFile):
def test_run(self): def test_run(self):
ifc = ifcopenshell.file() ifc = ifcopenshell.file()
@@ -346,86 +468,6 @@ class TestImportPersonAttributes(NewFile):
assert props.person_attributes.get("GivenName").string_value == "" 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): class TestImportRoleAttributes(NewFile):
def test_run(self): def test_run(self):
ifc = ifcopenshell.file() ifc = ifcopenshell.file()
@@ -454,35 +496,76 @@ class TestImportRoleAttributes(NewFile):
assert props.role_attributes.get("Role").enum_value == "ARCHITECT" 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): def test_run(self):
role = ifcopenshell.file().createIfcActorRole() role = ifcopenshell.file().createIfcActorRole()
subject().set_role(role) subject().set_role(role)
subject().clear_role() assert bpy.context.scene.BIMOwnerProperties.active_role_id == role.id()
assert bpy.context.scene.BIMOwnerProperties.active_role_id == 0
class TestGetRole(NewFile): class TestSetUser(NewFile):
def test_run(self): def test_run(self):
ifc = ifcopenshell.file() ifc = ifcopenshell.file()
tool.Ifc().set(ifc) tool.Ifc.set(ifc)
role = ifc.createIfcActorRole() user = ifc.createIfcPersonAndOrganization()
subject().set_role(role) subject.set_user(user)
assert subject().get_role() == role assert bpy.context.scene.BIMOwnerProperties.active_user_id == user.id()
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",
}