mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-28 03:05:33 +00:00
Feature to enable assigning Construction Resources to Tasks
This commit is contained in:
@@ -76,6 +76,9 @@ classes = (
|
|||||||
operator.AddTaskColumn,
|
operator.AddTaskColumn,
|
||||||
operator.RemoveTaskColumn,
|
operator.RemoveTaskColumn,
|
||||||
operator.SetTaskSortColumn,
|
operator.SetTaskSortColumn,
|
||||||
|
operator.EnableAssigningResources,
|
||||||
|
operator.AssignResource,
|
||||||
|
operator.UnassignResource,
|
||||||
prop.WorkPlan,
|
prop.WorkPlan,
|
||||||
prop.BIMWorkPlanProperties,
|
prop.BIMWorkPlanProperties,
|
||||||
prop.Task,
|
prop.Task,
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ from dateutil import parser, relativedelta
|
|||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
from bpy_extras.io_utils import ImportHelper
|
from bpy_extras.io_utils import ImportHelper
|
||||||
from ifcopenshell.api.sequence.data import Data
|
from ifcopenshell.api.sequence.data import Data
|
||||||
|
from ifcopenshell.api.resource.data import Data as ResourceData
|
||||||
|
|
||||||
|
|
||||||
class AddWorkPlan(bpy.types.Operator):
|
class AddWorkPlan(bpy.types.Operator):
|
||||||
@@ -534,7 +535,7 @@ class EnableEditingTaskTime(bpy.types.Operator):
|
|||||||
|
|
||||||
def add_task_time(self):
|
def add_task_time(self):
|
||||||
task_time = ifcopenshell.api.run("sequence.add_task_time", self.file, task=self.file.by_id(self.task))
|
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
|
return task_time
|
||||||
|
|
||||||
|
|
||||||
@@ -1958,3 +1959,79 @@ class SetTaskSortColumn(bpy.types.Operator):
|
|||||||
self.props.sort_column = self.column
|
self.props.sort_column = self.column
|
||||||
bpy.ops.bim.enable_editing_tasks(work_schedule=self.props.active_work_schedule_id)
|
bpy.ops.bim.enable_editing_tasks(work_schedule=self.props.active_work_schedule_id)
|
||||||
return {"FINISHED"}
|
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
|
import ifcopenshell.util.attribute
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
from ifcopenshell.api.sequence.data import Data
|
from ifcopenshell.api.sequence.data import Data
|
||||||
|
from ifcopenshell.api.resource.data import Data as ResourceData
|
||||||
from blenderbim.bim.prop import StrProperty, Attribute
|
from blenderbim.bim.prop import StrProperty, Attribute
|
||||||
from dateutil import parser
|
from dateutil import parser
|
||||||
from bpy.types import PropertyGroup
|
from bpy.types import PropertyGroup
|
||||||
@@ -208,6 +209,13 @@ def updateVisualisationStartFinish(self, context, startfinish):
|
|||||||
setattr(self, startfinish, canonical_value)
|
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):
|
class Task(PropertyGroup):
|
||||||
name: StringProperty(name="Name", update=updateTaskName)
|
name: StringProperty(name="Name", update=updateTaskName)
|
||||||
identification: StringProperty(name="Identification", update=updateTaskIdentification)
|
identification: StringProperty(name="Identification", update=updateTaskIdentification)
|
||||||
@@ -297,6 +305,7 @@ class BIMWorkScheduleProperties(PropertyGroup):
|
|||||||
name="Speed Type",
|
name="Speed Type",
|
||||||
default="FRAME_SPEED",
|
default="FRAME_SPEED",
|
||||||
)
|
)
|
||||||
|
resources: EnumProperty(items=getResources, name="Resources")
|
||||||
|
|
||||||
|
|
||||||
class BIMTaskTreeProperties(PropertyGroup):
|
class BIMTaskTreeProperties(PropertyGroup):
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import blenderbim.bim.helper
|
|||||||
from bpy.types import Panel, UIList
|
from bpy.types import Panel, UIList
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
from ifcopenshell.api.sequence.data import Data
|
from ifcopenshell.api.sequence.data import Data
|
||||||
|
from ifcopenshell.api.resource.data import Data as ResourceData
|
||||||
import blenderbim.bim.module.sequence.helper as helper
|
import blenderbim.bim.module.sequence.helper as helper
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
@@ -214,6 +215,8 @@ class BIM_PT_work_schedules(Panel):
|
|||||||
self.draw_editable_task_sequence_ui()
|
self.draw_editable_task_sequence_ui()
|
||||||
elif self.props.active_task_time_id and self.props.editing_task_type == "TASKTIME":
|
elif self.props.active_task_time_id and self.props.editing_task_type == "TASKTIME":
|
||||||
self.draw_editable_task_time_attributes_ui()
|
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):
|
def draw_editable_task_sequence_ui(self):
|
||||||
task = Data.tasks[self.props.active_task_id]
|
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):
|
def draw_editable_task_time_attributes_ui(self):
|
||||||
blenderbim.bim.helper.draw_attributes(self.props.task_time_attributes, self.layout)
|
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):
|
class BIM_UL_task_columns(UIList):
|
||||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||||
@@ -416,6 +436,7 @@ class BIM_UL_tasks(UIList):
|
|||||||
row.operator(
|
row.operator(
|
||||||
"bim.enable_editing_task_calendar", text="", icon="VIEW_ORTHO"
|
"bim.enable_editing_task_calendar", text="", icon="VIEW_ORTHO"
|
||||||
).task = item.ifc_definition_id
|
).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.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.add_task", text="", icon="ADD").task = item.ifc_definition_id
|
||||||
row.operator("bim.remove_task", text="", icon="X").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,
|
self.file,
|
||||||
ifc_class=self.settings["ifc_class"],
|
ifc_class=self.settings["ifc_class"],
|
||||||
predefined_type=self.settings["predefined_type"],
|
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 ?
|
# 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
|
# https://forums.buildingsmart.org/t/what-are-allowed-to-be-root-level-construction-resources/3550
|
||||||
|
|||||||
@@ -4,20 +4,31 @@ class Data:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def purge(cls):
|
def purge(cls):
|
||||||
|
cls.is_loaded = False
|
||||||
cls.resources = {}
|
cls.resources = {}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load(cls, file):
|
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 = {}
|
cls.resources = {}
|
||||||
for resource in file.by_type("IfcResource"):
|
for resource in cls._file.by_type("IfcResource"):
|
||||||
data = resource.get_info()
|
data = resource.get_info()
|
||||||
del data["OwnerHistory"]
|
del data["OwnerHistory"]
|
||||||
data["IsNestedBy"] = []
|
data["IsNestedBy"] = []
|
||||||
for rel in resource.IsNestedBy:
|
for rel in resource.IsNestedBy:
|
||||||
[data["IsNestedBy"].append(o.id()) for o in rel.RelatedObjects]
|
[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"] = []
|
data["ResourceOf"] = []
|
||||||
for rel in resource.ResourceOf:
|
for rel in resource.ResourceOf:
|
||||||
[data["ResourceOf"].append(o.id()) for o in rel.RelatedObjects]
|
[data["ResourceOf"].append(o.id()) for o in rel.RelatedObjects]
|
||||||
data["HasContext"] = resource.HasContext[0].RelatingContext.id() if resource.HasContext else None
|
data["HasContext"] = resource.HasContext[0].RelatingContext.id() if resource.HasContext else None
|
||||||
cls.resources[resource.id()] = data
|
cls.resources[resource.id()] = data
|
||||||
cls.is_loaded=True
|
|
||||||
|
|||||||
Reference in New Issue
Block a user