WIP partial port of IfcPerson to partial editing. New feature too! See message. See #1222.

* Previously, IfcPerson was not imported. Now it is! Funky.
This commit is contained in:
Dion Moult
2021-01-08 16:27:19 +11:00
parent 53de93e582
commit be2ea335f5
14 changed files with 249 additions and 69 deletions
@@ -14,6 +14,7 @@ if bpy is not None:
import blenderbim.bim.module.debug as module_debug
import blenderbim.bim.module.geometry as module_geometry
import blenderbim.bim.module.model as module_model
import blenderbim.bim.module.person as module_person
import blenderbim.bim.module.project as module_project
import blenderbim.bim.module.pset as module_pset
import blenderbim.bim.module.spatial as module_spatial
@@ -71,8 +72,6 @@ if bpy is not None:
operator.AssignConstraint,
operator.UnassignConstraint,
operator.RemoveObjectConstraint,
operator.AddPerson,
operator.RemovePerson,
operator.AddPersonRole,
operator.RemovePersonRole,
operator.AddPersonAddress,
@@ -265,7 +264,6 @@ if bpy is not None:
ui.BIM_PT_ifccsv,
ui.BIM_PT_ifcclash,
ui.BIM_PT_owner,
ui.BIM_PT_people,
ui.BIM_PT_organisations,
ui.BIM_PT_qa,
ui.BIM_PT_library,
@@ -311,6 +309,7 @@ if bpy is not None:
classes.extend(module_debug.classes)
classes.extend(module_geometry.classes)
classes.extend(module_model.classes)
classes.extend(module_person.classes)
classes.extend(module_project.classes)
classes.extend(module_pset.classes)
classes.extend(module_spatial.classes)
@@ -356,6 +355,7 @@ if bpy is not None:
module_debug.register()
module_geometry.register()
module_model.register()
module_person.register()
module_project.register()
module_pset.register()
module_spatial.register()
@@ -388,6 +388,7 @@ if bpy is not None:
module_spatial.unregister()
module_pset.unregister()
module_project.unregister()
module_person.unregister()
module_model.unregister()
module_geometry.unregister()
module_debug.unregister()
@@ -1,5 +1,6 @@
from bpy.types import Panel
from blenderbim.bim.module.context.data import Data
from blenderbim.bim.ifc import IfcStore
class BIM_PT_context(Panel):
@@ -10,14 +11,17 @@ class BIM_PT_context(Panel):
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()
layout = self.layout
props = context.scene.BIMProperties
row = layout.row(align=True)
row = self.layout.row(align=True)
row.prop(props, "available_contexts", text="")
row.prop(props, "available_subcontexts", text="")
row.prop(props, "available_target_views", text="")
@@ -0,0 +1,19 @@
import bpy
from . import ui, operator
classes = (
operator.EnableEditingPerson,
operator.DisableEditingPerson,
operator.AddPerson,
operator.EditPerson,
operator.RemovePerson,
ui.BIM_PT_people,
)
def register():
pass
def unregister():
pass
@@ -0,0 +1,6 @@
class Usecase:
def __init__(self, file):
self.file = file
def execute(self):
self.file.createIfcPerson("HSeldon", "Seldon", "Hari")
@@ -0,0 +1,32 @@
from blenderbim.bim.ifc import IfcStore
class Data:
is_loaded = False
people = {}
@classmethod
def load(cls):
file = IfcStore.get_file()
if not file:
return
cls.people = {}
for person in file.by_type("IfcPerson"):
data = person.get_info()
roles = {}
if data["Roles"]:
for role in data["Roles"]:
roles[role.id()] = role.get_info()
data["Roles"] = roles
addresses = []
if data["Addresses"]:
for address in data["Addresses"]:
addresses.append(address.get_info())
data["Addresses"] = addresses
data["is_engaged"] = bool(person.EngagedIn)
cls.people[person.id()] = data
cls.is_loaded = True
@@ -0,0 +1,13 @@
class Usecase:
def __init__(self, file, settings=None):
self.file = file
self.settings = {
"person": 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["person"], name, value)
@@ -0,0 +1,84 @@
import bpy
import json
import blenderbim.bim.module.person.add_person as add_person
import blenderbim.bim.module.person.edit_person as edit_person
import blenderbim.bim.module.person.remove_person as remove_person
from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.module.person.data import Data
class EnableEditingPerson(bpy.types.Operator):
bl_idname = "bim.enable_editing_person"
bl_label = "Enable Editing Person"
person_id: bpy.props.IntProperty()
def execute(self, context):
self.file = IfcStore.get_file()
props = context.scene.BIMProperties
props.active_person_id = self.person_id
data = Data.people[self.person_id]
name = data["Id"] if self.file.schema == "IFC2X3" else data["Identification"]
props.person.name = name or ""
props.person.family_name = data["FamilyName"] or ""
props.person.given_name = data["GivenName"] or ""
props.person.middle_names = json.dumps(data["MiddleNames"]) if data["MiddleNames"] else ""
props.person.prefix_titles = json.dumps(data["PrefixTitles"]) if data["PrefixTitles"] else ""
props.person.suffix_titles = json.dumps(data["SuffixTitles"]) if data["SuffixTitles"] else ""
return {"FINISHED"}
class DisableEditingPerson(bpy.types.Operator):
bl_idname = "bim.disable_editing_person"
bl_label = "Disable Editing Person"
def execute(self, context):
context.scene.BIMProperties.active_person_id = 0
return {"FINISHED"}
class AddPerson(bpy.types.Operator):
bl_idname = "bim.add_person"
bl_label = "Add Person"
def execute(self, context):
add_person.Usecase(IfcStore.get_file()).execute()
Data.load()
return {"FINISHED"}
class EditPerson(bpy.types.Operator):
bl_idname = "bim.edit_person"
bl_label = "Edit Person"
def execute(self, context):
self.file = IfcStore.get_file()
props = context.scene.BIMProperties
attributes = {
"Identification": props.person.name or None,
"FamilyName": props.person.family_name or None,
"GivenName": props.person.given_name or None,
"MiddleNames": json.loads(props.person.middle_names) if props.person.middle_names else None,
"PrefixTitles": json.loads(props.person.prefix_titles) if props.person.prefix_titles else None,
"SuffixTitles": json.loads(props.person.suffix_titles) if props.person.suffix_titles else None,
}
if self.file.schema == "IFC2X3":
attributes["Id"] = attributes["Identification"]
del attributes["Identification"]
edit_person.Usecase(
self.file, {"person": self.file.by_id(props.active_person_id), "attributes": attributes}
).execute()
Data.load()
bpy.ops.bim.disable_editing_person()
return {"FINISHED"}
class RemovePerson(bpy.types.Operator):
bl_idname = "bim.remove_person"
bl_label = "Remove Person"
person_id: bpy.props.IntProperty()
def execute(self, context):
self.file = IfcStore.get_file()
remove_person.Usecase(self.file, {"person": self.file.by_id(self.person_id)}).execute()
Data.load()
return {"FINISHED"}
@@ -0,0 +1,9 @@
class Usecase:
def __init__(self, file, settings=None):
self.file = file
self.settings = {"person": None}
for key, value in settings.items():
self.settings[key] = value
def execute(self):
self.file.remove(self.settings["person"])
@@ -0,0 +1,69 @@
from bpy.types import Panel
from blenderbim.bim.module.person.data import Data
from blenderbim.bim.ifc import IfcStore
class BIM_PT_people(Panel):
bl_label = "IFC People"
bl_idname = "BIM_PT_people"
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_person")
for person_id, person in Data.people.items():
if props.active_person_id == person_id:
blender_person = props.person
box = self.layout.box()
row = box.row(align=True)
row.prop(blender_person, "name", icon="USER", text="")
row.operator("bim.edit_person", icon="CHECKMARK", text="")
row.operator("bim.disable_editing_person", icon="X", text="")
row = box.row()
row.prop(blender_person, "family_name")
row = box.row()
row.prop(blender_person, "given_name")
row = box.row()
row.prop(blender_person, "middle_names")
row = box.row()
row.prop(blender_person, "prefix_titles")
row = box.row()
row.prop(blender_person, "suffix_titles")
else:
row = self.layout.row(align=True)
name = person["Id"] if self.file.schema == "IFC2X3" else person["Identification"]
name = name or "*"
if person["GivenName"] or person["FamilyName"]:
full_name = "{} {}".format(person["GivenName"] or "", person["FamilyName"] or "").strip()
name += f" ({full_name})"
row.label(text=name)
if person["Roles"]:
row.label(text=", ".join([r.Role for r in person["Roles"]]))
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
return
if props.people:
if props.active_person_index < len(props.people):
self.layout.label(text="Roles:")
draw_roles_ui(self.layout, person, "person")
self.layout.label(text="Addresses:")
draw_addresses_ui(self.layout, person, "person")
@@ -86,6 +86,10 @@ class AssignClass(bpy.types.Operator):
elif self.predefined_type == "":
predefined_type = None
for obj in objects:
if obj.data:
for material in obj.data.materials:
if not material.BIMMaterialProperties.ifc_style_id:
bpy.ops.bim.add_style(material=material.name)
self.assign_class(obj)
return {"FINISHED"}
@@ -41,7 +41,7 @@ class AddStyle(bpy.types.Operator):
def execute(self, context):
self.file = IfcStore.get_file()
material = bpy.data.objects.get(self.material) if self.material else bpy.context.active_object.active_material
material = bpy.data.materials.get(self.material) if self.material else bpy.context.active_object.active_material
settings = get_colour_settings(material)
settings["Name"] = material.name
settings["external_definition"] = None # TODO: Implement. See #1222
@@ -578,26 +578,6 @@ class RemoveObjectConstraint(bpy.types.Operator):
return {"FINISHED"}
class AddPerson(bpy.types.Operator):
bl_idname = "bim.add_person"
bl_label = "Add Person"
def execute(self, context):
new = bpy.context.scene.BIMProperties.people.add()
new.name = "New Person"
return {"FINISHED"}
class RemovePerson(bpy.types.Operator):
bl_idname = "bim.remove_person"
bl_label = "Remove Person"
index: bpy.props.IntProperty()
def execute(self, context):
bpy.context.scene.BIMProperties.people.remove(self.index)
return {"FINISHED"}
class AddPersonAddress(bpy.types.Operator):
bl_idname = "bim.add_person_address"
bl_label = "Add Person Address"
+2 -2
View File
@@ -1288,11 +1288,11 @@ class BIMProperties(PropertyGroup):
import_should_offset_model: BoolProperty(name="Import and Offset Model", default=False)
import_model_offset_coordinates: StringProperty(name="Model Offset Coordinates", default="0,0,0")
qa_reject_element_reason: StringProperty(name="Element Rejection Reason")
person: EnumProperty(items=getPersons, name="Person")
person: PointerProperty(type=Person)
organisation: EnumProperty(items=getOrganisations, name="Organisation")
people: CollectionProperty(name="People", type=Person)
organisations: CollectionProperty(name="Organisations", type=Organisation)
active_person_index: IntProperty(name="Active Person Index")
active_person_id: IntProperty(name="Active Person Id")
active_organisation_index: IntProperty(name="Active Organisation Index")
has_georeferencing: BoolProperty(name="Has Georeferencing", default=False)
has_library: BoolProperty(name="Has Project Library", default=False)
-41
View File
@@ -1058,47 +1058,6 @@ class BIM_PT_owner(Panel):
row.prop(props, "organisation")
class BIM_PT_people(Panel):
bl_label = "IFC People"
bl_idname = "BIM_PT_people"
bl_options = {"DEFAULT_CLOSED"}
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
def draw(self, context):
layout = self.layout
layout.use_property_split = True
props = context.scene.BIMProperties
row = layout.row()
row.operator("bim.add_person")
if props.people:
layout.template_list("BIM_UL_generic", "", props, "people", props, "active_person_index")
if props.active_person_index < len(props.people):
person = props.people[props.active_person_index]
row = layout.row()
row.prop(person, "name")
row.operator("bim.remove_person", icon="X", text="").index = props.active_person_index
row = layout.row()
row.prop(person, "family_name")
row = layout.row()
row.prop(person, "given_name")
row = layout.row()
row.prop(person, "middle_names")
row = layout.row()
row.prop(person, "prefix_titles")
row = layout.row()
row.prop(person, "suffix_titles")
layout.label(text="Roles:")
draw_roles_ui(layout, person, "person")
layout.label(text="Addresses:")
draw_addresses_ui(layout, person, "person")
class BIM_PT_organisations(Panel):
bl_label = "IFC Organisations"
bl_idname = "BIM_PT_organisations"