Feature to enable assigning Construction Resources to Tasks

This commit is contained in:
bosonprojets
2021-08-09 03:13:26 +01:00
parent a83952cec2
commit 6899f9fa8f
6 changed files with 125 additions and 4 deletions
@@ -76,6 +76,9 @@ classes = (
operator.AddTaskColumn,
operator.RemoveTaskColumn,
operator.SetTaskSortColumn,
operator.EnableAssigningResources,
operator.AssignResource,
operator.UnassignResource,
prop.WorkPlan,
prop.BIMWorkPlanProperties,
prop.Task,
@@ -18,6 +18,7 @@ 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):
@@ -534,7 +535,7 @@ class EnableEditingTaskTime(bpy.types.Operator):
def add_task_time(self):
task_time = ifcopenshell.api.run("sequence.add_task_time", self.file, task=self.file.by_id(self.task))
Data.load(IfcStore.get_file())
Data.load(self.file)
return task_time
@@ -1958,3 +1959,79 @@ class SetTaskSortColumn(bpy.types.Operator):
self.props.sort_column = self.column
bpy.ops.bim.enable_editing_tasks(work_schedule=self.props.active_work_schedule_id)
return {"FINISHED"}
class EnableAssigningResources(bpy.types.Operator):
bl_idname = "bim.enable_assigning_resources"
bl_label = "Enable Assigning Resources To Tasks"
bl_options = {"REGISTER", "UNDO"}
task: bpy.props.IntProperty()
def execute(self, context):
self.props = context.scene.BIMWorkScheduleProperties
self.props.active_task_id = self.task
self.props.editing_task_type = "RESOURCES"
return {"FINISHED"}
class AssignResource(bpy.types.Operator):
bl_idname = "bim.assign_resource"
bl_label = "Assign Resource"
bl_options = {"REGISTER", "UNDO"}
task: bpy.props.IntProperty()
parent_resource: bpy.props.IntProperty()
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context):
self.file = IfcStore.get_file()
resource = ifcopenshell.api.run(
"resource.add_resource",
self.file,
**{
"parent_resource": self.file.by_id(self.parent_resource),
"ifc_class": self.file.by_id(self.parent_resource).is_a(),
"name": self.file.by_id(self.parent_resource).Name + ": " + self.file.by_id(self.task).Name,
},
)
ifcopenshell.api.run(
"sequence.assign_process",
self.file,
**{
"related_object": resource,
"relating_process": self.file.by_id(self.task),
},
)
Data.load(self.file)
ResourceData.load(self.file)
bpy.ops.bim.load_resources()
return {"FINISHED"}
class UnassignResource(bpy.types.Operator):
bl_idname = "bim.unassign_resource"
bl_label = "Unassign Resource"
bl_options = {"REGISTER", "UNDO"}
task: bpy.props.IntProperty()
resource: bpy.props.IntProperty()
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context):
self.file = IfcStore.get_file()
ifcopenshell.api.run(
"sequence.unassign_process",
self.file,
related_object=self.file.by_id(self.resource),
relating_process=self.file.by_id(self.task),
)
ifcopenshell.api.run(
"resource.remove_resource",
self.file,
resource=self.file.by_id(self.resource),
)
Data.load(self.file)
ResourceData.load(self.file)
bpy.ops.bim.load_resources()
return {"FINISHED"}
@@ -3,6 +3,7 @@ import ifcopenshell.api
import ifcopenshell.util.attribute
from blenderbim.bim.ifc import IfcStore
from ifcopenshell.api.sequence.data import Data
from ifcopenshell.api.resource.data import Data as ResourceData
from blenderbim.bim.prop import StrProperty, Attribute
from dateutil import parser
from bpy.types import PropertyGroup
@@ -208,6 +209,13 @@ def updateVisualisationStartFinish(self, context, startfinish):
setattr(self, startfinish, canonical_value)
def getResources(self, context):
self.file = IfcStore.get_file()
return [(str(k), v["Name"], "") for k, v in ResourceData.resources.items()
if self.file.by_id(k).Nests and self.file.by_id(k).Nests[0].RelatingObject.HasContext
]
class Task(PropertyGroup):
name: StringProperty(name="Name", update=updateTaskName)
identification: StringProperty(name="Identification", update=updateTaskIdentification)
@@ -297,6 +305,7 @@ class BIMWorkScheduleProperties(PropertyGroup):
name="Speed Type",
default="FRAME_SPEED",
)
resources: EnumProperty(items=getResources, name="Resources")
class BIMTaskTreeProperties(PropertyGroup):
@@ -3,6 +3,7 @@ import blenderbim.bim.helper
from bpy.types import Panel, UIList
from blenderbim.bim.ifc import IfcStore
from ifcopenshell.api.sequence.data import Data
from ifcopenshell.api.resource.data import Data as ResourceData
import blenderbim.bim.module.sequence.helper as helper
from datetime import datetime
@@ -214,6 +215,8 @@ class BIM_PT_work_schedules(Panel):
self.draw_editable_task_sequence_ui()
elif self.props.active_task_time_id and self.props.editing_task_type == "TASKTIME":
self.draw_editable_task_time_attributes_ui()
elif self.props.active_task_id and self.props.editing_task_type == "RESOURCES":
self.draw_editable_task_resource_ui()
def draw_editable_task_sequence_ui(self):
task = Data.tasks[self.props.active_task_id]
@@ -287,6 +290,23 @@ class BIM_PT_work_schedules(Panel):
def draw_editable_task_time_attributes_ui(self):
blenderbim.bim.helper.draw_attributes(self.props.task_time_attributes, self.layout)
def draw_editable_task_resource_ui(self):
row = self.layout.row(align=True)
row.prop(self.props, "resources", text="")
op = row.operator("bim.assign_resource", text="", icon="ADD")
op.parent_resource = int(self.props.resources)
op.task = self.props.active_task_id
task = Data.tasks[self.props.active_task_id]
ResourceData.load(IfcStore.get_file())
for related_obect_id in task["OperatesOn"]:
resource = ResourceData.resources[related_obect_id]
row = self.layout.row(align=True)
row.label(text=resource["Name"], icon="COMMUNITY")
op = row.operator("bim.unassign_resource", text="", icon="X")
op.task = self.props.active_task_id
op.resource = related_obect_id
class BIM_UL_task_columns(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
@@ -416,6 +436,7 @@ class BIM_UL_tasks(UIList):
row.operator(
"bim.enable_editing_task_calendar", text="", icon="VIEW_ORTHO"
).task = item.ifc_definition_id
row.operator("bim.enable_assigning_resources", text="", icon="COMMUNITY").task = item.ifc_definition_id
row.operator("bim.enable_editing_task", text="", icon="GREASEPENCIL").task = item.ifc_definition_id
row.operator("bim.add_task", text="", icon="ADD").task = item.ifc_definition_id
row.operator("bim.remove_task", text="", icon="X").task = item.ifc_definition_id
@@ -19,7 +19,7 @@ class Usecase:
self.file,
ifc_class=self.settings["ifc_class"],
predefined_type=self.settings["predefined_type"],
name=self.settings["name"],
name=self.settings["name"] or "Unammed",
)
# TODO: this is an ambiguity by buildingSMART: Can we nest an IfcCrewResource under an IfcCrewResource ?
# https://forums.buildingsmart.org/t/what-are-allowed-to-be-root-level-construction-resources/3550
@@ -4,20 +4,31 @@ class Data:
@classmethod
def purge(cls):
cls.is_loaded = False
cls.resources = {}
@classmethod
def load(cls, file):
cls._file = file
if not cls._file:
return
cls.load_resources()
cls.is_loaded=True
@classmethod
def load_resources(cls):
cls.resources = {}
for resource in file.by_type("IfcResource"):
for resource in cls._file.by_type("IfcResource"):
data = resource.get_info()
del data["OwnerHistory"]
data["IsNestedBy"] = []
for rel in resource.IsNestedBy:
[data["IsNestedBy"].append(o.id()) for o in rel.RelatedObjects]
data["Nests"] = []
for rel in resource.Nests:
[data["Nests"].append(rel.RelatingObject.id())]
data["ResourceOf"] = []
for rel in resource.ResourceOf:
[data["ResourceOf"].append(o.id()) for o in rel.RelatedObjects]
data["HasContext"] = resource.HasContext[0].RelatingContext.id() if resource.HasContext else None
cls.resources[resource.id()] = data
cls.is_loaded=True