See #1848. Refactor sequence data class.

This commit is contained in:
Dion Moult
2023-01-31 20:31:26 +11:00
parent f01900bdb1
commit cd132d4fe9
4 changed files with 88 additions and 46 deletions
@@ -23,6 +23,8 @@ import ifcopenshell
def refresh():
SequenceData.is_loaded = False
WorkPlansData.is_loaded = False
TaskICOMData.is_loaded = False
class SequenceData:
@@ -216,3 +218,62 @@ class SequenceData:
if rel.RelatingControl.is_a("IfcWorkCalendar"):
data["HasAssignmentsWorkCalendar"].append(rel.RelatingControl.id())
cls.data["tasks"][task.id()] = data
class WorkPlansData:
data = {}
is_loaded = False
@classmethod
def load(cls):
cls.data = {
"total_work_plans": cls.total_work_plans(),
"work_plans": cls.work_plans(),
"has_work_schedules": cls.has_work_schedules(),
"active_work_plan_schedules": cls.active_work_plan_schedules(),
}
cls.is_loaded = True
@classmethod
def total_work_plans(cls):
return len(tool.Ifc.get().by_type("IfcWorkPlan"))
@classmethod
def work_plans(cls):
results = []
for work_plan in tool.Ifc.get().by_type("IfcWorkPlan"):
results.append({"id": work_plan.id(), "name": work_plan.Name or "Unnamed"})
return results
@classmethod
def has_work_schedules(cls):
return len(tool.Ifc.get().by_type("IfcWorkSchedule"))
@classmethod
def active_work_plan_schedules(cls):
if not self.props.active_work_plan_id:
return []
for rel in tool.Ifc.get().by_id(self.props.active_work_plan_id).IsDecomposedBy:
for related_object in rel.RelatedObjects:
results.append({"id": work_schedule.id(), "name": work_schedule.Name or "Unnamed"})
return results
class TaskICOMData:
data = {}
is_loaded = False
@classmethod
def load(cls):
cls.data = {"can_active_resource_be_assigned": cls.can_active_resource_be_assigned()}
cls.is_loaded = True
@classmethod
def can_active_resource_be_assigned(cls):
resource_props = bpy.context.scene.BIMResourceProperties
resource_tprops = bpy.context.scene.BIMResourceTreeProperties
total_resources = len(resource_tprops.resources)
if total_resources and resource_props.active_resource_index < total_resources:
resource_id = resource_tprops.resources[resource_props.active_resource_index].ifc_definition_id
return not tool.Ifc.get().by_id(resource_id).is_a("IfcCrewResource")
return False
@@ -31,8 +31,6 @@ from datetime import datetime
from dateutil import parser, relativedelta
from blenderbim.bim.ifc import IfcStore
from bpy_extras.io_utils import ImportHelper
from ifcopenshell.api.sequence.data import Data
from ifcopenshell.api.resource.data import Data as ResourceData
class AddWorkPlan(bpy.types.Operator, tool.Ifc.Operator):
@@ -543,7 +541,6 @@ class ImportP6(bpy.types.Operator, ImportHelper):
p62ifc.file = self.file
p62ifc.work_plan = self.file.by_type("IfcWorkPlan")[0] if self.file.by_type("IfcWorkPlan") else None
p62ifc.execute()
Data.load(IfcStore.get_file())
print("Import finished in {:.2f} seconds".format(time.time() - start))
return {"FINISHED"}
@@ -570,7 +567,6 @@ class ImportP6XER(bpy.types.Operator, ImportHelper):
p6xer2ifc.file = self.file
p6xer2ifc.work_plan = self.file.by_type("IfcWorkPlan")[0] if self.file.by_type("IfcWorkPlan") else None
p6xer2ifc.execute()
Data.load(IfcStore.get_file())
print("Import finished in {:.2f} seconds".format(time.time() - start))
return {"FINISHED"}
@@ -597,7 +593,6 @@ class ImportPP(bpy.types.Operator, ImportHelper):
pp2ifc.file = self.file
pp2ifc.work_plan = self.file.by_type("IfcWorkPlan")[0] if self.file.by_type("IfcWorkPlan") else None
pp2ifc.execute()
Data.load(IfcStore.get_file())
print("Import finished in {:.2f} seconds".format(time.time() - start))
return {"FINISHED"}
@@ -624,7 +619,6 @@ class ImportMSP(bpy.types.Operator, ImportHelper):
msp2ifc.file = self.file
msp2ifc.work_plan = self.file.by_type("IfcWorkPlan")[0] if self.file.by_type("IfcWorkPlan") else None
msp2ifc.execute()
Data.load(IfcStore.get_file())
print("Import finished in {:.2f} seconds".format(time.time() - start))
return {"FINISHED"}
@@ -1320,4 +1314,4 @@ class CopyTask(bpy.types.Operator):
def execute(self, context):
core.copy_task(tool.Ifc, tool.Sequence, task=tool.Ifc.get().by_id(self.task))
return {"FINISHED"}
return {"FINISHED"}
@@ -21,7 +21,6 @@ import isodate
import ifcopenshell.api
import ifcopenshell.util.attribute
from blenderbim.bim.ifc import IfcStore
from ifcopenshell.api.resource.data import Data as ResourceData
from blenderbim.bim.module.sequence.data import SequenceData
import blenderbim.bim.module.pset.data
from blenderbim.bim.prop import StrProperty, Attribute
@@ -21,8 +21,7 @@ import blenderbim.bim.helper
from bpy.types import Panel, UIList
from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.helper import draw_attributes
from blenderbim.bim.module.sequence.data import SequenceData
from ifcopenshell.api.resource.data import Data as ResourceData
from blenderbim.bim.module.sequence.data import WorkPlansData, SequenceData, TaskICOMData
class BIM_PT_work_plans(Panel):
@@ -40,40 +39,37 @@ class BIM_PT_work_plans(Panel):
return file and file.schema != "IFC2X3"
def draw(self, context):
if not SequenceData.is_loaded:
SequenceData.load()
if not WorkPlansData.is_loaded:
WorkPlansData.load()
self.props = context.scene.BIMWorkPlanProperties
row = self.layout.row()
if SequenceData.data["has_work_plans"]:
row.label(
text="{} Work Plans Found".format(SequenceData.data["number_of_work_plans_loaded"]),
icon="TEXT",
)
if WorkPlansData.data["total_work_plans"]:
row.label(text=f"{WorkPlansData.data['total_work_plans']} Work Plans Found", icon="TEXT")
else:
row.label(text="No Work Plans found.", icon="TEXT")
row.operator("bim.add_work_plan", icon="ADD", text="")
for work_plan_id, work_plan in SequenceData.data["work_plans"].items():
self.draw_work_plan_ui(work_plan_id, work_plan)
for work_plan in WorkPlansData.data["work_plans"]:
self.draw_work_plan_ui(work_plan)
def draw_work_plan_ui(self, work_plan_id, work_plan):
def draw_work_plan_ui(self, work_plan):
row = self.layout.row(align=True)
row.label(text=work_plan["Name"] or "Unnamed", icon="TEXT")
row.label(text=work_plan["name"], icon="TEXT")
if self.props.active_work_plan_id == work_plan_id:
if self.props.active_work_plan_id == work_plan["id"]:
if self.props.editing_type == "ATTRIBUTES":
row.operator("bim.edit_work_plan", text="", icon="CHECKMARK")
row.operator("bim.disable_editing_work_plan", text="", icon="CANCEL")
elif self.props.active_work_plan_id:
row.operator("bim.remove_work_plan", text="", icon="X").work_plan = work_plan_id
row.operator("bim.remove_work_plan", text="", icon="X").work_plan = work_plan["id"]
else:
op = row.operator("bim.enable_editing_work_plan_schedules", text="", icon="LINENUMBERS_ON")
op.work_plan = work_plan_id
op.work_plan = work_plan["id"]
op = row.operator("bim.enable_editing_work_plan", text="", icon="GREASEPENCIL")
op.work_plan = work_plan_id
row.operator("bim.remove_work_plan", text="", icon="X").work_plan = work_plan_id
op.work_plan = work_plan["id"]
row.operator("bim.remove_work_plan", text="", icon="X").work_plan = work_plan["id"]
if self.props.active_work_plan_id == work_plan_id:
if self.props.active_work_plan_id == work_plan["id"]:
if self.props.editing_type == "ATTRIBUTES":
self.draw_editable_ui()
elif self.props.editing_type == "SCHEDULES":
@@ -83,22 +79,18 @@ class BIM_PT_work_plans(Panel):
draw_attributes(self.props.work_plan_attributes, self.layout)
def draw_work_schedule_ui(self):
if not SequenceData.is_loaded:
SequenceData.load()
if SequenceData.data["has_work_schedules"]:
if WorkPlansData.data["has_work_schedules"]:
row = self.layout.row(align=True)
row.prop(self.props, "work_schedules", text="")
op = row.operator("bim.assign_work_schedule", text="", icon="ADD")
op.work_plan = self.props.active_work_plan_id
op.work_schedule = int(self.props.work_schedules)
for work_schedule_id in SequenceData.data["work_plans"][self.props.active_work_plan_id]["IsDecomposedBy"]:
work_schedule = SequenceData.data["work_schedules"][work_schedule_id]
for work_schedule in WorkPlansData.data["active_work_plan_schedules"]:
row = self.layout.row(align=True)
row.label(text=work_schedule["Name"] or "Unnamed", icon="LINENUMBERS_ON")
row.label(text=work_schedule["name"], icon="LINENUMBERS_ON")
op = row.operator("bim.unassign_work_schedule", text="", icon="X")
op.work_plan = self.props.active_work_plan_id
op.work_schedule = int(self.props.work_schedules)
op.work_schedule = work_schedule["id"]
else:
row = self.layout.row()
row.label(text="No schedules found. See Work Schedule Panel", icon="INFO")
@@ -409,6 +401,9 @@ class BIM_PT_task_icom(Panel):
return False
def draw(self, context):
if not TaskICOMData.is_loaded:
TaskICOMData.load()
self.props = context.scene.BIMWorkScheduleProperties
self.tprops = context.scene.BIMTaskTreeProperties
task = self.tprops.tasks[self.props.active_task_index]
@@ -449,17 +444,10 @@ class BIM_PT_task_icom(Panel):
op = row2.operator("bim.calculate_task_duration", text="", icon="TEMP")
op.task = task.ifc_definition_id
resource_props = context.scene.BIMResourceProperties
resource_tprops = context.scene.BIMResourceTreeProperties
total_resources = len(resource_tprops.resources)
if total_resources and context.scene.BIMResourceProperties.active_resource_index < total_resources:
resource_id = resource_tprops.resources[resource_props.active_resource_index].ifc_definition_id
ResourceData.load(IfcStore.get_file())
resource = ResourceData.resources[resource_id]
if resource["type"] != "IfcCrewResource":
op = row2.operator("bim.assign_process", icon="ADD", text="")
op.task = task.ifc_definition_id
op.related_object_type = "RESOURCE"
if TaskICOMData.data["can_active_resource_be_assigned"]:
op = row2.operator("bim.assign_process", icon="ADD", text="")
op.task = task.ifc_definition_id
op.related_object_type = "RESOURCE"
if total_task_resources and self.props.active_task_resource_index < total_task_resources:
op = row2.operator("bim.unassign_process", icon="REMOVE", text="")