From 6bcfa5946f70b12323c4ed92d5c3851a5d228fb6 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Wed, 17 Feb 2021 22:54:11 +1100 Subject: [PATCH] New basic UI to view tasks in an IFC file --- .../blenderbim/bim/__init__.py | 1 + .../blenderbim/bim/module/constraint/ui.py | 1 - .../bim/module/sequence/__init__.py | 19 +++++++ .../blenderbim/bim/module/sequence/data.py | 18 +++++++ .../bim/module/sequence/operator.py | 29 ++++++++++ .../blenderbim/bim/module/sequence/prop.py | 26 +++++++++ .../blenderbim/bim/module/sequence/ui.py | 53 +++++++++++++++++++ src/ifcblenderexport/p6_to_ifc.py | 23 +++++--- 8 files changed, 162 insertions(+), 8 deletions(-) create mode 100644 src/ifcblenderexport/blenderbim/bim/module/sequence/__init__.py create mode 100644 src/ifcblenderexport/blenderbim/bim/module/sequence/data.py create mode 100644 src/ifcblenderexport/blenderbim/bim/module/sequence/operator.py create mode 100644 src/ifcblenderexport/blenderbim/bim/module/sequence/prop.py create mode 100644 src/ifcblenderexport/blenderbim/bim/module/sequence/ui.py diff --git a/src/ifcblenderexport/blenderbim/bim/__init__.py b/src/ifcblenderexport/blenderbim/bim/__init__.py index 6eec4e5a6d..6d94237727 100644 --- a/src/ifcblenderexport/blenderbim/bim/__init__.py +++ b/src/ifcblenderexport/blenderbim/bim/__init__.py @@ -23,6 +23,7 @@ if bpy is not None: "aggregate": None, "geometry": None, "cobie": None, + "sequence": None, "material": None, "style": None, "layer": None, diff --git a/src/ifcblenderexport/blenderbim/bim/module/constraint/ui.py b/src/ifcblenderexport/blenderbim/bim/module/constraint/ui.py index 0c8ce408ed..329a203779 100644 --- a/src/ifcblenderexport/blenderbim/bim/module/constraint/ui.py +++ b/src/ifcblenderexport/blenderbim/bim/module/constraint/ui.py @@ -42,7 +42,6 @@ class BIM_PT_constraints(Panel): if self.props.active_constraint_id: self.draw_editable_ui(context) - return def draw_editable_ui(self, context): for attribute in self.props.constraint_attributes: diff --git a/src/ifcblenderexport/blenderbim/bim/module/sequence/__init__.py b/src/ifcblenderexport/blenderbim/bim/module/sequence/__init__.py new file mode 100644 index 0000000000..15641355a0 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/sequence/__init__.py @@ -0,0 +1,19 @@ +import bpy +from . import ui, prop, operator + +classes = ( + operator.LoadTasks, + operator.DisableTaskEditingUI, + prop.Task, + prop.BIMTaskProperties, + ui.BIM_PT_tasks, + ui.BIM_UL_tasks, +) + + +def register(): + bpy.types.Scene.BIMTaskProperties = bpy.props.PointerProperty(type=prop.BIMTaskProperties) + + +def unregister(): + del bpy.types.Scene.BIMTaskProperties diff --git a/src/ifcblenderexport/blenderbim/bim/module/sequence/data.py b/src/ifcblenderexport/blenderbim/bim/module/sequence/data.py new file mode 100644 index 0000000000..dd7dc98e98 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/sequence/data.py @@ -0,0 +1,18 @@ +from blenderbim.bim.ifc import IfcStore + + +class Data: + is_loaded = False + tasks = {} + + @classmethod + def purge(cls): + cls.is_loaded = False + cls.tasks = {} + + @classmethod + def load(cls): + cls.tasks = {} + for task in IfcStore.get_file().by_type("IfcTask"): + cls.tasks[task.id()] = {"Name": task.Name, "Identification": task.Identification or ""} + cls.is_loaded=True diff --git a/src/ifcblenderexport/blenderbim/bim/module/sequence/operator.py b/src/ifcblenderexport/blenderbim/bim/module/sequence/operator.py new file mode 100644 index 0000000000..97cb506169 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/sequence/operator.py @@ -0,0 +1,29 @@ +import bpy +from blenderbim.bim.ifc import IfcStore +from blenderbim.bim.module.sequence.data import Data + + +class LoadTasks(bpy.types.Operator): + bl_idname = "bim.load_tasks" + bl_label = "Load Tasks" + + def execute(self, context): + props = context.scene.BIMTaskProperties + while len(props.tasks) > 0: + props.tasks.remove(0) + for ifc_definition_id, task in Data.tasks.items(): + new = props.tasks.add() + new.ifc_definition_id = ifc_definition_id + new.name = task["Name"] + new.identification = task["Identification"] + props.is_editing = True + return {"FINISHED"} + + +class DisableTaskEditingUI(bpy.types.Operator): + bl_idname = "bim.disable_task_editing_ui" + bl_label = "Disable Task Editing UI" + + def execute(self, context): + context.scene.BIMTaskProperties.is_editing = False + return {"FINISHED"} diff --git a/src/ifcblenderexport/blenderbim/bim/module/sequence/prop.py b/src/ifcblenderexport/blenderbim/bim/module/sequence/prop.py new file mode 100644 index 0000000000..84f9e92181 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/sequence/prop.py @@ -0,0 +1,26 @@ +import bpy +from blenderbim.bim.prop import StrProperty, Attribute +from blenderbim.bim.module.sequence.data import Data +from bpy.types import PropertyGroup +from bpy.props import ( + PointerProperty, + StringProperty, + EnumProperty, + BoolProperty, + IntProperty, + FloatProperty, + FloatVectorProperty, + CollectionProperty, +) + + +class Task(PropertyGroup): + name: StringProperty(name="Name") + identification: StringProperty(name="Identification") + ifc_definition_id: IntProperty(name="IFC Definition ID") + + +class BIMTaskProperties(PropertyGroup): + is_editing: BoolProperty(name="Is Editing", default=False) + tasks: CollectionProperty(name="Available Library References", type=Task) + active_task_index: IntProperty(name="Active Task Index") diff --git a/src/ifcblenderexport/blenderbim/bim/module/sequence/ui.py b/src/ifcblenderexport/blenderbim/bim/module/sequence/ui.py new file mode 100644 index 0000000000..7334c7d788 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/sequence/ui.py @@ -0,0 +1,53 @@ +from bpy.types import Panel, UIList +from blenderbim.bim.ifc import IfcStore +from blenderbim.bim.module.sequence.data import Data + + +class BIM_PT_tasks(Panel): + bl_label = "IFC Tasks" + bl_idname = "BIM_PT_tasks" + 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.props = context.scene.BIMTaskProperties + + row = self.layout.row(align=True) + row.label(text="{} Tasks Found".format(len(Data.tasks)), icon="ACTION") + if self.props.is_editing: + row.operator("bim.disable_task_editing_ui", text="", icon="CHECKMARK") + else: + row.operator("bim.load_tasks", text="", icon="GREASEPENCIL") + + if self.props.is_editing: + self.layout.template_list( + "BIM_UL_tasks", + "", + self.props, + "tasks", + self.props, + "active_task_index", + ) + + if self.props.active_task_index: + self.draw_editable_ui(context) + + def draw_editable_ui(self, context): + pass + + +class BIM_UL_tasks(UIList): + def draw_item(self, context, layout, data, item, icon, active_data, active_propname): + if item: + row = layout.row(align=True) + if item.identification: + layout.label(text=item.identification) + layout.label(text=item.name) diff --git a/src/ifcblenderexport/p6_to_ifc.py b/src/ifcblenderexport/p6_to_ifc.py index 4eed375423..68ab8bd74f 100644 --- a/src/ifcblenderexport/p6_to_ifc.py +++ b/src/ifcblenderexport/p6_to_ifc.py @@ -32,6 +32,7 @@ class P6ToIfc: self.wbs[activity.find("pr:WBSObjectId", ns).text]["activities"].append( { "Name": activity.find("pr:Name", ns).text, + "Identification": activity.find("pr:Id", ns).text, "StartDate": activity.find("pr:StartDate", ns).text, "FinishDate": activity.find("pr:FinishDate", ns).text, "ifc": None, @@ -43,7 +44,7 @@ class P6ToIfc: def create_ifc(self): self.file = ifcopenshell.file(schema="IFC4") - #self.file = ifcopenshell.file(schema="IFC2X3") + # self.file = ifcopenshell.file(schema="IFC2X3") self.root = self.file.create_entity( "IfcTask", **{"GlobalId": ifcopenshell.guid.new(), "Name": self.project["Name"]} ) @@ -89,16 +90,24 @@ class P6ToIfc: is_milestone = activity["StartDate"] == activity["FinishDate"] activity["ifc"] = self.file.create_entity( "IfcTask", - **{"GlobalId": ifcopenshell.guid.new(), "Name": activity["Name"], "IsMilestone": is_milestone} + **{ + "GlobalId": ifcopenshell.guid.new(), + "Name": activity["Name"], + "Identification": activity["Identification"], + "IsMilestone": is_milestone, + } ) if self.file.schema == "IFC2X3": # Invalid, but reading the IFC2X3 docs gives me a headache - self.file.create_entity("IfcRelAssignsTasks", **{ - "GlobalId": ifcopenshell.guid.new(), - "RelatedObjects": [activity["ifc"]], - "TimeForTask": activity["TimeForTask"] - }) + self.file.create_entity( + "IfcRelAssignsTasks", + **{ + "GlobalId": ifcopenshell.guid.new(), + "RelatedObjects": [activity["ifc"]], + "TimeForTask": activity["TimeForTask"], + } + ) else: activity["ifc"].TaskTime = activity["TaskTime"]