mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-12 10:33:20 +00:00
Feature to enable assigning Construction Resources to Tasks
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user