mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 23:36:20 +00:00
BBIM: refactor gantt generation operator
This commit is contained in:
@@ -464,62 +464,9 @@ class GenerateGanttChart(bpy.types.Operator):
|
|||||||
work_schedule: bpy.props.IntProperty()
|
work_schedule: bpy.props.IntProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
self.file = IfcStore.get_file()
|
core.generate_gantt_chart(tool.Sequence, work_schedule=tool.Ifc.get().by_id(self.work_schedule))
|
||||||
self.json = []
|
|
||||||
self.sequence_type_map = {
|
|
||||||
None: "FS",
|
|
||||||
"START_START": "SS",
|
|
||||||
"START_FINISH": "SF",
|
|
||||||
"FINISH_START": "FS",
|
|
||||||
"FINISH_FINISH": "FF",
|
|
||||||
"USERDEFINED": "FS",
|
|
||||||
"NOTDEFINED": "FS",
|
|
||||||
}
|
|
||||||
Data.load(self.file)
|
|
||||||
for task_id in Data.work_schedules[self.work_schedule]["RelatedObjects"]:
|
|
||||||
self.create_new_task_json(task_id)
|
|
||||||
with open(os.path.join(context.scene.BIMProperties.data_dir, "gantt", "index.html"), "w") as f:
|
|
||||||
with open(os.path.join(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(context.scene.BIMProperties.data_dir, "gantt", "index.html"))
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
def create_new_task_json(self, task_id):
|
|
||||||
task = self.file.by_id(task_id)
|
|
||||||
data = {
|
|
||||||
"pID": task.id(),
|
|
||||||
"pName": task.Name,
|
|
||||||
"pCaption": 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 "",
|
|
||||||
"pMile": 1 if task.IsMilestone else 0,
|
|
||||||
"pComp": 0,
|
|
||||||
"pGroup": 1 if task.IsNestedBy else 0,
|
|
||||||
"pParent": task.Nests[0].RelatingObject.id() if task.Nests else 0,
|
|
||||||
"pOpen": 1,
|
|
||||||
"pCost": 1,
|
|
||||||
"ifcduration": task.TaskTime.ScheduleDuration if task.TaskTime else "",
|
|
||||||
}
|
|
||||||
if task.TaskTime and task.TaskTime.IsCritical:
|
|
||||||
data["pClass"] = "gtaskred"
|
|
||||||
elif data["pGroup"]:
|
|
||||||
data["pClass"] = "ggroupblack"
|
|
||||||
elif data["pMile"]:
|
|
||||||
data["pClass"] = "gmilestone"
|
|
||||||
else:
|
|
||||||
data["pClass"] = "gtaskblue"
|
|
||||||
data["pDepend"] = ",".join(
|
|
||||||
[
|
|
||||||
"{}{}".format(rel.RelatingProcess.id(), self.sequence_type_map[rel.SequenceType])
|
|
||||||
for rel in task.IsSuccessorFrom or []
|
|
||||||
]
|
|
||||||
)
|
|
||||||
self.json.append(data)
|
|
||||||
for task_id in Data.tasks[task_id]["RelatedObjects"]:
|
|
||||||
self.create_new_task_json(task_id)
|
|
||||||
|
|
||||||
|
|
||||||
class AddWorkCalendar(bpy.types.Operator, tool.Ifc.Operator):
|
class AddWorkCalendar(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.add_work_calendar"
|
bl_idname = "bim.add_work_calendar"
|
||||||
@@ -1097,7 +1044,7 @@ class VisualiseWorkScheduleDateRange(bpy.types.Operator):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
has_start, has_finish = bpy.context.scene.BIMWorkScheduleProperties.visualisation_start, bpy.context.scene.BIMWorkScheduleProperties.visualisation_finish
|
has_start, has_finish = bpy.context.scene.BIMWorkScheduleProperties.visualisation_start, bpy.context.scene.BIMWorkScheduleProperties.visualisation_finish
|
||||||
return bool(has_start and has_finish)
|
return bool(has_start and has_finish) and not "-" in (has_start, has_finish)
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
core.visualise_work_schedule_date_range(tool.Sequence, work_schedule=tool.Ifc.get().by_id(self.work_schedule))
|
core.visualise_work_schedule_date_range(tool.Sequence, work_schedule=tool.Ifc.get().by_id(self.work_schedule))
|
||||||
@@ -1364,3 +1311,13 @@ class DisableEditingTaskAnimationColors(bpy.types.Operator):
|
|||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
core.disable_editing_task_animation_colors(tool.Sequence)
|
core.disable_editing_task_animation_colors(tool.Sequence)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
class CopyTask(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.copy_task"
|
||||||
|
bl_label = "Copy Task"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
task: bpy.props.IntProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
core.copy_task(tool.Ifc, tool.Sequence, task=tool.Ifc.get().by_id(self.task))
|
||||||
|
return {"FINISHED"}
|
||||||
@@ -500,4 +500,8 @@ def visualise_work_schedule_date_range(sequence, work_schedule=None):
|
|||||||
product_frames = sequence.get_animation_product_frames(work_schedule, settings)
|
product_frames = sequence.get_animation_product_frames(work_schedule, settings)
|
||||||
sequence.load_task_animation_colors()
|
sequence.load_task_animation_colors()
|
||||||
sequence.animate_objects(settings, product_frames)
|
sequence.animate_objects(settings, product_frames)
|
||||||
sequence.add_text_animation_handler(settings)
|
sequence.add_text_animation_handler(settings)
|
||||||
|
|
||||||
|
def generate_gantt_chart(sequence, work_schedule):
|
||||||
|
json = sequence.create_tasks_json(work_schedule)
|
||||||
|
sequence.generate_gantt_browser_chart(json)
|
||||||
|
|||||||
@@ -501,7 +501,7 @@ class Sequence:
|
|||||||
def expand_task(cls, task): pass
|
def expand_task(cls, task): pass
|
||||||
def find_related_output_tasks(cls, column): pass
|
def find_related_output_tasks(cls, column): pass
|
||||||
def get_active_task(cls): pass
|
def get_active_task(cls): pass
|
||||||
def get_active_work_schedule_id(cls): pass
|
def get_active_work_schedule(cls): pass
|
||||||
def get_checked_tasks(cls): pass
|
def get_checked_tasks(cls): pass
|
||||||
def get_direct_nested_tasks(cls, task):pass
|
def get_direct_nested_tasks(cls, task):pass
|
||||||
def get_direct_task_outputs(cls, task): pass
|
def get_direct_task_outputs(cls, task): pass
|
||||||
|
|||||||
@@ -18,10 +18,13 @@
|
|||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
import re
|
import re
|
||||||
|
import os
|
||||||
import isodate
|
import isodate
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import ifcopenshell.util.sequence
|
import ifcopenshell.util.sequence
|
||||||
import ifcopenshell.util.date
|
import ifcopenshell.util.date
|
||||||
|
import ifcopenshell.util.element
|
||||||
|
import ifcopenshell.util.unit
|
||||||
import json
|
import json
|
||||||
import blenderbim.core.tool
|
import blenderbim.core.tool
|
||||||
import blenderbim.tool as tool
|
import blenderbim.tool as tool
|
||||||
@@ -30,6 +33,8 @@ import blenderbim.bim.module.sequence.helper as helper
|
|||||||
from dateutil import parser
|
from dateutil import parser
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import mathutils
|
import mathutils
|
||||||
|
import pystache
|
||||||
|
import webbrowser
|
||||||
|
|
||||||
|
|
||||||
class Sequence(blenderbim.core.tool.Sequence):
|
class Sequence(blenderbim.core.tool.Sequence):
|
||||||
@@ -1271,3 +1276,61 @@ class Sequence(blenderbim.core.tool.Sequence):
|
|||||||
obj.data.BIMDateTextProperties.start = bpy.context.scene.BIMWorkScheduleProperties.visualisation_start
|
obj.data.BIMDateTextProperties.start = bpy.context.scene.BIMWorkScheduleProperties.visualisation_start
|
||||||
obj.data.BIMDateTextProperties.finish = bpy.context.scene.BIMWorkScheduleProperties.visualisation_finish
|
obj.data.BIMDateTextProperties.finish = bpy.context.scene.BIMWorkScheduleProperties.visualisation_finish
|
||||||
append_handler(animate_text_handler)
|
append_handler(animate_text_handler)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create_tasks_json(cls, work_schedule=None):
|
||||||
|
sequence_type_map = {
|
||||||
|
None: "FS",
|
||||||
|
"START_START": "SS",
|
||||||
|
"START_FINISH": "SF",
|
||||||
|
"FINISH_START": "FS",
|
||||||
|
"FINISH_FINISH": "FF",
|
||||||
|
"USERDEFINED": "FS",
|
||||||
|
"NOTDEFINED": "FS",
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks_json = []
|
||||||
|
for task in ifcopenshell.util.sequence.get_root_tasks(work_schedule):
|
||||||
|
cls.create_new_task_json(task, tasks_json, sequence_type_map)
|
||||||
|
return tasks_json
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create_new_task_json(cls, task, json, type_map=None):
|
||||||
|
task_time = task.TaskTime
|
||||||
|
data = {
|
||||||
|
"pID": task.id(),
|
||||||
|
"pName": task.Name,
|
||||||
|
"pCaption": task.Name,
|
||||||
|
"pStart": task_time.ScheduleStart if task_time else "",
|
||||||
|
"pEnd": task_time.ScheduleFinish if task_time else "",
|
||||||
|
"pPlanStart": task_time.ScheduleStart if task_time else "",
|
||||||
|
"pPlanEnd": task_time.ScheduleFinish if task_time else "",
|
||||||
|
"pMile": 1 if task.IsMilestone else 0,
|
||||||
|
"pComp": 0,
|
||||||
|
"pGroup": 1 if task.IsNestedBy else 0,
|
||||||
|
"pParent": task.Nests[0].RelatingObject.id() if task.Nests else 0,
|
||||||
|
"pOpen": 1,
|
||||||
|
"pCost": 1,
|
||||||
|
"ifcduration": task_time.ScheduleDuration if task_time else "",
|
||||||
|
}
|
||||||
|
|
||||||
|
if task_time and task_time.IsCritical:
|
||||||
|
data["pClass"] = "gtaskred"
|
||||||
|
elif data["pGroup"]:
|
||||||
|
data["pClass"] = "ggroupblack"
|
||||||
|
elif data["pMile"]:
|
||||||
|
data["pClass"] = "gmilestone"
|
||||||
|
else:
|
||||||
|
data["pClass"] = "gtaskblue"
|
||||||
|
|
||||||
|
data["pDepend"] = ",".join([f"{rel.RelatingProcess.id()}{type_map[rel.SequenceType]}" for rel in task.IsSuccessorFrom or []])
|
||||||
|
json.append(data)
|
||||||
|
for nested_task in ifcopenshell.util.sequence.get_nested_tasks(task):
|
||||||
|
cls.create_new_task_json(nested_task, json, type_map)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def generate_gantt_browser_chart(cls, task_json):
|
||||||
|
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(task_json)}))
|
||||||
|
webbrowser.open("file://" + os.path.join(bpy.context.scene.BIMProperties.data_dir, "gantt", "index.html"))
|
||||||
Reference in New Issue
Block a user