WIP implement organisation editing. Also new features see commit message. See #1222.

* Organisations are now imported.
 * Organisation identification attribute support is now added, which I missed before
This commit is contained in:
Dion Moult
2021-01-09 11:42:21 +11:00
parent 84de1f1b09
commit 06e1ee7825
11 changed files with 271 additions and 315 deletions
@@ -7,6 +7,11 @@ classes = (
operator.AddPerson,
operator.EditPerson,
operator.RemovePerson,
operator.EnableEditingOrganisation,
operator.DisableEditingOrganisation,
operator.AddOrganisation,
operator.EditOrganisation,
operator.RemoveOrganisation,
operator.EnableEditingRole,
operator.DisableEditingRole,
operator.AddRole,
@@ -18,6 +23,7 @@ classes = (
operator.EditAddress,
operator.RemoveAddress,
ui.BIM_PT_people,
ui.BIM_PT_organisations,
)
@@ -0,0 +1,6 @@
class Usecase:
def __init__(self, file):
self.file = file
def execute(self):
self.file.createIfcOrganization("APTR", "Apeture Science")
@@ -4,6 +4,7 @@ from blenderbim.bim.ifc import IfcStore
class Data:
is_loaded = False
people = {}
organisations = {}
addresses = {}
roles = {}
@@ -15,6 +16,8 @@ class Data:
cls.people = {}
for person in file.by_type("IfcPerson"):
data = person.get_info()
data["is_engaged"] = bool(person.EngagedIn)
cls.people[person.id()] = data
roles = []
if data["Roles"]:
@@ -28,9 +31,24 @@ class Data:
addresses.append(address.id())
data["Addresses"] = addresses
data["is_engaged"] = bool(person.EngagedIn)
for organisation in file.by_type("IfcOrganization"):
data = organisation.get_info()
data["is_engaged"] = (
bool(organisation.IsRelatedBy) or bool(organisation.Relates) or bool(organisation.Engages)
)
cls.organisations[organisation.id()] = data
cls.people[person.id()] = data
roles = []
if data["Roles"]:
for role in data["Roles"]:
roles.append(role.id())
data["Roles"] = roles
addresses = []
if data["Addresses"]:
for address in data["Addresses"]:
addresses.append(address.id())
data["Addresses"] = addresses
for address in file.by_type("IfcAddress"):
cls.addresses[address.id()] = address.get_info()
@@ -0,0 +1,13 @@
class Usecase:
def __init__(self, file, settings=None):
self.file = file
self.settings = {
"organisation": None,
"attributes": {}
}
for key, value in settings.items():
self.settings[key] = value
def execute(self):
for name, value in self.settings["attributes"].items():
setattr(self.settings["organisation"], name, value)
@@ -3,6 +3,9 @@ import json
import blenderbim.bim.module.owner.add_person as add_person
import blenderbim.bim.module.owner.edit_person as edit_person
import blenderbim.bim.module.owner.remove_person as remove_person
import blenderbim.bim.module.owner.add_organisation as add_organisation
import blenderbim.bim.module.owner.edit_organisation as edit_organisation
import blenderbim.bim.module.owner.remove_organisation as remove_organisation
import blenderbim.bim.module.owner.add_role as add_role
import blenderbim.bim.module.owner.edit_role as edit_role
import blenderbim.bim.module.owner.remove_role as remove_role
@@ -279,3 +282,74 @@ class RemoveAddress(bpy.types.Operator):
remove_address.Usecase(self.file, {"address": self.file.by_id(self.address_id)}).execute()
Data.load()
return {"FINISHED"}
class EnableEditingOrganisation(bpy.types.Operator):
bl_idname = "bim.enable_editing_organisation"
bl_label = "Enable Editing Organisation"
organisation_id: bpy.props.IntProperty()
def execute(self, context):
self.file = IfcStore.get_file()
props = context.scene.BIMProperties
props.active_organisation_id = self.organisation_id
data = Data.organisations[self.organisation_id]
identification = data["Id"] if self.file.schema == "IFC2X3" else data["Identification"]
props.organisation.identification = identification or ""
props.organisation.name = data["Name"]
props.organisation.description = data["Description"] or ""
return {"FINISHED"}
class DisableEditingOrganisation(bpy.types.Operator):
bl_idname = "bim.disable_editing_organisation"
bl_label = "Disable Editing Organisation"
def execute(self, context):
context.scene.BIMProperties.active_organisation_id = 0
return {"FINISHED"}
class AddOrganisation(bpy.types.Operator):
bl_idname = "bim.add_organisation"
bl_label = "Add Organisation"
def execute(self, context):
add_organisation.Usecase(IfcStore.get_file()).execute()
Data.load()
return {"FINISHED"}
class EditOrganisation(bpy.types.Operator):
bl_idname = "bim.edit_organisation"
bl_label = "Edit Organisation"
def execute(self, context):
self.file = IfcStore.get_file()
props = context.scene.BIMProperties
attributes = {
"Identification": props.organisation.identification or None,
"Name": props.organisation.name,
"Description": props.organisation.description or None,
}
if self.file.schema == "IFC2X3":
attributes["Id"] = attributes["Identification"]
del attributes["Identification"]
edit_organisation.Usecase(
self.file, {"organisation": self.file.by_id(props.active_organisation_id), "attributes": attributes}
).execute()
Data.load()
bpy.ops.bim.disable_editing_organisation()
return {"FINISHED"}
class RemoveOrganisation(bpy.types.Operator):
bl_idname = "bim.remove_organisation"
bl_label = "Remove Organisation"
organisation_id: bpy.props.IntProperty()
def execute(self, context):
self.file = IfcStore.get_file()
remove_organisation.Usecase(self.file, {"organisation": self.file.by_id(self.organisation_id)}).execute()
Data.load()
return {"FINISHED"}
@@ -0,0 +1,9 @@
class Usecase:
def __init__(self, file, settings=None):
self.file = file
self.settings = {"organisation": None}
for key, value in settings.items():
self.settings[key] = value
def execute(self):
self.file.remove(self.settings["organisation"])
@@ -1,8 +1,97 @@
import bpy
from bpy.types import Panel
from blenderbim.bim.module.owner.data import Data
from blenderbim.bim.ifc import IfcStore
def draw_roles_ui(box, assigned_object_id, roles):
props = bpy.context.scene.BIMProperties
row = box.row(align=True)
row.label(text="Roles")
row.operator("bim.add_role", icon="ADD", text="").assigned_object_id = assigned_object_id
for role_id in roles:
role = Data.roles[role_id]
if props.active_role_id == role_id:
blender_role = props.role
box2 = box.box()
row = box2.row(align=True)
row.prop(blender_role, "name", icon="MOD_CLOTH", text="")
row.operator("bim.edit_role", icon="CHECKMARK", text="")
row.operator("bim.disable_editing_role", icon="X", text="")
if blender_role.name == "USERDEFINED":
row = box2.row()
row.prop(blender_role, "user_defined_role")
row = box2.row()
row.prop(blender_role, "description")
else:
row = box.row(align=True)
row.label(text=role["UserDefinedRole"] or role["Role"])
row.operator("bim.enable_editing_role", icon="GREASEPENCIL", text="").role_id = role_id
row.operator("bim.remove_role", icon="X", text="").role_id = role_id
def draw_addresses_ui(box, assigned_object_id, addresses, file):
props = bpy.context.scene.BIMProperties
row = box.row(align=True)
row.label(text="Addresses")
op = row.operator("bim.add_address", icon="LINK_BLEND", text="")
op.assigned_object_id = assigned_object_id
op.ifc_class = "IfcTelecomAddress"
op = row.operator("bim.add_address", icon="APPEND_BLEND", text="")
op.assigned_object_id = assigned_object_id
op.ifc_class = "IfcPostalAddress"
for address_id in addresses:
address = Data.addresses[address_id]
if props.active_address_id == address_id:
blender_address = props.address
box2 = box.box()
row = box2.row(align=True)
row.prop(blender_address, "purpose", icon="MOD_CLOTH", text="")
row.operator("bim.edit_address", icon="CHECKMARK", text="")
row.operator("bim.disable_editing_address", icon="X", text="")
if blender_address.purpose == "USERDEFINED":
row = box2.row()
row.prop(blender_address, "user_defined_purpose")
row = box2.row()
row.prop(blender_address, "description")
if address["type"] == "IfcTelecomAddress":
row = box2.row()
row.prop(blender_address, "telephone_numbers")
row = box2.row()
row.prop(blender_address, "facsimile_numbers")
row = box2.row()
row.prop(blender_address, "pager_number")
row = box2.row()
row.prop(blender_address, "electronic_mail_addresses")
row = box2.row()
row.prop(blender_address, "www_home_page_url")
if file.schema != "IFC2X3":
row = box2.row()
row.prop(blender_address, "messaging_ids")
elif address["type"] == "IfcPostalAddress":
row = box2.row()
row.prop(blender_address, "internal_location")
row = box2.row()
row.prop(blender_address, "address_lines")
row = box2.row()
row.prop(blender_address, "postal_box")
row = box2.row()
row.prop(blender_address, "town")
row = box2.row()
row.prop(blender_address, "region")
row = box2.row()
row.prop(blender_address, "postal_code")
row = box2.row()
row.prop(blender_address, "country")
else:
row = box.row(align=True)
row.label(text=address["type"])
row.operator("bim.enable_editing_address", icon="GREASEPENCIL", text="").address_id = address_id
row.operator("bim.remove_address", icon="X", text="").address_id = address_id
class BIM_PT_people(Panel):
bl_label = "IFC People"
bl_idname = "BIM_PT_people"
@@ -24,7 +113,7 @@ class BIM_PT_people(Panel):
props = context.scene.BIMProperties
row = self.layout.row()
row.operator("bim.add_person")
row.operator("bim.add_person", icon="ADD")
for person_id, person in Data.people.items():
if props.active_person_id == person_id:
@@ -45,87 +134,8 @@ class BIM_PT_people(Panel):
row = box.row()
row.prop(blender_person, "suffix_titles")
row = box.row(align=True)
row.label(text="Roles")
row.operator("bim.add_role", icon="ADD", text="").assigned_object_id = person_id
for role_id in person["Roles"]:
role = Data.roles[role_id]
if props.active_role_id == role_id:
blender_role = props.role
box2 = box.box()
row = box2.row(align=True)
row.prop(blender_role, "name", icon="MOD_CLOTH", text="")
row.operator("bim.edit_role", icon="CHECKMARK", text="")
row.operator("bim.disable_editing_role", icon="X", text="")
if blender_role.name == "USERDEFINED":
row = box2.row()
row.prop(blender_role, "user_defined_role")
row = box2.row()
row.prop(blender_role, "description")
else:
row = box.row(align=True)
row.label(text=role["UserDefinedRole"] or role["Role"])
row.operator("bim.enable_editing_role", icon="GREASEPENCIL", text="").role_id = role_id
row.operator("bim.remove_role", icon="X", text="").role_id = role_id
row = box.row(align=True)
row.label(text="Addresses")
op = row.operator("bim.add_address", icon="LINK_BLEND", text="")
op.assigned_object_id = person_id
op.ifc_class = "IfcTelecomAddress"
op = row.operator("bim.add_address", icon="APPEND_BLEND", text="")
op.assigned_object_id = person_id
op.ifc_class = "IfcPostalAddress"
for address_id in person["Addresses"]:
address = Data.addresses[address_id]
if props.active_address_id == address_id:
blender_address = props.address
box2 = box.box()
row = box2.row(align=True)
row.prop(blender_address, "purpose", icon="MOD_CLOTH", text="")
row.operator("bim.edit_address", icon="CHECKMARK", text="")
row.operator("bim.disable_editing_address", icon="X", text="")
if blender_address.purpose == "USERDEFINED":
row = box2.row()
row.prop(blender_address, "user_defined_purpose")
row = box2.row()
row.prop(blender_address, "description")
if address["type"] == "IfcTelecomAddress":
row = box2.row()
row.prop(blender_address, "telephone_numbers")
row = box2.row()
row.prop(blender_address, "facsimile_numbers")
row = box2.row()
row.prop(blender_address, "pager_number")
row = box2.row()
row.prop(blender_address, "electronic_mail_addresses")
row = box2.row()
row.prop(blender_address, "www_home_page_url")
if self.file.schema != "IFC2X3":
row = box2.row()
row.prop(blender_address, "messaging_ids")
elif address["type"] == "IfcPostalAddress":
row = box2.row()
row.prop(blender_address, "internal_location")
row = box2.row()
row.prop(blender_address, "address_lines")
row = box2.row()
row.prop(blender_address, "postal_box")
row = box2.row()
row.prop(blender_address, "town")
row = box2.row()
row.prop(blender_address, "region")
row = box2.row()
row.prop(blender_address, "postal_code")
row = box2.row()
row.prop(blender_address, "country")
else:
row = box.row(align=True)
row.label(text=address["type"])
row.operator("bim.enable_editing_address", icon="GREASEPENCIL", text="").address_id = address_id
row.operator("bim.remove_address", icon="X", text="").address_id = address_id
draw_roles_ui(box, person_id, person["Roles"])
draw_addresses_ui(box, person_id, person["Addresses"], self.file)
else:
row = self.layout.row(align=True)
name = person["Id"] if self.file.schema == "IFC2X3" else person["Identification"]
@@ -139,3 +149,51 @@ class BIM_PT_people(Panel):
row.operator("bim.enable_editing_person", icon="GREASEPENCIL", text="").person_id = person_id
if not person["is_engaged"]:
row.operator("bim.remove_person", icon="X", text="").person_id = person_id
class BIM_PT_organisations(Panel):
bl_label = "IFC Organisations"
bl_idname = "BIM_PT_organisations"
bl_options = {"DEFAULT_CLOSED"}
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
@classmethod
def poll(cls, context):
return IfcStore.get_file()
def draw(self, context):
if not Data.is_loaded:
Data.load()
self.file = IfcStore.get_file()
self.layout.use_property_split = True
props = context.scene.BIMProperties
row = self.layout.row()
row.operator("bim.add_organisation", icon="ADD")
for organisation_id, organisation in Data.organisations.items():
if props.active_organisation_id == organisation_id:
blender_organisation = props.organisation
box = self.layout.box()
row = box.row(align=True)
row.prop(blender_organisation, "name", icon="USER", text="")
row.operator("bim.edit_organisation", icon="CHECKMARK", text="")
row.operator("bim.disable_editing_organisation", icon="X", text="")
row = box.row()
row.prop(blender_organisation, "identification")
row = box.row()
row.prop(blender_organisation, "description")
draw_roles_ui(box, organisation_id, organisation["Roles"])
draw_addresses_ui(box, organisation_id, organisation["Addresses"], self.file)
else:
row = self.layout.row(align=True)
row.label(text=organisation["Name"])
if organisation["Roles"]:
row.label(text=", ".join([Data.roles[r]["Role"] for r in organisation["Roles"]]))
row.operator("bim.enable_editing_organisation", icon="GREASEPENCIL", text="").organisation_id = organisation_id
if not organisation["is_engaged"]:
row.operator("bim.remove_organisation", icon="X", text="").organisation_id = organisation_id