From e7b153cbf67655cb86f8226bf6f997246bb16bbe Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Wed, 21 Apr 2021 12:57:31 +1000 Subject: [PATCH] You can now generate gantt charts from work schedules --- src/blenderbim/Makefile | 7 ++++ .../blenderbim/bim/data/gantt/index.mustache | 11 +++++ .../bim/module/sequence/__init__.py | 1 + .../bim/module/sequence/operator.py | 42 +++++++++++++++++++ .../blenderbim/bim/module/sequence/ui.py | 1 + src/blenderbim/ifc_to_gantt.py | 33 --------------- 6 files changed, 62 insertions(+), 33 deletions(-) create mode 100644 src/blenderbim/blenderbim/bim/data/gantt/index.mustache delete mode 100644 src/blenderbim/ifc_to_gantt.py diff --git a/src/blenderbim/Makefile b/src/blenderbim/Makefile index 894f8297d6..f90728a02e 100644 --- a/src/blenderbim/Makefile +++ b/src/blenderbim/Makefile @@ -184,6 +184,13 @@ endif cp -r dist/working/python-dateutil-2.8.1/dateutil dist/blenderbim/libs/site/packages/ rm -rf dist/working + # Provides jsgantt-improved supports for web-based construction sequencing gantt charts + mkdir dist/working + cd dist/working && wget https://raw.githubusercontent.com/jsGanttImproved/jsgantt-improved/master/dist/jsgantt.js + cd dist/working && wget https://raw.githubusercontent.com/jsGanttImproved/jsgantt-improved/master/dist/jsgantt.css + cd dist/working && mv jsgantt* dist/blenderbim/bim/data/gantt/ + rm -rf dist/working + # Required by IFCDiff mkdir dist/working cd dist/working && wget https://github.com/Moult/deepdiff/archive/master.zip diff --git a/src/blenderbim/blenderbim/bim/data/gantt/index.mustache b/src/blenderbim/blenderbim/bim/data/gantt/index.mustache new file mode 100644 index 0000000000..832f8e4a8b --- /dev/null +++ b/src/blenderbim/blenderbim/bim/data/gantt/index.mustache @@ -0,0 +1,11 @@ + + +
+ diff --git a/src/blenderbim/blenderbim/bim/module/sequence/__init__.py b/src/blenderbim/blenderbim/bim/module/sequence/__init__.py index b205cce8bb..6dd9b2c6b9 100644 --- a/src/blenderbim/blenderbim/bim/module/sequence/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/sequence/__init__.py @@ -41,6 +41,7 @@ classes = ( operator.EditTaskTime, operator.AssignProduct, operator.UnassignProduct, + operator.GenerateGanttChart, 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 3984198796..66fb5232e7 100644 --- a/src/blenderbim/blenderbim/bim/module/sequence/operator.py +++ b/src/blenderbim/blenderbim/bim/module/sequence/operator.py @@ -1,5 +1,8 @@ +import os import bpy import json +import pystache +import webbrowser import ifcopenshell.api from datetime import datetime from dateutil import parser @@ -783,3 +786,42 @@ class UnassignProduct(bpy.types.Operator): ) Data.load(self.file) return {"FINISHED"} + + +class GenerateGanttChart(bpy.types.Operator): + bl_idname = "bim.generate_gantt_chart" + bl_label = "Generate Gantt Chart" + work_schedule: bpy.props.IntProperty() + + def execute(self, context): + self.file = IfcStore.get_file() + self.json = [] + for task_id in Data.work_schedules[self.work_schedule]["RelatedObjects"]: + self.create_new_task_json(task_id) + with open(os.path.join(bpy.context.scene.BIMProperties.data_dir, "gantt", "index.html"), "w") as f: + with open(os.path.join(bpy.context.scene.BIMProperties.data_dir, "gantt", "index.mustache"), "r") as t: + f.write(pystache.render(t.read(), {"json_data": json.dumps(self.json)})) + webbrowser.open("file://" + os.path.join(bpy.context.scene.BIMProperties.data_dir, "gantt", "index.html")) + return {"FINISHED"} + + def create_new_task_json(self, task_id): + task = self.file.by_id(task_id) + self.json.append( + { + "pID": task.id(), + "pName": task.Name, + "pStart": task.TaskTime.ScheduleStart if task.TaskTime else "", + "pEnd": task.TaskTime.ScheduleFinish if task.TaskTime else "", + "pPlanStart": task.TaskTime.ScheduleStart if task.TaskTime else "", + "pPlanEnd": task.TaskTime.ScheduleFinish if task.TaskTime else "", + "pClass": "ggroupblack", + "pMile": 1 if task.IsMilestone else 0, + "pComp": 0, + "pGroup": 1, + "pParent": task.Nests[0].RelatingObject.id() if task.Nests else 0, + "pOpen": 1, + "pCost": 1, + } + ) + for task_id in Data.tasks[task_id]["RelatedObjects"]: + self.create_new_task_json(task_id) diff --git a/src/blenderbim/blenderbim/bim/module/sequence/ui.py b/src/blenderbim/blenderbim/bim/module/sequence/ui.py index 492fbda7a9..e1bb49fe11 100644 --- a/src/blenderbim/blenderbim/bim/module/sequence/ui.py +++ b/src/blenderbim/blenderbim/bim/module/sequence/ui.py @@ -100,6 +100,7 @@ class BIM_PT_work_schedules(Panel): row.operator("bim.edit_work_schedule", text="", icon="CHECKMARK") elif self.props.is_editing == "TASKS": row.prop(self.props, "should_show_times", text="", icon="TIME") + row.operator("bim.generate_gantt_chart", text="", icon="NLA").work_schedule = work_schedule_id row.operator("bim.add_summary_task", text="", icon="ADD").work_schedule = work_schedule_id row.operator("bim.disable_editing_work_schedule", text="", icon="CANCEL") elif self.props.active_work_schedule_id: diff --git a/src/blenderbim/ifc_to_gantt.py b/src/blenderbim/ifc_to_gantt.py deleted file mode 100644 index 1359805a02..0000000000 --- a/src/blenderbim/ifc_to_gantt.py +++ /dev/null @@ -1,33 +0,0 @@ -import json -import ifcopenshell - -class IfcToGantt: - def __init__(self): - self.json = [] - - def execute(self): - self.file = ifcopenshell.open("p6.ifc") - self.root = self.file.by_type("IfcTask")[0] - task = self.root - for task in self.file.by_type("IfcTask"): - self.json.append({ - "pID": task.id(), - "pName": task.Name, - "pStart": task.TaskTime.ScheduleStart if task.TaskTime else "", - "pEnd": task.TaskTime.ScheduleFinish if task.TaskTime else "", - "pPlanStart": task.TaskTime.ScheduleStart if task.TaskTime else "", - "pPlanEnd": task.TaskTime.ScheduleFinish if task.TaskTime else "", - "pClass": "ggroupblack", - "pMile": 1 if task.IsMilestone else 0, - "pComp": 0, - "pGroup": 1, - "pParent": task.Nests[0].RelatingObject.id() if task.Nests else 0, - "pOpen": 1, - "pCost": 1 - }) - with open("p6.json", "w") as f: - json.dump(self.json, f) - -ifc_to_gantt = IfcToGantt() -ifc_to_gantt.execute() -