diff --git a/src/blenderbim/blenderbim/bim/module/sequence/__init__.py b/src/blenderbim/blenderbim/bim/module/sequence/__init__.py index 973cbe3e6e..3d3a176149 100644 --- a/src/blenderbim/blenderbim/bim/module/sequence/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/sequence/__init__.py @@ -32,6 +32,10 @@ classes = ( operator.EnableEditingTask, operator.DisableEditingTask, operator.EditTask, + operator.AssignPredecessor, + operator.AssignSuccessor, + operator.UnassignPredecessor, + operator.UnassignSuccessor, prop.WorkPlan, prop.BIMWorkPlanProperties, prop.Task, diff --git a/src/blenderbim/blenderbim/bim/module/sequence/operator.py b/src/blenderbim/blenderbim/bim/module/sequence/operator.py index e3d4d44425..23969b1fc0 100644 --- a/src/blenderbim/blenderbim/bim/module/sequence/operator.py +++ b/src/blenderbim/blenderbim/bim/module/sequence/operator.py @@ -546,3 +546,75 @@ class EditTask(bpy.types.Operator): bpy.ops.bim.disable_editing_task() bpy.ops.bim.enable_editing_tasks(work_schedule=props.active_work_schedule_id) return {"FINISHED"} + + +class AssignPredecessor(bpy.types.Operator): + bl_idname = "bim.assign_predecessor" + bl_label = "Assign Predecessor" + task: bpy.props.IntProperty() + + def execute(self, context): + props = context.scene.BIMWorkScheduleProperties + self.file = IfcStore.get_file() + ifcopenshell.api.run( + "sequence.assign_sequence", + self.file, + relating_process=IfcStore.get_file().by_id(self.task), + related_process=IfcStore.get_file().by_id(props.active_task_id), + ) + Data.load(self.file) + return {"FINISHED"} + + +class AssignSuccessor(bpy.types.Operator): + bl_idname = "bim.assign_successor" + bl_label = "Assign Successor" + task: bpy.props.IntProperty() + + def execute(self, context): + props = context.scene.BIMWorkScheduleProperties + self.file = IfcStore.get_file() + ifcopenshell.api.run( + "sequence.assign_sequence", + self.file, + relating_process=IfcStore.get_file().by_id(props.active_task_id), + related_process=IfcStore.get_file().by_id(self.task), + ) + Data.load(self.file) + return {"FINISHED"} + + +class UnassignPredecessor(bpy.types.Operator): + bl_idname = "bim.unassign_predecessor" + bl_label = "Unassign Predecessor" + task: bpy.props.IntProperty() + + def execute(self, context): + props = context.scene.BIMWorkScheduleProperties + self.file = IfcStore.get_file() + ifcopenshell.api.run( + "sequence.unassign_sequence", + self.file, + relating_process=IfcStore.get_file().by_id(self.task), + related_process=IfcStore.get_file().by_id(props.active_task_id), + ) + Data.load(self.file) + return {"FINISHED"} + + +class UnassignSuccessor(bpy.types.Operator): + bl_idname = "bim.unassign_successor" + bl_label = "Unassign Successor" + task: bpy.props.IntProperty() + + def execute(self, context): + props = context.scene.BIMWorkScheduleProperties + self.file = IfcStore.get_file() + ifcopenshell.api.run( + "sequence.unassign_sequence", + self.file, + relating_process=IfcStore.get_file().by_id(props.active_task_id), + related_process=IfcStore.get_file().by_id(self.task), + ) + Data.load(self.file) + return {"FINISHED"} diff --git a/src/blenderbim/blenderbim/bim/module/sequence/ui.py b/src/blenderbim/blenderbim/bim/module/sequence/ui.py index 2531a574cf..25d90b949f 100644 --- a/src/blenderbim/blenderbim/bim/module/sequence/ui.py +++ b/src/blenderbim/blenderbim/bim/module/sequence/ui.py @@ -153,6 +153,7 @@ class BIM_PT_work_schedules(Panel): class BIM_UL_tasks(UIList): def draw_item(self, context, layout, data, item, icon, active_data, active_propname): if item: + props = context.scene.BIMWorkScheduleProperties row = layout.row(align=True) for i in range(0, item.level_index): row.label(text="", icon="BLANK1") @@ -169,10 +170,20 @@ class BIM_UL_tasks(UIList): row.label(text="", icon="DOT") row.prop(item, "identification", emboss=False, text="") row.prop(item, "name", emboss=False, text="") - if context.scene.BIMWorkScheduleProperties.active_task_id == item.ifc_definition_id: + if props.active_task_id == item.ifc_definition_id: row.operator("bim.edit_task", text="", icon="CHECKMARK") row.operator("bim.disable_editing_task", text="", icon="CANCEL") - if context.scene.BIMWorkScheduleProperties.active_task_id: + elif props.active_task_id: + if props.active_task_id in Data.tasks[item.ifc_definition_id]["IsPredecessorTo"]: + row.operator("bim.unassign_predecessor", text="", icon="BACK", emboss=False).task = item.ifc_definition_id + else: + row.operator("bim.assign_predecessor", text="", icon="TRACKING_BACKWARDS", emboss=False).task = item.ifc_definition_id + + if props.active_task_id in Data.tasks[item.ifc_definition_id]["IsSuccessorFrom"]: + row.operator("bim.unassign_successor", text="", icon="FORWARD", emboss=False).task = item.ifc_definition_id + else: + row.operator("bim.assign_successor", text="", icon="TRACKING_FORWARDS", emboss=False).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 else: diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/assign_sequence.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/assign_sequence.py new file mode 100644 index 0000000000..d72d237326 --- /dev/null +++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/assign_sequence.py @@ -0,0 +1,27 @@ +import ifcopenshell +import ifcopenshell.api + + +class Usecase: + def __init__(self, file, **settings): + self.file = file + self.settings = { + "relating_process": None, + "related_process": None, + } + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + for rel in self.settings["related_process"].IsSuccessorFrom or []: + if rel.RelatingProcess == self.settings["relating_process"]: + return rel + return self.file.create_entity( + "IfcRelSequence", + **{ + "GlobalId": ifcopenshell.guid.new(), + "OwnerHistory": ifcopenshell.api.run("owner.create_owner_history", self.file), + "RelatingProcess": self.settings["relating_process"], + "RelatedProcess": self.settings["related_process"], + } + ) diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/assign_task_predecessor.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/assign_task_predecessor.py deleted file mode 100644 index 36c0140728..0000000000 --- a/src/ifcopenshell-python/ifcopenshell/api/sequence/assign_task_predecessor.py +++ /dev/null @@ -1,25 +0,0 @@ -import ifcopenshell -import ifcopenshell.api - - -class Usecase: - def __init__(self, file, **settings): - self.file = file - self.settings = { - "predecessor_task": None, - "sequence_type":"FINISH_START", - "task": None, - } - for key, value in settings.items(): - self.settings[key] = value - - def execute(self): - #TODO: tasks can only have one relationship between oneanother: if a relationship is already assigned, it should overide the previous one's settings. - rel_sequence = self.file.create_entity("IfcRelSequence",**{ - "GlobalId": ifcopenshell.guid.new(), - "OwnerHistory": ifcopenshell.api.run("owner.create_owner_history", self.file), - "RelatingProcess": self.settings["predecessor_task"], - "SequenceType": self.settings["sequence_type"], - "RelatedProcess": self.settings["task"], - }) - return rel_sequence \ No newline at end of file diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/assign_task_successor.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/assign_task_successor.py deleted file mode 100644 index 21f818949f..0000000000 --- a/src/ifcopenshell-python/ifcopenshell/api/sequence/assign_task_successor.py +++ /dev/null @@ -1,25 +0,0 @@ -import ifcopenshell -import ifcopenshell.api - - -class Usecase: - def __init__(self, file, **settings): - self.file = file - self.settings = { - "task": None, - "sequence_type":"FINISH_START", - "successor_task": None, - } - for key, value in settings.items(): - self.settings[key] = value - - def execute(self): - #TODO: tasks can only have one relationship between oneanother: if a relationship is already assigned, it should overide the previous one's settings. - rel_sequence = self.file.create_entity("IfcRelSequence",**{ - "GlobalId": ifcopenshell.guid.new(), - "OwnerHistory": ifcopenshell.api.run("owner.create_owner_history", self.file), - "RelatingProcess": self.settings["task"], - "SequenceType": self.settings["sequence_type"], - "RelatedProcess": self.settings["successor_task"], - }) - return rel_sequence \ No newline at end of file diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/data.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/data.py index 04ba1e7a63..3aa298bafc 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/sequence/data.py +++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/data.py @@ -76,6 +76,10 @@ class Data: data = task.get_info() del data["OwnerHistory"] data["RelatedObjects"] = [] + data["IsPredecessorTo"] = [] + data["IsSuccessorFrom"] = [] for rel in task.IsNestedBy: [data["RelatedObjects"].append(o.id()) for o in rel.RelatedObjects if o.is_a("IfcTask")] + [data["IsPredecessorTo"].append(rel.RelatedProcess.id()) for rel in task.IsPredecessorTo or []] + [data["IsSuccessorFrom"].append(rel.RelatingProcess.id()) for rel in task.IsSuccessorFrom or []] cls.tasks[task.id()] = data diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/unassign_sequence.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/unassign_sequence.py new file mode 100644 index 0000000000..496b8bfec2 --- /dev/null +++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/unassign_sequence.py @@ -0,0 +1,18 @@ +import ifcopenshell +import ifcopenshell.api + + +class Usecase: + def __init__(self, file, **settings): + self.file = file + self.settings = { + "relating_process": None, + "related_process": None, + } + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + for rel in self.settings["related_process"].IsSuccessorFrom or []: + if rel.RelatingProcess == self.settings["relating_process"]: + self.file.remove(rel)