mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 09:48:32 +00:00
massive refactor of the sequence module
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# from datetime import date
|
||||
import bpy
|
||||
import json
|
||||
import math
|
||||
@@ -46,6 +47,11 @@ def draw_attribute(attribute, layout, copy_operator=None):
|
||||
value_name,
|
||||
text=attribute.name,
|
||||
)
|
||||
if "ScheduleDuration" in attribute.name:
|
||||
layout.prop(bpy.context.scene.BIMDuration, "duration_days",text="D")
|
||||
layout.prop(bpy.context.scene.BIMDuration, "duration_hours",text="H")
|
||||
layout.prop(bpy.context.scene.BIMDuration, "duration_minutes",text="M")
|
||||
|
||||
if attribute.is_optional:
|
||||
layout.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="")
|
||||
if copy_operator:
|
||||
@@ -78,6 +84,7 @@ def import_attribute(attribute, props, data, callback=None):
|
||||
new.is_optional = attribute.optional()
|
||||
new.data_type = data_type if isinstance(data_type, str) else ""
|
||||
is_handled_by_callback = callback(attribute.name(), new, data) if callback else None
|
||||
|
||||
if is_handled_by_callback:
|
||||
pass # Our job is done
|
||||
elif is_handled_by_callback is False:
|
||||
@@ -96,8 +103,7 @@ def import_attribute(attribute, props, data, callback=None):
|
||||
new.enum_items = json.dumps(ifcopenshell.util.attribute.get_enum_items(attribute))
|
||||
if data[attribute.name()]:
|
||||
new.enum_value = data[attribute.name()]
|
||||
|
||||
|
||||
|
||||
def export_attributes(props, callback=None):
|
||||
attributes = {}
|
||||
for prop in props:
|
||||
|
||||
@@ -102,7 +102,8 @@ class EnablePsetEditing(bpy.types.Operator):
|
||||
def execute(self, context):
|
||||
self.props = get_pset_props(context, self.obj, self.obj_type)
|
||||
self.props.properties.clear()
|
||||
|
||||
ifc_definition_id = get_pset_obj_ifc_definition_id(context, self.obj, self.obj_type)
|
||||
Data.load(IfcStore.get_file(), ifc_definition_id)
|
||||
data = Data.psets if self.pset_id in Data.psets else Data.qtos
|
||||
pset_data = data[self.pset_id]
|
||||
self.props.active_pset_name = pset_data["Name"]
|
||||
|
||||
@@ -40,6 +40,7 @@ class LoadResources(bpy.types.Operator):
|
||||
self.tprops.resources.clear()
|
||||
|
||||
self.contracted_resources = json.loads(self.props.contracted_resources)
|
||||
Data.load(IfcStore.get_file())
|
||||
for resource_id, data in Data.resources.items():
|
||||
if not data["HasContext"]:
|
||||
continue
|
||||
@@ -116,7 +117,7 @@ class LoadResourceProperties(bpy.types.Operator):
|
||||
|
||||
class DisableEditingResource(bpy.types.Operator):
|
||||
bl_idname = "bim.disable_editing_resource"
|
||||
bl_label = "Disable Editing Workplan"
|
||||
bl_label = "Disable Editing Resources"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
@@ -20,6 +20,7 @@ import bpy
|
||||
import ifcopenshell.api
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from ifcopenshell.api.resource.data import Data
|
||||
import blenderbim.bim.module.pset.data
|
||||
from blenderbim.bim.prop import StrProperty, Attribute
|
||||
from bpy.types import PropertyGroup
|
||||
from bpy.props import (
|
||||
@@ -70,6 +71,9 @@ def get_quantity_types(self, context):
|
||||
return quantitytypes_enum
|
||||
|
||||
|
||||
def update_active_resource_index(self, context):
|
||||
blenderbim.bim.module.pset.data.refresh()
|
||||
|
||||
class Resource(PropertyGroup):
|
||||
name: StringProperty(name="Name", update=updateResourceName)
|
||||
ifc_definition_id: IntProperty(name="IFC Definition ID")
|
||||
@@ -85,7 +89,7 @@ class BIMResourceTreeProperties(PropertyGroup):
|
||||
class BIMResourceProperties(PropertyGroup):
|
||||
resource_attributes: CollectionProperty(name="Resource Attributes", type=Attribute)
|
||||
is_editing: BoolProperty(name="Is Editing")
|
||||
active_resource_index: IntProperty(name="Active Resource Index")
|
||||
active_resource_index: IntProperty(name="Active Resource Index", update=update_active_resource_index)
|
||||
active_resource_id: IntProperty(name="Active Resource Id")
|
||||
contracted_resources: StringProperty(name="Contracted Resources", default="[]")
|
||||
is_resource_update_enabled: BoolProperty(name="Is Resource Update Enabled", default=True)
|
||||
|
||||
@@ -63,7 +63,7 @@ classes = (
|
||||
operator.EnableEditingTaskCalendar,
|
||||
operator.EnableEditingTaskSequence,
|
||||
operator.EnableEditingTaskTime,
|
||||
operator.EnableEditingTasks,
|
||||
operator.EnableEditingWorkScheduleTasks,
|
||||
operator.EnableEditingWorkCalendar,
|
||||
operator.EnableEditingWorkCalendarTimes,
|
||||
operator.EnableEditingWorkPlan,
|
||||
@@ -92,6 +92,7 @@ classes = (
|
||||
operator.RemoveWorkSchedule,
|
||||
operator.RemoveWorkTime,
|
||||
operator.SelectTaskRelatedProducts,
|
||||
operator.SelectTaskRelatedInputs,
|
||||
operator.SetTaskSortColumn,
|
||||
operator.UnassignLagTime,
|
||||
operator.UnassignPredecessor,
|
||||
@@ -114,6 +115,7 @@ classes = (
|
||||
prop.BIMWorkCalendarProperties,
|
||||
prop.DatePickerProperties,
|
||||
prop.BIMDateTextProperties,
|
||||
prop.BIMDuration,
|
||||
ui.BIM_PT_work_plans,
|
||||
ui.BIM_PT_work_schedules,
|
||||
ui.BIM_PT_work_calendars,
|
||||
@@ -144,6 +146,7 @@ def register():
|
||||
bpy.types.Scene.BIMTaskTreeProperties = bpy.props.PointerProperty(type=prop.BIMTaskTreeProperties)
|
||||
bpy.types.Scene.BIMWorkCalendarProperties = bpy.props.PointerProperty(type=prop.BIMWorkCalendarProperties)
|
||||
bpy.types.Scene.DatePickerProperties = bpy.props.PointerProperty(type=prop.DatePickerProperties)
|
||||
bpy.types.Scene.BIMDuration = bpy.props.PointerProperty(type=prop.BIMDuration)
|
||||
bpy.types.TextCurve.BIMDateTextProperties = bpy.props.PointerProperty(type=prop.BIMDateTextProperties)
|
||||
bpy.types.TOPBAR_MT_file_export.append(menu_func_export)
|
||||
bpy.types.TOPBAR_MT_file_import.append(menu_func_import)
|
||||
@@ -155,6 +158,7 @@ def unregister():
|
||||
del bpy.types.Scene.BIMTaskTreeProperties
|
||||
del bpy.types.Scene.BIMWorkCalendarProperties
|
||||
del bpy.types.Scene.DatePickerProperties
|
||||
del bpy.types.Scene.BIMDuration
|
||||
del bpy.types.TextCurve.BIMDateTextProperties
|
||||
bpy.types.TOPBAR_MT_file_export.remove(menu_func_export)
|
||||
bpy.types.TOPBAR_MT_file_import.remove(menu_func_import)
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
import bpy
|
||||
import blenderbim.tool as tool
|
||||
import ifcopenshell
|
||||
|
||||
|
||||
def refresh():
|
||||
@@ -25,20 +26,193 @@ def refresh():
|
||||
|
||||
|
||||
class SequenceData:
|
||||
data = {}
|
||||
is_loaded = False
|
||||
number_of_work_plans_loaded = 0
|
||||
number_of_work_schedules_loaded = 0
|
||||
number_of_tasks_loaded = 0
|
||||
tasks = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls):
|
||||
cls.data = {
|
||||
"has_work_plans": cls.has_work_plans(),
|
||||
"has_work_schedules": cls.has_work_schedules(),
|
||||
"has_work_calendars": cls.has_work_calendars(),
|
||||
}
|
||||
cls.load_work_plans()
|
||||
cls.load_work_schedules()
|
||||
cls.load_work_calendars()
|
||||
cls.load_work_times()
|
||||
cls.load_recurrence_patterns()
|
||||
cls.load_time_periods()
|
||||
cls.load_sequences()
|
||||
cls.load_lag_times()
|
||||
cls.load_task_times()
|
||||
cls.load_tasks()
|
||||
cls.is_loaded = True
|
||||
|
||||
@classmethod
|
||||
def has_work_plans(cls):
|
||||
return bool(tool.Ifc.get().by_type("IfcWorkPlan"))
|
||||
|
||||
@classmethod
|
||||
def has_work_calendars(cls):
|
||||
return bool(tool.Ifc.get().by_type("IfcWorkCalendar"))
|
||||
|
||||
@classmethod
|
||||
def number_of_work_plans_loaded(cls):
|
||||
return len(tool.Ifc.get().by_type("IfcWorkPlan"))
|
||||
|
||||
@classmethod
|
||||
def number_of_work_schedules_loaded(cls):
|
||||
return len(tool.Ifc.get().by_type("IfcWorkSchedule"))
|
||||
|
||||
@classmethod
|
||||
def has_work_schedules(cls):
|
||||
return bool(tool.Ifc.get().by_type("IfcWorkSchedule"))
|
||||
|
||||
@classmethod
|
||||
def load_work_plans(cls):
|
||||
cls.work_plans = {}
|
||||
cls.number_of_work_plans_loaded = len(tool.Ifc.get().by_type("IfcWorkPlan"))
|
||||
cls.data["work_plans"] = {}
|
||||
for work_plan in tool.Ifc.get().by_type("IfcWorkPlan"):
|
||||
cls.work_plans[work_plan.id()] = {"Name": work_plan.Name}
|
||||
data = {"Name": work_plan.Name}
|
||||
data["IsDecomposedBy"] = []
|
||||
for rel in work_plan.IsDecomposedBy:
|
||||
data["IsDecomposedBy"].extend([o.id() for o in rel.RelatedObjects])
|
||||
cls.data["work_plans"][work_plan.id()] = data
|
||||
cls.data["number_of_work_plans_loaded"] = cls.number_of_work_plans_loaded()
|
||||
|
||||
@classmethod
|
||||
def load_work_schedules(cls):
|
||||
cls.data["work_schedules"] = {}
|
||||
for work_schedule in tool.Ifc.get().by_type("IfcWorkSchedule"):
|
||||
data = work_schedule.get_info()
|
||||
del data["OwnerHistory"]
|
||||
if data["Creators"]:
|
||||
data["Creators"] = [p.id() for p in data["Creators"]]
|
||||
data["CreationDate"] = (
|
||||
ifcopenshell.util.date.ifc2datetime(data["CreationDate"]) if data["CreationDate"] else ""
|
||||
)
|
||||
data["StartTime"] = ifcopenshell.util.date.ifc2datetime(data["StartTime"]) if data["StartTime"] else ""
|
||||
data["FinishTime"] = ifcopenshell.util.date.ifc2datetime(data["FinishTime"]) if data["FinishTime"] else ""
|
||||
data["RelatedObjects"] = []
|
||||
for rel in work_schedule.Controls:
|
||||
for obj in rel.RelatedObjects:
|
||||
if obj.is_a("IfcTask"):
|
||||
data["RelatedObjects"].append(obj.id())
|
||||
cls.data["work_schedules"][work_schedule.id()] = data
|
||||
|
||||
cls.data["number_of_work_schedules_loaded"] = cls.number_of_work_schedules_loaded()
|
||||
|
||||
@classmethod
|
||||
def load_work_calendars(cls):
|
||||
cls.data["work_calendars"] = {}
|
||||
for work_calendar in tool.Ifc.get().by_type("IfcWorkCalendar"):
|
||||
data = work_calendar.get_info()
|
||||
del data["OwnerHistory"]
|
||||
data["WorkingTimes"] = [t.id() for t in work_calendar.WorkingTimes or []]
|
||||
data["ExceptionTimes"] = [t.id() for t in work_calendar.ExceptionTimes or []]
|
||||
cls.data["work_calendars"][work_calendar.id()] = data
|
||||
|
||||
cls.data["number_of_work_calendars_loaded"] = len(cls.data["work_calendars"].keys())
|
||||
|
||||
@classmethod
|
||||
def load_work_times(cls):
|
||||
cls.data["work_times"] = {}
|
||||
for work_time in tool.Ifc.get().by_type("IfcWorkTime"):
|
||||
data = work_time.get_info()
|
||||
data["Start"] = ifcopenshell.util.date.ifc2datetime(data["Start"]) if data["Start"] else None
|
||||
data["Finish"] = ifcopenshell.util.date.ifc2datetime(data["Finish"]) if data["Finish"] else None
|
||||
data["RecurrencePattern"] = work_time.RecurrencePattern.id() if work_time.RecurrencePattern else None
|
||||
cls.data["work_times"][work_time.id()] = data
|
||||
|
||||
@classmethod
|
||||
def load_recurrence_patterns(cls):
|
||||
cls.data["recurrence_patterns"] = {}
|
||||
for recurrence_pattern in tool.Ifc.get().by_type("IfcRecurrencePattern"):
|
||||
data = recurrence_pattern.get_info()
|
||||
data["TimePeriods"] = [t.id() for t in recurrence_pattern.TimePeriods or []]
|
||||
cls.data["recurrence_patterns"][recurrence_pattern.id()] = data
|
||||
|
||||
@classmethod
|
||||
def load_sequences(cls):
|
||||
cls.data["sequences"] = {}
|
||||
for sequence in tool.Ifc.get().by_type("IfcRelSequence"):
|
||||
data = sequence.get_info()
|
||||
data["RelatingProcess"] = sequence.RelatingProcess.id()
|
||||
data["RelatedProcess"] = sequence.RelatedProcess.id()
|
||||
data["TimeLag"] = sequence.TimeLag.id() if sequence.TimeLag else None
|
||||
cls.data["sequences"][sequence.id()] = data
|
||||
|
||||
@classmethod
|
||||
def load_time_periods(cls):
|
||||
cls.data["time_periods"] = {}
|
||||
for time_period in tool.Ifc.get().by_type("IfcTimePeriod"):
|
||||
cls.data["time_periods"][time_period.id()] = {
|
||||
"StartTime": ifcopenshell.util.date.ifc2datetime(time_period.StartTime),
|
||||
"EndTime": ifcopenshell.util.date.ifc2datetime(time_period.EndTime),
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def load_task_times(cls):
|
||||
cls.data["task_times"] = {}
|
||||
for task_time in tool.Ifc.get().by_type("IfcTaskTime"):
|
||||
data = task_time.get_info()
|
||||
for key, value in data.items():
|
||||
if not value:
|
||||
continue
|
||||
if "Start" in key or "Finish" in key or key == "StatusTime":
|
||||
data[key] = ifcopenshell.util.date.ifc2datetime(value)
|
||||
elif key == "ScheduleDuration":
|
||||
data[key] = ifcopenshell.util.date.ifc2datetime(value)
|
||||
cls.data["task_times"][task_time.id()] = data
|
||||
|
||||
@classmethod
|
||||
def load_lag_times(cls):
|
||||
cls.data["lag_times"] = {}
|
||||
for lag_time in tool.Ifc.get().by_type("IfcLagTime"):
|
||||
data = lag_time.get_info()
|
||||
if data["LagValue"]:
|
||||
if data["LagValue"].is_a("IfcDuration"):
|
||||
data["LagValue"] = ifcopenshell.util.date.ifc2datetime(data["LagValue"].wrappedValue)
|
||||
else:
|
||||
data["LagValue"] = float(data["LagValue"].wrappedValue)
|
||||
cls.data["lag_times"][lag_time.id()] = data
|
||||
|
||||
@classmethod
|
||||
def load_tasks(cls):
|
||||
cls.data["tasks"] = {}
|
||||
for task in tool.Ifc.get().by_type("IfcTask"):
|
||||
data = task.get_info()
|
||||
del data["OwnerHistory"]
|
||||
data["HasAssignmentsWorkCalendar"] = []
|
||||
data["RelatedObjects"] = []
|
||||
data["Inputs"] = []
|
||||
data["Controls"] = []
|
||||
data["Outputs"] = []
|
||||
data["Resources"] = []
|
||||
data["IsPredecessorTo"] = []
|
||||
data["IsSuccessorFrom"] = []
|
||||
if task.TaskTime:
|
||||
data["TaskTime"] = data["TaskTime"].id()
|
||||
for rel in task.IsNestedBy:
|
||||
[data["RelatedObjects"].append(o.id()) for o in rel.RelatedObjects if o.is_a("IfcTask")]
|
||||
data["Nests"] = [r.RelatingObject.id() for r in task.Nests or []]
|
||||
[
|
||||
data["Outputs"].append(r.RelatingProduct.id())
|
||||
for r in task.HasAssignments
|
||||
if r.is_a("IfcRelAssignsToProduct")
|
||||
]
|
||||
[
|
||||
data["Resources"].extend([o.id() for o in r.RelatedObjects if o.is_a("IfcResource")])
|
||||
for r in task.OperatesOn
|
||||
]
|
||||
[
|
||||
data["Controls"].extend([o.id() for o in r.RelatedObjects if o.is_a("IfcControl")])
|
||||
for r in task.OperatesOn
|
||||
]
|
||||
[data["Inputs"].extend([o.id() for o in r.RelatedObjects if o.is_a("IfcProduct")]) for r in task.OperatesOn]
|
||||
[data["IsPredecessorTo"].append(rel.id()) for rel in task.IsPredecessorTo or []]
|
||||
[data["IsSuccessorFrom"].append(rel.id()) for rel in task.IsSuccessorFrom or []]
|
||||
for rel in task.HasAssignments:
|
||||
if rel.is_a("IfcRelAssignsToControl") and rel.RelatingControl:
|
||||
if rel.RelatingControl.is_a("IfcWorkCalendar"):
|
||||
data["HasAssignmentsWorkCalendar"].append(rel.RelatingControl.id())
|
||||
cls.data["tasks"][task.id()] = data
|
||||
|
||||
@@ -16,38 +16,21 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import math
|
||||
import isodate
|
||||
import datetime
|
||||
from dateutil import parser
|
||||
from ifcopenshell.api.sequence.data import Data
|
||||
import ifcopenshell.util.date as ifcdateutils
|
||||
|
||||
|
||||
def derive_date(ifc_definition_id, attribute_name, date=None, is_earliest=False, is_latest=False):
|
||||
task = Data.tasks[ifc_definition_id]
|
||||
if task["TaskTime"]:
|
||||
current_date = Data.task_times[task["TaskTime"]][attribute_name]
|
||||
def derive_date(task, attribute_name, date=None, is_earliest=False, is_latest=False):
|
||||
if task.TaskTime:
|
||||
current_date = (
|
||||
ifcdateutils.ifc2datetime(getattr(task.TaskTime, attribute_name))
|
||||
if getattr(task.TaskTime, attribute_name)
|
||||
else ""
|
||||
)
|
||||
if current_date:
|
||||
return current_date
|
||||
for subtask in task["RelatedObjects"]:
|
||||
current_date = derive_date(subtask, attribute_name, date=date, is_earliest=is_earliest, is_latest=is_latest)
|
||||
if is_earliest:
|
||||
if current_date and (date is None or current_date < date):
|
||||
date = current_date
|
||||
if is_latest:
|
||||
if current_date and (date is None or current_date > date):
|
||||
date = current_date
|
||||
return date
|
||||
|
||||
|
||||
def derive_duration(ifc_definition_id, attribute_name):
|
||||
task = Data.tasks[ifc_definition_id]
|
||||
if task["TaskTime"]:
|
||||
current_date = Data.task_times[task["TaskTime"]][attribute_name]
|
||||
if current_date:
|
||||
return current_date
|
||||
for subtask in task["RelatedObjects"]:
|
||||
for subtask in get_nested_tasks(task):
|
||||
current_date = derive_date(subtask, attribute_name, date=date, is_earliest=is_earliest, is_latest=is_latest)
|
||||
if is_earliest:
|
||||
if current_date and (date is None or current_date < date):
|
||||
@@ -79,3 +62,30 @@ def canonicalise_time(time):
|
||||
if not time:
|
||||
return "-"
|
||||
return time.strftime("%d/%m/%y")
|
||||
|
||||
|
||||
def get_nested_tasks(task):
|
||||
tasks = []
|
||||
for rel in task.IsNestedBy:
|
||||
for object in rel.RelatedObjects:
|
||||
if object.is_a("IfcTask"):
|
||||
tasks.append(object)
|
||||
return tasks
|
||||
|
||||
|
||||
def get_parent_task(task):
|
||||
return task.Nests[0].RelatingObject if task.Nests and task.Nests[0].RelatingObject.is_a("IfcTask") else None
|
||||
|
||||
|
||||
def get_task_work_schedule(task):
|
||||
parent_task = get_parent_task(task)
|
||||
if parent_task:
|
||||
get_task_work_schedule(parent_task)
|
||||
else:
|
||||
schedules = [
|
||||
rel.RelatingControl
|
||||
for rel in task.HasAssignments
|
||||
if rel.is_a("IfcRelAssignsToControl") and rel.RelatingControl.is_a("IfcWorkSchedule")
|
||||
]
|
||||
print(f"Returning {schedules}")
|
||||
return schedules
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,8 +21,9 @@ import isodate
|
||||
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.module.sequence.data import SequenceData
|
||||
import blenderbim.bim.module.pset.data
|
||||
from blenderbim.bim.prop import StrProperty, Attribute
|
||||
from dateutil import parser
|
||||
from bpy.types import PropertyGroup
|
||||
@@ -78,17 +79,18 @@ def getTaskTimeColumns(self, context):
|
||||
|
||||
|
||||
def getWorkSchedules(self, context):
|
||||
return [(str(k), v["Name"], "") for k, v in Data.work_schedules.items()]
|
||||
return [(str(k), v["Name"], "") for k, v in SequenceData.data["work_schedules"].items()]
|
||||
|
||||
|
||||
def getWorkCalendars(self, context):
|
||||
return [(str(k), v["Name"], "") for k, v in Data.work_calendars.items()]
|
||||
return [(str(k), v["Name"], "") for k, v in SequenceData.data["work_calendars"].items()]
|
||||
|
||||
|
||||
def update_active_task_index(self, context):
|
||||
bpy.ops.bim.load_task_inputs()
|
||||
bpy.ops.bim.load_task_resources()
|
||||
bpy.ops.bim.load_task_outputs()
|
||||
blenderbim.bim.module.pset.data.refresh()
|
||||
|
||||
|
||||
def updateTaskName(self, context):
|
||||
@@ -101,7 +103,7 @@ def updateTaskName(self, context):
|
||||
self.file,
|
||||
**{"task": self.file.by_id(self.ifc_definition_id), "attributes": {"Name": self.name}},
|
||||
)
|
||||
Data.load(IfcStore.get_file())
|
||||
SequenceData.load()
|
||||
if props.active_task_id == self.ifc_definition_id:
|
||||
attribute = props.task_attributes.get("Name")
|
||||
attribute.string_value = self.name
|
||||
@@ -117,7 +119,7 @@ def updateTaskIdentification(self, context):
|
||||
self.file,
|
||||
**{"task": self.file.by_id(self.ifc_definition_id), "attributes": {"Identification": self.identification}},
|
||||
)
|
||||
Data.load(self.file)
|
||||
SequenceData.load()
|
||||
if props.active_task_id == self.ifc_definition_id:
|
||||
attribute = props.task_attributes.get("Identification")
|
||||
attribute.string_value = self.identification
|
||||
@@ -163,10 +165,10 @@ def updateTaskTimeDateTime(self, context, startfinish):
|
||||
task_time = task.TaskTime
|
||||
else:
|
||||
task_time = ifcopenshell.api.run("sequence.add_task_time", self.file, task=task)
|
||||
Data.load(IfcStore.get_file())
|
||||
SequenceData.load()
|
||||
|
||||
startfinish_key = "Schedule" + startfinish.capitalize()
|
||||
if Data.task_times[task_time.id()][startfinish_key] == startfinish_datetime:
|
||||
if SequenceData.data["task_times"][task_time.id()][startfinish_key] == startfinish_datetime:
|
||||
canonical_startfinish_value = canonicalise_time(startfinish_datetime)
|
||||
if startfinish_value != canonical_startfinish_value:
|
||||
setattr(self, startfinish, canonical_startfinish_value)
|
||||
@@ -177,7 +179,7 @@ def updateTaskTimeDateTime(self, context, startfinish):
|
||||
self.file,
|
||||
**{"task_time": task_time, "attributes": {startfinish_key: startfinish_datetime}},
|
||||
)
|
||||
Data.load(IfcStore.get_file())
|
||||
SequenceData.load()
|
||||
bpy.ops.bim.load_task_properties()
|
||||
|
||||
|
||||
@@ -201,13 +203,13 @@ def updateTaskDuration(self, context):
|
||||
task_time = task.TaskTime
|
||||
else:
|
||||
task_time = ifcopenshell.api.run("sequence.add_task_time", self.file, task=task)
|
||||
Data.load(IfcStore.get_file())
|
||||
SequenceData.load()
|
||||
ifcopenshell.api.run(
|
||||
"sequence.edit_task_time",
|
||||
self.file,
|
||||
**{"task_time": task_time, "attributes": {"ScheduleDuration": self.duration}},
|
||||
)
|
||||
Data.load(IfcStore.get_file())
|
||||
SequenceData.load()
|
||||
if props.active_task_id == self.ifc_definition_id:
|
||||
attribute = props.task_time_attributes.get("Duration")
|
||||
if attribute:
|
||||
@@ -285,6 +287,7 @@ class BIMWorkPlanProperties(PropertyGroup):
|
||||
active_work_plan_index: IntProperty(name="Active Work Plan Index")
|
||||
active_work_plan_id: IntProperty(name="Active Work Plan Id")
|
||||
work_schedules: EnumProperty(items=getWorkSchedules, name="Work Schedules")
|
||||
show_work_plan_hints: BoolProperty(name="Show Hints", default=False)
|
||||
|
||||
|
||||
class BIMWorkScheduleProperties(PropertyGroup):
|
||||
@@ -326,7 +329,7 @@ class BIMWorkScheduleProperties(PropertyGroup):
|
||||
editing_sequence_type: StringProperty(name="Editing Sequence Type")
|
||||
active_sequence_id: IntProperty(name="Active Sequence Id")
|
||||
sequence_attributes: CollectionProperty(name="Sequence Attributes", type=Attribute)
|
||||
time_lag_attributes: CollectionProperty(name="Time Lag Attributes", type=Attribute)
|
||||
lag_time_attributes: CollectionProperty(name="Time Lag Attributes", type=Attribute)
|
||||
visualisation_start: StringProperty(name="Visualisation Start", update=update_visualisation_start)
|
||||
visualisation_finish: StringProperty(name="Visualisation Finish", update=update_visualisation_finish)
|
||||
speed_multiplier: FloatProperty(name="Speed Multiplier", default=10000)
|
||||
@@ -349,6 +352,10 @@ class BIMWorkScheduleProperties(PropertyGroup):
|
||||
task_outputs: CollectionProperty(name="Task Outputs", type=TaskProduct)
|
||||
active_task_output_index: IntProperty(name="Active Task Output Index")
|
||||
|
||||
class BIMDuration(PropertyGroup):
|
||||
duration_days: IntProperty(name="Days ")
|
||||
duration_hours: IntProperty(name="Hours")
|
||||
duration_minutes: IntProperty(name="Minutes")
|
||||
|
||||
class BIMTaskTreeProperties(PropertyGroup):
|
||||
# This belongs by itself for performance reasons. https://developer.blender.org/T87737
|
||||
|
||||
@@ -21,11 +21,8 @@ import blenderbim.bim.helper
|
||||
from bpy.types import Panel, UIList
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from blenderbim.bim.helper import draw_attributes
|
||||
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 blenderbim.bim.module.sequence.data import SequenceData
|
||||
from datetime import datetime
|
||||
from ifcopenshell.api.resource.data import Data as ResourceData
|
||||
|
||||
|
||||
class BIM_PT_work_plans(Panel):
|
||||
@@ -48,13 +45,15 @@ class BIM_PT_work_plans(Panel):
|
||||
self.props = context.scene.BIMWorkPlanProperties
|
||||
|
||||
row = self.layout.row()
|
||||
row.label(
|
||||
text="{} Work Plans Found".format(SequenceData.number_of_work_plans_loaded),
|
||||
icon="TEXT",
|
||||
)
|
||||
if SequenceData.data["has_work_plans"]:
|
||||
row.label(
|
||||
text="{} Work Plans Found".format(SequenceData.data["number_of_work_plans_loaded"]),
|
||||
icon="TEXT",
|
||||
)
|
||||
else:
|
||||
row.label(text="No Work Plans found.", icon="TEXT")
|
||||
row.operator("bim.add_work_plan", icon="ADD", text="")
|
||||
|
||||
for work_plan_id, work_plan in SequenceData.work_plans.items():
|
||||
for work_plan_id, work_plan in SequenceData.data["work_plans"].items():
|
||||
self.draw_work_plan_ui(work_plan_id, work_plan)
|
||||
|
||||
def draw_work_plan_ui(self, work_plan_id, work_plan):
|
||||
@@ -62,7 +61,8 @@ class BIM_PT_work_plans(Panel):
|
||||
row.label(text=work_plan["Name"] or "Unnamed", icon="TEXT")
|
||||
|
||||
if self.props.active_work_plan_id == work_plan_id:
|
||||
row.operator("bim.edit_work_plan", text="", icon="CHECKMARK")
|
||||
if self.props.editing_type == "ATTRIBUTES":
|
||||
row.operator("bim.edit_work_plan", text="", icon="CHECKMARK")
|
||||
row.operator("bim.disable_editing_work_plan", text="", icon="CANCEL")
|
||||
elif self.props.active_work_plan_id:
|
||||
row.operator("bim.remove_work_plan", text="", icon="X").work_plan = work_plan_id
|
||||
@@ -83,19 +83,25 @@ class BIM_PT_work_plans(Panel):
|
||||
draw_attributes(self.props.work_plan_attributes, self.layout)
|
||||
|
||||
def draw_work_schedule_ui(self):
|
||||
row = self.layout.row(align=True)
|
||||
row.prop(self.props, "work_schedules", text="")
|
||||
op = row.operator("bim.assign_work_schedule", text="", icon="ADD")
|
||||
op.work_plan = self.props.active_work_plan_id
|
||||
op.work_schedule = int(self.props.work_schedules)
|
||||
if not SequenceData.is_loaded:
|
||||
SequenceData.load()
|
||||
|
||||
for work_schedule_id in Data.work_plans[self.props.active_work_plan_id]["IsDecomposedBy"]:
|
||||
work_schedule = Data.work_schedules[work_schedule_id]
|
||||
if SequenceData.data["has_work_schedules"]:
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text=work_schedule["Name"] or "Unnamed", icon="LINENUMBERS_ON")
|
||||
op = row.operator("bim.unassign_work_schedule", text="", icon="X")
|
||||
row.prop(self.props, "work_schedules", text="")
|
||||
op = row.operator("bim.assign_work_schedule", text="", icon="ADD")
|
||||
op.work_plan = self.props.active_work_plan_id
|
||||
op.work_schedule = int(self.props.work_schedules)
|
||||
for work_schedule_id in SequenceData.data["work_plans"][self.props.active_work_plan_id]["IsDecomposedBy"]:
|
||||
work_schedule = SequenceData.data["work_schedules"][work_schedule_id]
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text=work_schedule["Name"] or "Unnamed", icon="LINENUMBERS_ON")
|
||||
op = row.operator("bim.unassign_work_schedule", text="", icon="X")
|
||||
op.work_plan = self.props.active_work_plan_id
|
||||
op.work_schedule = int(self.props.work_schedules)
|
||||
else:
|
||||
row = self.layout.row()
|
||||
row.label(text="Must Create a WorkSchedule First. See Work Schedule Panel", icon="INFO")
|
||||
|
||||
|
||||
class BIM_PT_work_schedules(Panel):
|
||||
@@ -113,23 +119,29 @@ class BIM_PT_work_schedules(Panel):
|
||||
return file and hasattr(file, "schema") and file.schema != "IFC2X3"
|
||||
|
||||
def draw(self, context):
|
||||
if not SequenceData.is_loaded:
|
||||
SequenceData.load()
|
||||
self.props = context.scene.BIMWorkScheduleProperties
|
||||
self.tprops = context.scene.BIMTaskTreeProperties
|
||||
|
||||
if not Data.is_loaded:
|
||||
Data.load(IfcStore.get_file())
|
||||
|
||||
row = self.layout.row()
|
||||
row.operator("bim.add_work_schedule", icon="ADD")
|
||||
if SequenceData.data["has_work_schedules"]:
|
||||
row.label(
|
||||
text="{} Work Schedules Found".format(SequenceData.data["number_of_work_schedules_loaded"]),
|
||||
icon="TEXT",
|
||||
)
|
||||
else:
|
||||
row.label(text="No Work Schedules found.", icon="TEXT")
|
||||
row.operator("bim.add_work_schedule", text="", icon="ADD")
|
||||
|
||||
for work_schedule_id, work_schedule in Data.work_schedules.items():
|
||||
for work_schedule_id, work_schedule in SequenceData.data["work_schedules"].items():
|
||||
self.draw_work_schedule_ui(work_schedule_id, work_schedule)
|
||||
|
||||
def draw_work_schedule_ui(self, work_schedule_id, work_schedule):
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text=work_schedule["Name"] or "Unnamed", icon="LINENUMBERS_ON")
|
||||
|
||||
if self.props.active_work_schedule_id and self.props.active_work_schedule_id == work_schedule_id:
|
||||
if self.props.active_work_schedule_id == work_schedule_id:
|
||||
if self.props.editing_type == "WORK_SCHEDULE":
|
||||
row.operator("bim.edit_work_schedule", text="", icon="CHECKMARK")
|
||||
elif self.props.editing_type == "TASKS":
|
||||
@@ -139,23 +151,23 @@ class BIM_PT_work_schedules(Panel):
|
||||
row.operator("bim.recalculate_schedule", text="", icon="FILE_REFRESH").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:
|
||||
row.operator("bim.remove_work_schedule", text="", icon="X").work_schedule = work_schedule_id
|
||||
else:
|
||||
row.operator("bim.enable_editing_tasks", text="", icon="ACTION").work_schedule = work_schedule_id
|
||||
row.operator(
|
||||
"bim.enable_editing_work_schedule_tasks", text="", icon="ACTION"
|
||||
).work_schedule = work_schedule_id
|
||||
row.operator(
|
||||
"bim.enable_editing_work_schedule", text="", icon="GREASEPENCIL"
|
||||
).work_schedule = work_schedule_id
|
||||
row.operator("bim.remove_work_schedule", text="", icon="X").work_schedule = work_schedule_id
|
||||
|
||||
if self.props.active_work_schedule_id == work_schedule_id:
|
||||
if self.props.should_show_column_ui:
|
||||
self.draw_column_ui()
|
||||
if self.props.should_show_visualisation_ui:
|
||||
self.draw_visualisation_ui()
|
||||
if self.props.editing_type == "WORK_SCHEDULE":
|
||||
self.draw_editable_work_schedule_ui()
|
||||
elif self.props.editing_type == "TASKS":
|
||||
if self.props.should_show_column_ui:
|
||||
self.draw_column_ui()
|
||||
if self.props.should_show_visualisation_ui:
|
||||
self.draw_visualisation_ui()
|
||||
self.draw_editable_task_ui(work_schedule_id)
|
||||
|
||||
def draw_task_operators(self):
|
||||
@@ -250,68 +262,70 @@ class BIM_PT_work_schedules(Panel):
|
||||
self.draw_editable_task_time_attributes_ui()
|
||||
|
||||
def draw_editable_task_sequence_ui(self):
|
||||
task = Data.tasks[self.props.active_task_id]
|
||||
task = SequenceData.data["tasks"][self.props.active_task_id]
|
||||
row = self.layout.row()
|
||||
row.label(text="{} Predecessors".format(len(task["IsSuccessorFrom"])), icon="BACK")
|
||||
for sequence_id in task["IsSuccessorFrom"]:
|
||||
self.draw_editable_sequence_ui(Data.sequences[sequence_id], "RelatingProcess")
|
||||
self.draw_editable_sequence_ui(SequenceData.data["sequences"][sequence_id], "RelatingProcess")
|
||||
|
||||
row = self.layout.row()
|
||||
row.label(text="{} Successors".format(len(task["IsPredecessorTo"])), icon="FORWARD")
|
||||
for sequence_id in task["IsPredecessorTo"]:
|
||||
self.draw_editable_sequence_ui(Data.sequences[sequence_id], "RelatedProcess")
|
||||
self.draw_editable_sequence_ui(SequenceData.data["sequences"][sequence_id], "RelatedProcess")
|
||||
|
||||
def draw_editable_sequence_ui(self, sequence, process_type):
|
||||
task = Data.tasks[sequence[process_type]]
|
||||
task = SequenceData.data["tasks"][sequence[process_type]]
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text=task["Identification"] or "XXX")
|
||||
row.label(text=task["Name"] or "Unnamed")
|
||||
row.label(text=sequence["SequenceType"] or "N/A")
|
||||
if sequence["TimeLag"]:
|
||||
row.operator("bim.unassign_lag_time", text="", icon="X").sequence = sequence["id"]
|
||||
row.label(text=isodate.duration_isoformat(Data.lag_times[sequence["TimeLag"]]["LagValue"]))
|
||||
row.label(text=isodate.duration_isoformat(SequenceData.data["lag_times"][sequence["TimeLag"]]["LagValue"]))
|
||||
else:
|
||||
row.operator("bim.assign_lag_time", text="", icon="ADD").sequence = sequence["id"]
|
||||
row.label(text="N/A")
|
||||
row.operator("bim.assign_lag_time", text="Add Time Lag", icon="ADD").sequence = sequence["id"]
|
||||
if self.props.active_sequence_id == sequence["id"]:
|
||||
if self.props.editing_sequence_type == "ATTRIBUTES":
|
||||
row.operator("bim.edit_sequence_attributes", text="", icon="CHECKMARK")
|
||||
row.operator("bim.disable_editing_sequence", text="", icon="CANCEL")
|
||||
self.draw_editable_sequence_attributes_ui()
|
||||
elif self.props.editing_sequence_type == "TIME_LAG":
|
||||
op = row.operator("bim.edit_sequence_time_lag", text="", icon="CHECKMARK")
|
||||
elif self.props.editing_sequence_type == "LAG_TIME":
|
||||
op = row.operator("bim.edit_sequence_lag_time", text="", icon="CHECKMARK")
|
||||
op.lag_time = sequence["TimeLag"]
|
||||
row.operator("bim.disable_editing_sequence", text="", icon="CANCEL")
|
||||
self.draw_editable_sequence_time_lag_ui()
|
||||
self.draw_editable_sequence_lag_time_ui()
|
||||
else:
|
||||
if sequence["TimeLag"]:
|
||||
op = row.operator("bim.enable_editing_sequence_time_lag", text="", icon="CON_LOCKTRACK")
|
||||
op = row.operator("bim.enable_editing_sequence_lag_time", text="Edit Time Lag", icon="CON_LOCKTRACK")
|
||||
op.sequence = sequence["id"]
|
||||
op.lag_time = sequence["TimeLag"]
|
||||
op = row.operator("bim.enable_editing_sequence_attributes", text="", icon="GREASEPENCIL")
|
||||
op = row.operator("bim.enable_editing_sequence_attributes", text="Edit Sequence", icon="GREASEPENCIL")
|
||||
op.sequence = sequence["id"]
|
||||
|
||||
def draw_editable_sequence_attributes_ui(self):
|
||||
blenderbim.bim.helper.draw_attributes(self.props.sequence_attributes, self.layout)
|
||||
|
||||
def draw_editable_sequence_time_lag_ui(self):
|
||||
blenderbim.bim.helper.draw_attributes(self.props.time_lag_attributes, self.layout)
|
||||
def draw_editable_sequence_lag_time_ui(self):
|
||||
blenderbim.bim.helper.draw_attributes(self.props.lag_time_attributes, self.layout)
|
||||
|
||||
def draw_editable_task_calendar_ui(self):
|
||||
task = Data.tasks[self.props.active_task_id]
|
||||
task = SequenceData.data["tasks"][self.props.active_task_id]
|
||||
if task["HasAssignmentsWorkCalendar"]:
|
||||
row = self.layout.row(align=True)
|
||||
calendar = Data.work_calendars[task["HasAssignmentsWorkCalendar"][0]]
|
||||
calendar = SequenceData.data["work_calendars"][task["HasAssignmentsWorkCalendar"][0]]
|
||||
row.label(text=calendar["Name"] or "Unnamed")
|
||||
op = row.operator("bim.remove_task_calendar", text="", icon="X")
|
||||
op.work_calendar = task["HasAssignmentsWorkCalendar"][0]
|
||||
op.task = self.props.active_task_id
|
||||
else:
|
||||
elif SequenceData.data["has_work_calendars"]:
|
||||
row = self.layout.row(align=True)
|
||||
row.prop(self.props, "work_calendars", text="")
|
||||
op = row.operator("bim.edit_task_calendar", text="", icon="ADD")
|
||||
op.work_calendar = int(self.props.work_calendars)
|
||||
op.task = self.props.active_task_id
|
||||
else:
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text="Must Create a Calendar First. See Work Calendar Panel", icon="INFO")
|
||||
|
||||
def draw_editable_task_attributes_ui(self):
|
||||
blenderbim.bim.helper.draw_attributes(
|
||||
@@ -353,16 +367,22 @@ class BIM_PT_task_icom(Panel):
|
||||
|
||||
row2 = col.row(align=True)
|
||||
row2.label(text="Inputs")
|
||||
total_task_inputs = len(self.props.task_inputs)
|
||||
|
||||
if context.selected_objects:
|
||||
op = row2.operator("bim.assign_process", icon="ADD", text="")
|
||||
op.task = task.ifc_definition_id
|
||||
op.related_object_type = "PRODUCT"
|
||||
op.related_object = ""
|
||||
if total_task_inputs:
|
||||
op = row2.operator("bim.unassign_process", icon="REMOVE", text="")
|
||||
op.task = task.ifc_definition_id
|
||||
op.related_object_type = "PRODUCT"
|
||||
op.related_object = ""
|
||||
if not context.selected_objects and self.props.active_task_input_index < total_task_inputs:
|
||||
input_id = self.props.task_inputs[self.props.active_task_input_index].ifc_definition_id
|
||||
op.related_object = input_id
|
||||
|
||||
op = row2.operator("bim.select_task_related_inputs", icon="RESTRICT_SELECT_OFF", text="")
|
||||
op.task = task.ifc_definition_id
|
||||
|
||||
row2 = col.row()
|
||||
row2.template_list("BIM_UL_task_inputs", "", self.props, "task_inputs", self.props, "active_task_input_index")
|
||||
@@ -376,14 +396,17 @@ class BIM_PT_task_icom(Panel):
|
||||
op = row2.operator("bim.calculate_task_duration", text="", icon="TEMP")
|
||||
op.task = task.ifc_definition_id
|
||||
|
||||
total_resources = len(context.scene.BIMResourceTreeProperties.resources)
|
||||
resource_props = context.scene.BIMResourceProperties
|
||||
resource_tprops = context.scene.BIMResourceTreeProperties
|
||||
total_resources = len(resource_tprops.resources)
|
||||
if total_resources and context.scene.BIMResourceProperties.active_resource_index < total_resources:
|
||||
op = row2.operator("bim.assign_process", icon="ADD", text="")
|
||||
op.task = task.ifc_definition_id
|
||||
op.related_object_type = "RESOURCE"
|
||||
op.resource = context.scene.BIMResourceTreeProperties.resources[
|
||||
context.scene.BIMResourceProperties.active_resource_index
|
||||
].ifc_definition_id
|
||||
resource_id = resource_tprops.resources[resource_props.active_resource_index].ifc_definition_id
|
||||
ResourceData.load(IfcStore.get_file())
|
||||
resource = ResourceData.resources[resource_id]
|
||||
if resource["type"] != "IfcCrewResource":
|
||||
op = row2.operator("bim.assign_process", icon="ADD", text="")
|
||||
op.task = task.ifc_definition_id
|
||||
op.related_object_type = "RESOURCE"
|
||||
|
||||
total_task_resources = len(self.props.task_resources)
|
||||
if total_task_resources and self.props.active_task_resource_index < total_task_resources:
|
||||
@@ -402,14 +425,17 @@ class BIM_PT_task_icom(Panel):
|
||||
|
||||
row2 = col.row(align=True)
|
||||
row2.label(text="Outputs")
|
||||
total_task_outputs = len(self.props.task_outputs)
|
||||
|
||||
if context.selected_objects:
|
||||
op = row2.operator("bim.assign_product", icon="ADD", text="")
|
||||
op.task = task.ifc_definition_id
|
||||
op.relating_product = ""
|
||||
if total_task_outputs:
|
||||
op = row2.operator("bim.unassign_product", icon="REMOVE", text="")
|
||||
op.task = task.ifc_definition_id
|
||||
op.relating_product = ""
|
||||
if not context.selected_objects and self.props.active_task_output_index < total_task_outputs:
|
||||
output_id = self.props.task_outputs[self.props.active_task_output_index].ifc_definition_id
|
||||
op.relating_product = output_id
|
||||
|
||||
op = row2.operator("bim.select_task_related_products", icon="RESTRICT_SELECT_OFF", text="")
|
||||
op.task = task.ifc_definition_id
|
||||
@@ -558,14 +584,20 @@ class BIM_PT_work_calendars(Panel):
|
||||
return file and hasattr(file, "schema") and file.schema != "IFC2X3"
|
||||
|
||||
def draw(self, context):
|
||||
if not Data.is_loaded:
|
||||
Data.load(IfcStore.get_file())
|
||||
if not SequenceData.is_loaded:
|
||||
SequenceData.load()
|
||||
|
||||
self.props = context.scene.BIMWorkCalendarProperties
|
||||
|
||||
row = self.layout.row()
|
||||
row.operator("bim.add_work_calendar", icon="ADD")
|
||||
|
||||
for work_calendar_id, work_calendar in Data.work_calendars.items():
|
||||
if SequenceData.data["has_work_calendars"]:
|
||||
row.label(
|
||||
text="{} Work Calendars Found".format(SequenceData.data["number_of_work_calendars_loaded"]),
|
||||
icon="TEXT",
|
||||
)
|
||||
else:
|
||||
row.label(text="No Work Calendars found.", icon="TEXT")
|
||||
row.operator("bim.add_work_calendar", icon="ADD", text="")
|
||||
for work_calendar_id, work_calendar in SequenceData.data["work_calendars"].items():
|
||||
self.draw_work_calendar_ui(work_calendar_id, work_calendar)
|
||||
|
||||
def draw_work_calendar_ui(self, work_calendar_id, work_calendar):
|
||||
@@ -600,10 +632,10 @@ class BIM_PT_work_calendars(Panel):
|
||||
op.time_type = "ExceptionTimes"
|
||||
|
||||
for work_time_id in work_calendar["WorkingTimes"]:
|
||||
self.draw_work_time_ui(Data.work_times[work_time_id], time_type="WorkingTimes")
|
||||
self.draw_work_time_ui(SequenceData.data["work_times"][work_time_id], time_type="WorkingTimes")
|
||||
|
||||
for work_time_id in work_calendar["ExceptionTimes"]:
|
||||
self.draw_work_time_ui(Data.work_times[work_time_id], time_type="ExceptionTimes")
|
||||
self.draw_work_time_ui(SequenceData.data["work_times"][work_time_id], time_type="ExceptionTimes")
|
||||
|
||||
def draw_work_time_ui(self, work_time, time_type):
|
||||
row = self.layout.row(align=True)
|
||||
@@ -628,7 +660,9 @@ class BIM_PT_work_calendars(Panel):
|
||||
def draw_editable_work_time_ui(self, work_time):
|
||||
draw_attributes(self.props.work_time_attributes, self.layout)
|
||||
if work_time["RecurrencePattern"]:
|
||||
self.draw_editable_recurrence_pattern_ui(Data.recurrence_patterns[work_time["RecurrencePattern"]])
|
||||
self.draw_editable_recurrence_pattern_ui(
|
||||
SequenceData.data["recurrence_patterns"][work_time["RecurrencePattern"]]
|
||||
)
|
||||
else:
|
||||
row = self.layout.row(align=True)
|
||||
row.prop(self.props, "recurrence_types", icon="RECOVER_LAST", text="")
|
||||
@@ -650,7 +684,7 @@ class BIM_PT_work_calendars(Panel):
|
||||
op.recurrence_pattern = recurrence_pattern["id"]
|
||||
|
||||
for time_period_id in recurrence_pattern["TimePeriods"]:
|
||||
time_period = Data.time_periods[time_period_id]
|
||||
time_period = SequenceData.data["time_periods"][time_period_id]
|
||||
row = box.row(align=True)
|
||||
row.label(text="{} - {}".format(time_period["StartTime"], time_period["EndTime"]), icon="TIME")
|
||||
op = row.operator("bim.remove_time_period", text="", icon="X")
|
||||
|
||||
@@ -17,14 +17,12 @@
|
||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
def add_work_plan(ifc, sequence):
|
||||
ifc.run("sequence.add_work_plan")
|
||||
sequence.load_work_plans()
|
||||
def add_work_plan(ifc):
|
||||
return ifc.run("sequence.add_work_plan")
|
||||
|
||||
|
||||
def remove_work_plan(ifc, sequence, work_plan=None):
|
||||
def remove_work_plan(ifc, work_plan=None):
|
||||
ifc.run("sequence.remove_work_plan", work_plan=work_plan)
|
||||
sequence.load_work_plans()
|
||||
|
||||
|
||||
def enable_editing_work_plan(sequence, work_plan=None):
|
||||
@@ -36,9 +34,419 @@ def disable_editing_work_plan(sequence):
|
||||
sequence.disable_editing_work_plan()
|
||||
|
||||
|
||||
def edit_work_plan(ifc, sequence):
|
||||
work_plan = sequence.get_current_ifc_work_plan()
|
||||
def edit_work_plan(ifc, sequence, work_plan=None):
|
||||
attributes = sequence.get_work_plan_attributes()
|
||||
ifc.run("sequence.edit_work_plan", work_plan=work_plan, attributes=attributes)
|
||||
sequence.disable_editing_work_plan()
|
||||
sequence.load_work_plans()
|
||||
|
||||
|
||||
def edit_work_schedule(ifc, sequence, work_schedule=None):
|
||||
attributes = sequence.get_work_schedule_attributes()
|
||||
ifc.run("sequence.edit_work_schedule", **{"work_schedule": work_schedule, "attributes": attributes})
|
||||
sequence.disable_editing_work_schedule()
|
||||
|
||||
|
||||
def enable_editing_work_plan_schedules(sequence, work_plan=None):
|
||||
sequence.enable_editing_work_plan_schedules(work_plan)
|
||||
|
||||
|
||||
def add_work_schedule(ifc):
|
||||
return ifc.run("sequence.add_work_schedule")
|
||||
|
||||
|
||||
def remove_work_schedule(ifc, work_schedule=None):
|
||||
ifc.run("sequence.remove_work_schedule", **{"work_schedule": work_schedule})
|
||||
|
||||
|
||||
def assign_work_schedule(ifc, sequence, work_plan=None, work_schedule=None):
|
||||
if work_schedule:
|
||||
sequence.hide_work_plan_hints()
|
||||
return ifc.run("aggregate.assign_object", **{"relating_object": work_plan, "product": work_schedule})
|
||||
else:
|
||||
sequence.show_work_plan_hints()
|
||||
|
||||
|
||||
def unassign_work_schedule(ifc, work_plan=None, work_schedule=None):
|
||||
ifc.run("aggregate.unassign_object", **{"relating_object": work_plan, "product": work_schedule})
|
||||
|
||||
|
||||
def enable_editing_work_schedule(sequence, work_schedule=None):
|
||||
sequence.load_work_schedule_attributes(work_schedule)
|
||||
sequence.enable_editing_work_schedule(work_schedule)
|
||||
|
||||
|
||||
def enable_editing_work_schedule_tasks(sequence, work_schedule=None):
|
||||
sequence.enable_editing_work_schedule_tasks(work_schedule)
|
||||
sequence.create_task_tree(work_schedule)
|
||||
sequence.load_task_properties()
|
||||
|
||||
|
||||
def create_task_tree(sequence, work_schedule):
|
||||
sequence.create_task_tree(work_schedule)
|
||||
sequence.load_task_properties()
|
||||
|
||||
|
||||
def expand_task(sequence, task=None):
|
||||
sequence.expand_task(task)
|
||||
work_schedule = sequence.get_active_work_schedule()
|
||||
sequence.create_task_tree(work_schedule)
|
||||
sequence.load_task_properties()
|
||||
|
||||
|
||||
def contract_task(sequence, task=None):
|
||||
sequence.contract_task(task)
|
||||
work_schedule = sequence.get_active_work_schedule()
|
||||
sequence.create_task_tree(work_schedule)
|
||||
sequence.load_task_properties()
|
||||
|
||||
|
||||
def remove_task(ifc, sequence, task=None):
|
||||
ifc.run("sequence.remove_task", **{"task": task})
|
||||
work_schedule = sequence.get_active_work_schedule()
|
||||
sequence.create_task_tree(work_schedule)
|
||||
sequence.load_task_properties()
|
||||
|
||||
sequence.disable_selecting_deleted_task()
|
||||
|
||||
|
||||
def load_task_properties(sequence):
|
||||
sequence.load_task_properties()
|
||||
|
||||
|
||||
def disable_editing_work_schedule(sequence):
|
||||
sequence.disable_editing_work_schedule()
|
||||
|
||||
|
||||
def add_summary_task(ifc, sequence, work_schedule=None):
|
||||
ifc.run("sequence.add_task", **{"work_schedule": work_schedule})
|
||||
sequence.create_task_tree(work_schedule)
|
||||
sequence.load_task_properties()
|
||||
|
||||
|
||||
def add_task(ifc, sequence, parent_task=None):
|
||||
ifc.run("sequence.add_task", **{"parent_task": parent_task})
|
||||
work_schedule = sequence.get_active_work_schedule()
|
||||
sequence.create_task_tree(work_schedule)
|
||||
sequence.load_task_properties()
|
||||
|
||||
|
||||
def enable_editing_task(sequence, task=None):
|
||||
sequence.load_task_attributes(task)
|
||||
sequence.enable_editing_task(task)
|
||||
|
||||
|
||||
def edit_task(ifc, sequence, task=None):
|
||||
attributes = sequence.get_task_attributes()
|
||||
ifc.run("sequence.edit_task", **{"task": task, "attributes": attributes})
|
||||
sequence.load_task_properties(task=task)
|
||||
sequence.disable_editing_task()
|
||||
|
||||
|
||||
def copy_task_attribute(ifc, sequence, attribute_name=None):
|
||||
for task in sequence.get_checked_tasks():
|
||||
ifc.run(
|
||||
"sequence.edit_task",
|
||||
**{"task": task, "attributes": {attribute_name: sequence.get_task_attribute_value(attribute_name)}}
|
||||
)
|
||||
sequence.load_task_properties(task)
|
||||
|
||||
|
||||
def disable_editing_task(sequence):
|
||||
sequence.disable_editing_task()
|
||||
|
||||
|
||||
def enable_editing_task_time(ifc, sequence, task=None):
|
||||
task_time = sequence.get_task_time(task)
|
||||
if task_time is None:
|
||||
task_time = ifc.run("sequence.add_task_time", **{"task": task})
|
||||
sequence.load_task_time_attributes(task_time)
|
||||
sequence.enable_editing_task_time(task)
|
||||
|
||||
|
||||
def edit_task_time(ifc, sequence, task_time=None):
|
||||
attributes = sequence.get_task_time_attributes()
|
||||
print(task_time)
|
||||
ifc.run("sequence.edit_task_time", **{"task_time": task_time, "attributes": attributes}) # nasty loop goes on when calendar props are messed up
|
||||
task = sequence.get_active_task()
|
||||
sequence.load_task_properties(task=task)
|
||||
sequence.disable_editing_task_time()
|
||||
|
||||
|
||||
def assign_predecessor(ifc, sequence, task=None):
|
||||
predecessor_task = sequence.get_active_task()
|
||||
ifc.run("sequence.assign_sequence", **{"relating_process": task, "related_process": predecessor_task})
|
||||
sequence.load_task_properties()
|
||||
|
||||
|
||||
def unassign_predecessor(ifc, sequence, task=None):
|
||||
predecessor_task = sequence.get_active_task()
|
||||
ifc.run("sequence.unassign_sequence", **{"relating_process": task, "related_process": predecessor_task})
|
||||
sequence.load_task_properties()
|
||||
|
||||
|
||||
def assign_successor(ifc, sequence, task=None):
|
||||
successor_task = sequence.get_active_task()
|
||||
ifc.run("sequence.assign_sequence", **{"relating_process": successor_task, "related_process": task})
|
||||
sequence.load_task_properties()
|
||||
|
||||
|
||||
def unassign_successor(ifc, sequence, task=None):
|
||||
successor_task = sequence.get_active_task()
|
||||
ifc.run("sequence.unassign_sequence", **{"relating_process": successor_task, "related_process": task})
|
||||
sequence.load_task_properties()
|
||||
|
||||
|
||||
def assign_products(ifc, sequence, task=None, products=None):
|
||||
if not products:
|
||||
products = sequence.get_selected_products()
|
||||
for product in products:
|
||||
ifc.run("sequence.assign_product", **{"relating_product": product, "related_object": task})
|
||||
outputs = sequence.get_task_outputs(task)
|
||||
sequence.load_task_outputs(outputs)
|
||||
|
||||
|
||||
def unassign_products(ifc, sequence, task=None, products=None):
|
||||
if not products:
|
||||
products = sequence.get_selected_products()
|
||||
for product in products:
|
||||
ifc.run("sequence.unassign_product", **{"relating_product": product, "related_object": task})
|
||||
outputs = sequence.get_task_outputs(task)
|
||||
sequence.load_task_outputs(outputs)
|
||||
|
||||
|
||||
def assign_input_products(ifc, sequence, task=None, products=None):
|
||||
if not products:
|
||||
products = sequence.get_selected_products()
|
||||
for product in products:
|
||||
ifc.run("sequence.assign_process", **{"relating_process": task, "related_object": product})
|
||||
inputs = sequence.get_task_inputs(task)
|
||||
sequence.load_task_inputs(inputs)
|
||||
|
||||
|
||||
def unassign_input_products(ifc, sequence, task=None, products=None):
|
||||
if not products:
|
||||
products = sequence.get_selected_products()
|
||||
for product in products:
|
||||
ifc.run("sequence.unassign_process", **{"relating_process": task, "related_object": product})
|
||||
inputs = sequence.get_task_inputs(task)
|
||||
sequence.load_task_inputs(inputs)
|
||||
|
||||
|
||||
def assign_resource(ifc, sequence, task=None):
|
||||
resource = sequence.get_selected_resource()
|
||||
sub_resource = ifc.run(
|
||||
"resource.add_resource", **{"parent_resource": resource, "ifc_class": resource.is_a(), "name": resource.Name}
|
||||
)
|
||||
ifc.run("sequence.assign_process", **{"relating_process": task, "related_object": sub_resource})
|
||||
resources = sequence.get_task_resources(task)
|
||||
sequence.load_task_resources(resources)
|
||||
sequence.load_resources()
|
||||
|
||||
|
||||
def unassign_resource(ifc, sequence, task=None, resource=None):
|
||||
ifc.run("sequence.unassign_process", **{"relating_process": task, "related_object": resource})
|
||||
ifc.run("resource.remove_resource", **{"resource": resource})
|
||||
resources = sequence.get_task_resources(task)
|
||||
sequence.load_task_resources(resources)
|
||||
sequence.load_resources()
|
||||
|
||||
|
||||
def load_task_outputs(sequence):
|
||||
task = sequence.get_highlighted_task()
|
||||
outputs = sequence.get_task_outputs(task)
|
||||
sequence.load_task_outputs(outputs)
|
||||
|
||||
|
||||
def load_task_inputs(sequence):
|
||||
task = sequence.get_highlighted_task()
|
||||
inputs = sequence.get_task_inputs(task)
|
||||
sequence.load_task_inputs(inputs)
|
||||
|
||||
|
||||
def load_task_resources(sequence):
|
||||
task = sequence.get_highlighted_task()
|
||||
resources = sequence.get_task_resources(task)
|
||||
sequence.load_task_resources(resources)
|
||||
|
||||
|
||||
def remove_work_calendar(ifc, work_calendar=None):
|
||||
ifc.run("sequence.remove_work_calendar", **{"work_calendar": work_calendar})
|
||||
|
||||
|
||||
def add_work_calendar(ifc):
|
||||
return ifc.run("sequence.add_work_calendar")
|
||||
|
||||
|
||||
def edit_work_calendar(ifc, sequence, work_calendar=None):
|
||||
attributes = sequence.get_work_calendar_attributes()
|
||||
ifc.run("sequence.edit_work_calendar", **{"work_calendar": work_calendar, "attributes": attributes})
|
||||
sequence.disable_editing_work_calendar()
|
||||
sequence.load_task_properties()
|
||||
|
||||
|
||||
def enable_editing_work_calendar(sequence, work_calendar=None):
|
||||
sequence.load_work_calendar_attributes(work_calendar)
|
||||
sequence.enable_editing_work_calendar(work_calendar)
|
||||
|
||||
|
||||
def disable_editing_work_calendar(sequence):
|
||||
sequence.disable_editing_work_calendar()
|
||||
|
||||
|
||||
def enable_editing_work_calendar_times(sequence, work_calendar=None):
|
||||
sequence.enable_editing_work_calendar_times(work_calendar)
|
||||
|
||||
|
||||
def add_work_time(ifc, work_calendar=None, time_type=None):
|
||||
return ifc.run("sequence.add_work_time", **{"work_calendar": work_calendar, "time_type": time_type})
|
||||
|
||||
|
||||
def enable_editing_work_time(sequence, work_time=None):
|
||||
sequence.load_work_time_attributes(work_time)
|
||||
sequence.enable_editing_work_time(work_time)
|
||||
|
||||
|
||||
def disable_editing_work_time(sequence):
|
||||
sequence.disable_editing_work_time()
|
||||
|
||||
|
||||
def remove_work_time(ifc, work_time=None):
|
||||
ifc.run("sequence.remove_work_time", **{"work_time": work_time})
|
||||
|
||||
|
||||
def edit_work_time(ifc, sequence):
|
||||
work_time = sequence.get_active_work_time()
|
||||
ifc.run("sequence.edit_work_time", **{"work_time": work_time, "attributes": sequence.get_work_time_attributes()})
|
||||
recurrence_pattern = work_time.RecurrencePattern
|
||||
if recurrence_pattern:
|
||||
ifc.run(
|
||||
"sequence.edit_recurrence_pattern",
|
||||
**{
|
||||
"recurrence_pattern": recurrence_pattern,
|
||||
"attributes": sequence.get_recurrence_pattern_attributes(recurrence_pattern),
|
||||
}
|
||||
)
|
||||
sequence.disable_editing_work_time()
|
||||
|
||||
|
||||
def assign_recurrence_pattern(ifc, work_time=None, recurrence_type=None):
|
||||
return ifc.run("sequence.assign_recurrence_pattern", **{"parent": work_time, "recurrence_type": recurrence_type})
|
||||
|
||||
|
||||
def unassign_recurrence_pattern(ifc, recurrence_pattern=None):
|
||||
ifc.run("sequence.unassign_recurrence_pattern", **{"recurrence_pattern": recurrence_pattern})
|
||||
|
||||
|
||||
def add_time_period(ifc, sequence, recurrence_pattern=None):
|
||||
start_time, end_time = sequence.get_recurrence_pattern_times()
|
||||
ifc.run(
|
||||
"sequence.add_time_period",
|
||||
**{"recurrence_pattern": recurrence_pattern, "start_time": start_time, "end_time": end_time}
|
||||
)
|
||||
sequence.reset_time_period()
|
||||
|
||||
|
||||
def remove_time_period(ifc, time_period=None):
|
||||
ifc.run("sequence.remove_time_period", **{"time_period": time_period})
|
||||
|
||||
|
||||
def enable_editing_task_calendar(sequence, task=None):
|
||||
sequence.enable_editing_task_calendar(task)
|
||||
|
||||
|
||||
def edit_task_calendar(ifc, sequence, task=None, work_calendar=None):
|
||||
ifc.run("control.assign_control", **{"relating_control": work_calendar, "related_object": task})
|
||||
ifc.run("sequence.cascade_schedule", **{"task": task})
|
||||
sequence.load_task_properties()
|
||||
|
||||
|
||||
def remove_task_calendar(ifc, sequence, task=None, work_calendar=None):
|
||||
ifc.run("control.unassign_control", **{"relating_control": work_calendar, "related_object": task})
|
||||
ifc.run("sequence.cascade_schedule", **{"task": task})
|
||||
sequence.load_task_properties()
|
||||
|
||||
|
||||
def enable_editing_task_sequence(sequence, task=None):
|
||||
sequence.enable_editing_task_sequence(task)
|
||||
sequence.load_task_properties()
|
||||
|
||||
|
||||
def disable_editing_task_sequence(sequence, task=None):
|
||||
sequence.enable_editing_task_sequence(task)
|
||||
sequence.load_task_properties()
|
||||
|
||||
|
||||
def disable_editing_task_time(sequence):
|
||||
sequence.disable_editing_task_time()
|
||||
|
||||
|
||||
def enable_editing_sequence_attributes(sequence, rel_sequence=None):
|
||||
sequence.enable_editing_rel_sequence_attributes(rel_sequence)
|
||||
sequence.load_rel_sequence_attributes(rel_sequence)
|
||||
|
||||
|
||||
def enable_editing_sequence_lag_time(sequence, rel_sequence=None, lag_time=None):
|
||||
sequence.load_lag_time_attributes(lag_time)
|
||||
sequence.enable_editing_sequence_lag_time(rel_sequence)
|
||||
|
||||
|
||||
def unassign_lag_time(ifc, sequence, rel_sequence=None):
|
||||
ifc.run("sequence.unassign_lag_time", **{"rel_sequence": rel_sequence})
|
||||
sequence.load_task_properties()
|
||||
|
||||
|
||||
def assign_lag_time(ifc, rel_sequence=None):
|
||||
ifc.run("sequence.assign_lag_time", **{"rel_sequence": rel_sequence, "lag_value": "P1D"})
|
||||
|
||||
|
||||
def edit_sequence_attributes(ifc, sequence, rel_sequence=None):
|
||||
attributes = sequence.get_rel_sequence_attributes()
|
||||
ifc.run("sequence.edit_sequence", **{"rel_sequence": rel_sequence, "attributes": attributes})
|
||||
sequence.disable_editing_rel_sequence()
|
||||
sequence.load_task_properties()
|
||||
|
||||
|
||||
def edit_sequence_lag_time(ifc, sequence, lag_time=None):
|
||||
attributes = sequence.get_lag_time_attributes()
|
||||
ifc.run("sequence.edit_lag_time", **{"lag_time": lag_time, "attributes": attributes})
|
||||
sequence.disable_editing_rel_sequence()
|
||||
sequence.load_task_properties()
|
||||
|
||||
|
||||
def disable_editing_rel_sequence(sequence):
|
||||
sequence.disable_editing_rel_sequence()
|
||||
|
||||
|
||||
def select_task_outputs(ifc, sequence, task=None):
|
||||
outputs = sequence.get_task_outputs(task) ## should this be from the api instead ?
|
||||
sequence.select_task_products(outputs)
|
||||
|
||||
|
||||
def select_task_inputs(ifc, sequence, task=None):
|
||||
inputs = sequence.get_task_inputs(task) ## should this be from the api instead ?
|
||||
print(inputs)
|
||||
sequence.select_task_products(inputs)
|
||||
|
||||
|
||||
def recalculate_schedule(ifc, work_schedule=None):
|
||||
ifc.run("sequence.recalculate_schedule", **{"work_schedule": work_schedule})
|
||||
|
||||
|
||||
def add_task_column(sequence, column_type=None, name=None, data_type=None):
|
||||
sequence.add_task_column(column_type, name, data_type)
|
||||
|
||||
|
||||
def remove_task_column(sequence, name=None):
|
||||
sequence.remove_task_column(name)
|
||||
|
||||
|
||||
def set_task_sort_column(sequence, column=None):
|
||||
sequence.set_task_sort_column(column)
|
||||
|
||||
|
||||
def calculate_task_duration(ifc, sequence, task=None):
|
||||
ifc.run("sequence.calculate_task_duration", **{"task": task})
|
||||
work_schedule = sequence.get_active_work_schedule()
|
||||
if work_schedule:
|
||||
sequence.create_task_tree(work_schedule)
|
||||
sequence.load_task_properties()
|
||||
|
||||
@@ -423,13 +423,79 @@ class Selector:
|
||||
|
||||
@interface
|
||||
class Sequence:
|
||||
def disable_editing_work_plan(cls): pass
|
||||
def get_work_plan_attributes(cls): pass
|
||||
def load_work_plan_attributes(cls, work_plan): pass
|
||||
def get_nested_tasks(cls, task):pass
|
||||
def enable_editing_work_plan(cls, work_plan): pass
|
||||
def export_attributes(cls): pass
|
||||
def get_current_ifc_work_plan(cls): pass
|
||||
def get_ifc_work_plan_attributes(cls): pass
|
||||
def load_work_plan_attributes(cls): pass
|
||||
def load_work_plans(cls): pass
|
||||
def disable_editing_work_plan(cls): pass
|
||||
def enable_editing_work_plan_schedules(cls, work_plan): pass
|
||||
def get_work_schedule_attributes(cls): pass
|
||||
def load_work_schedule_attributes(cls, work_schedule): pass
|
||||
def enable_editing_work_schedule(cls,work_schedule): pass
|
||||
def disable_editing_work_schedule(cls): pass
|
||||
def enable_editing_work_schedule_tasks(cls, work_schedule): pass
|
||||
def create_task_tree(cls, work_schedule): pass
|
||||
def load_task_properties(cls, task): pass
|
||||
def hide_work_plan_hints(cls): pass
|
||||
def show_work_plan_hints(cls): pass
|
||||
def get_active_work_schedule_id(cls): pass
|
||||
def get_selected_resource(cls): pass
|
||||
def expand_task(cls, task): pass
|
||||
def contract_task(cls, task): pass
|
||||
def disable_work_schedule(cls): pass
|
||||
def disable_selecting_deleted_task(cls): pass
|
||||
def get_checked_tasks(cls): pass
|
||||
def get_task_attribute_value(cls, attribute_name): pass
|
||||
def get_active_task(cls): pass
|
||||
def get_task_time(cls, task): pass
|
||||
def load_task_attributes(cls, task): pass
|
||||
def get_selected_products(cls): pass
|
||||
def enable_editing_task(cls, task): pass
|
||||
def get_task_attributes(cls): pass
|
||||
def load_task_time_attributes(cls, task_time): pass
|
||||
def enable_editing_task_time(cls, task): pass
|
||||
def disable_editing_task(cls): pass
|
||||
def get_task_time_attributes(cls): pass
|
||||
def load_task_resources(cls,resources): pass
|
||||
def load_resources(cls): pass
|
||||
def get_task_inputs(cls, task): pass
|
||||
def load_task_inputs(cls, inputs): pass
|
||||
def load_task_outputs(cls, outputs): pass
|
||||
def get_highlighted_task(cls): pass
|
||||
def get_task_outputs(cls, task): pass
|
||||
def get_task_resources(cls, task):pass
|
||||
def enable_editing_work_calendar_times(cls, work_calendar): pass
|
||||
def load_work_calendar_attributes(cls, work_calendar): pass
|
||||
def enable_editing_work_calendar(cls, work_calendar): pass
|
||||
def disable_editing_work_calendar(cls): pass
|
||||
def get_work_calendar_attributes(cls): pass
|
||||
def load_work_time_attributes(cls, work_time): pass
|
||||
def enable_editing_work_time(cls, work_time): pass
|
||||
def get_work_time_attributes(cls): pass
|
||||
def get_recurrence_pattern_attributes(cls, recurrence_pattern): pass
|
||||
def disable_editing_work_time(cls): pass
|
||||
def get_recurrence_pattern_times(cls): pass
|
||||
def reset_time_period(cls): pass
|
||||
def enable_editing_task_calendar(cls, task): pass
|
||||
def enable_editing_task_sequence(cls, task): pass
|
||||
def disable_editing_task_time(cls): pass
|
||||
def load_rel_sequence_attributes(cls, rel_sequence): pass
|
||||
def enable_editing_rel_sequence_attributes(cls, rel_sequence): pass
|
||||
def load_lag_time_attributes(cls, lag_time): pass
|
||||
def enable_editing_sequence_lag_time(cls, rel_sequence): pass
|
||||
def get_rel_sequence_attributes(cls): pass
|
||||
def disable_editing_rel_sequence(cls): pass
|
||||
def get_lag_time_attributes(cls): pass
|
||||
def select_task_products(cls, products): pass
|
||||
def add_task_column(cls, column_type, name, data_type): pass
|
||||
def remove_task_column(cls, name): pass
|
||||
def set_task_sort_column(cls, column): pass
|
||||
def find_related_output_tasks(cls, column): pass
|
||||
def get_root_task(cls, task): pass
|
||||
def get_task_work_schedule(cls, task): pass
|
||||
def is_work_schedule_active(cls, work_schedule): pass
|
||||
def highlight_task(cls, task): pass
|
||||
|
||||
|
||||
|
||||
@interface
|
||||
|
||||
@@ -40,9 +40,9 @@ from blenderbim.tool.project import Project
|
||||
from blenderbim.tool.pset import Pset
|
||||
from blenderbim.tool.qto import Qto
|
||||
from blenderbim.tool.root import Root
|
||||
from blenderbim.tool.sequence import Sequence
|
||||
from blenderbim.tool.spatial import Spatial
|
||||
from blenderbim.tool.structural import Structural
|
||||
from blenderbim.tool.sequence import Sequence
|
||||
from blenderbim.tool.style import Style
|
||||
from blenderbim.tool.surveyor import Surveyor
|
||||
from blenderbim.tool.system import System
|
||||
|
||||
@@ -15,8 +15,11 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from dateutil import parser
|
||||
import bpy
|
||||
import re
|
||||
import isodate
|
||||
from datetime import datetime
|
||||
import ifcopenshell
|
||||
import json
|
||||
import blenderbim.core.tool
|
||||
@@ -26,40 +29,6 @@ import blenderbim.bim.module.sequence.helper as helper
|
||||
|
||||
|
||||
class Sequence(blenderbim.core.tool.Sequence):
|
||||
@classmethod
|
||||
def load_work_plans(cls):
|
||||
props = bpy.context.scene.BIMWorkPlanProperties
|
||||
props.work_plans.clear()
|
||||
for work_plan in tool.Ifc.get().by_type("IfcWorkPlan"):
|
||||
new = props.work_plans.add()
|
||||
new.ifc_definition_id = work_plan.id()
|
||||
new.name = work_plan.Name or "Unnamed"
|
||||
|
||||
@classmethod
|
||||
def enable_editing_work_plan(cls, work_plan):
|
||||
if work_plan:
|
||||
bpy.context.scene.BIMWorkPlanProperties.active_work_plan_id = work_plan.id()
|
||||
bpy.context.scene.BIMWorkPlanProperties.editing_type = "ATTRIBUTES"
|
||||
|
||||
@classmethod
|
||||
def disable_editing_work_plan(cls):
|
||||
bpy.context.scene.BIMWorkPlanProperties.active_work_plan_id = 0
|
||||
|
||||
@classmethod
|
||||
def get_current_ifc_work_plan(cls):
|
||||
return tool.Ifc.get().by_id(bpy.context.scene.BIMWorkPlanProperties.active_work_plan_id)
|
||||
|
||||
@classmethod
|
||||
def load_work_plan_attributes(cls, work_plan):
|
||||
def callback(name, prop, data):
|
||||
if name in ["CreationDate", "StartTime", "FinishTime"]:
|
||||
prop.string_value = "" if prop.is_null else data[name]
|
||||
return True
|
||||
|
||||
props = bpy.context.scene.BIMWorkPlanProperties
|
||||
props.work_plan_attributes.clear()
|
||||
blenderbim.bim.helper.import_attributes2(work_plan, props.work_plan_attributes, callback)
|
||||
|
||||
@classmethod
|
||||
def get_work_plan_attributes(cls):
|
||||
def callback(attributes, prop):
|
||||
@@ -78,3 +47,708 @@ class Sequence(blenderbim.core.tool.Sequence):
|
||||
|
||||
props = bpy.context.scene.BIMWorkPlanProperties
|
||||
return blenderbim.bim.helper.export_attributes(props.work_plan_attributes, callback)
|
||||
|
||||
@classmethod
|
||||
def load_work_plan_attributes(cls, work_plan):
|
||||
def callback(name, prop, data):
|
||||
if name in ["CreationDate", "StartTime", "FinishTime"]:
|
||||
prop.string_value = "" if prop.is_null else data[name]
|
||||
return True
|
||||
|
||||
props = bpy.context.scene.BIMWorkPlanProperties
|
||||
props.work_plan_attributes.clear()
|
||||
blenderbim.bim.helper.import_attributes2(work_plan, props.work_plan_attributes, callback)
|
||||
|
||||
@classmethod
|
||||
def enable_editing_work_plan(cls, work_plan):
|
||||
if work_plan:
|
||||
bpy.context.scene.BIMWorkPlanProperties.active_work_plan_id = work_plan.id()
|
||||
bpy.context.scene.BIMWorkPlanProperties.editing_type = "ATTRIBUTES"
|
||||
|
||||
@classmethod
|
||||
def disable_editing_work_plan(cls):
|
||||
bpy.context.scene.BIMWorkPlanProperties.active_work_plan_id = 0
|
||||
|
||||
@classmethod
|
||||
def enable_editing_work_plan_schedules(cls, work_plan):
|
||||
if work_plan:
|
||||
bpy.context.scene.BIMWorkPlanProperties.active_work_plan_id = work_plan.id()
|
||||
bpy.context.scene.BIMWorkPlanProperties.editing_type = "SCHEDULES"
|
||||
|
||||
@classmethod
|
||||
def get_work_schedule_attributes(cls):
|
||||
def callback(attributes, prop):
|
||||
if "Date" in prop.name or "Time" in prop.name:
|
||||
if prop.is_null:
|
||||
attributes[prop.name] = None
|
||||
return True
|
||||
attributes[prop.name] = helper.parse_datetime(prop.string_value)
|
||||
return True
|
||||
elif prop.name == "Duration" or prop.name == "TotalFloat":
|
||||
if prop.is_null:
|
||||
attributes[prop.name] = None
|
||||
return True
|
||||
attributes[prop.name] = helper.parse_duration(prop.string_value)
|
||||
return True
|
||||
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
return blenderbim.bim.helper.export_attributes(props.work_schedule_attributes, callback)
|
||||
|
||||
@classmethod
|
||||
def load_work_schedule_attributes(cls, work_schedule):
|
||||
def callback(name, prop, data):
|
||||
if name in ["CreationDate", "StartTime", "FinishTime"]:
|
||||
prop.string_value = "" if prop.is_null else data[name]
|
||||
return True
|
||||
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
props.work_schedule_attributes.clear()
|
||||
blenderbim.bim.helper.import_attributes2(work_schedule, props.work_schedule_attributes, callback)
|
||||
|
||||
@classmethod
|
||||
def enable_editing_work_schedule(cls, work_schedule):
|
||||
bpy.context.scene.BIMWorkScheduleProperties.active_work_schedule_id = work_schedule.id()
|
||||
bpy.context.scene.BIMWorkScheduleProperties.editing_type = "WORK_SCHEDULE"
|
||||
|
||||
@classmethod
|
||||
def disable_editing_work_schedule(cls):
|
||||
bpy.context.scene.BIMWorkScheduleProperties.active_work_schedule_id = 0
|
||||
|
||||
@classmethod
|
||||
def enable_editing_work_schedule_tasks(cls, work_schedule):
|
||||
if work_schedule:
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
props.active_work_schedule_id = work_schedule.id()
|
||||
props.editing_type = "TASKS"
|
||||
|
||||
@classmethod
|
||||
def create_task_tree(cls, work_schedule):
|
||||
def get_work_schedule_root_tasks(work_schedule):
|
||||
related_objects_ids = []
|
||||
if work_schedule.Controls:
|
||||
for rel in work_schedule.Controls:
|
||||
for obj in rel.RelatedObjects:
|
||||
if obj.is_a("IfcTask"):
|
||||
related_objects_ids.append(obj.id())
|
||||
return related_objects_ids
|
||||
|
||||
bpy.context.scene.BIMTaskTreeProperties.tasks.clear()
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
cls.contracted_tasks = json.loads(props.contracted_tasks)
|
||||
|
||||
related_objects_ids = get_work_schedule_root_tasks(work_schedule)
|
||||
if not related_objects_ids:
|
||||
return
|
||||
cls.sort_keys = {i: cls.get_sort_key(tool.Ifc.get().by_id(i)) for i in related_objects_ids}
|
||||
related_objects_ids = sorted(cls.sort_keys, key=cls.natural_sort_key)
|
||||
if props.is_sort_reversed:
|
||||
related_objects_ids.reverse()
|
||||
for related_object_id in related_objects_ids:
|
||||
cls.create_new_task_li(related_object_id, 0)
|
||||
|
||||
@classmethod
|
||||
def create_new_task_li(cls, related_object_id, level_index):
|
||||
task = tool.Ifc.get().by_id(related_object_id)
|
||||
new = bpy.context.scene.BIMTaskTreeProperties.tasks.add()
|
||||
new.ifc_definition_id = related_object_id
|
||||
new.is_expanded = related_object_id not in cls.contracted_tasks
|
||||
new.level_index = level_index
|
||||
if task.IsNestedBy:
|
||||
new.has_children = True
|
||||
if new.is_expanded:
|
||||
cls.sort_keys = {subtask.id(): cls.get_sort_key(subtask) for subtask in helper.get_nested_tasks(task)}
|
||||
related_object_ids = sorted(cls.sort_keys, key=cls.natural_sort_key)
|
||||
if bpy.context.scene.BIMWorkScheduleProperties.is_sort_reversed:
|
||||
related_object_ids.reverse()
|
||||
for related_object_id in related_object_ids:
|
||||
cls.create_new_task_li(related_object_id, level_index + 1)
|
||||
|
||||
@classmethod
|
||||
def natural_sort_key(cls, i, _nsre=re.compile("([0-9]+)")):
|
||||
s = cls.sort_keys[i]
|
||||
return [int(text) if text.isdigit() else text.lower() for text in _nsre.split(s)]
|
||||
|
||||
@classmethod
|
||||
def get_sort_key(cls, task):
|
||||
# Sorting only applies to actual tasks, not the WBS
|
||||
for rel in task.IsNestedBy:
|
||||
for object in rel.RelatedObjects:
|
||||
if object.is_a("IfcTask"):
|
||||
return "0000000000" + (task.Identification or "")
|
||||
if not bpy.context.scene.BIMWorkScheduleProperties.sort_column:
|
||||
return task.Identification or ""
|
||||
column_type, name = bpy.context.scene.BIMWorkScheduleProperties.sort_column.split(".")
|
||||
if column_type == "IfcTask":
|
||||
return task.Name or ""
|
||||
elif column_type == "IfcTaskTime" and task.TaskTime:
|
||||
return task.TaskTime.Name or ""
|
||||
return task.Identification or ""
|
||||
|
||||
@classmethod
|
||||
def load_task_properties(cls, task=None):
|
||||
def canonicalise_time(time):
|
||||
if not time:
|
||||
return "-"
|
||||
return time.strftime("%d/%m/%y")
|
||||
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
task_props = bpy.context.scene.BIMTaskTreeProperties
|
||||
props.is_task_update_enabled = False
|
||||
|
||||
for item in task_props.tasks:
|
||||
# if task and item.ifc_definition_id != task.id():
|
||||
# continue
|
||||
task = tool.Ifc.get().by_id(item.ifc_definition_id)
|
||||
item.name = task.Name or "Unnamed"
|
||||
item.identification = task.Identification or "XXX"
|
||||
if props.active_task_id:
|
||||
item.is_predecessor = props.active_task_id in [rel.RelatedProcess.id() for rel in task.IsPredecessorTo]
|
||||
item.is_successor = props.active_task_id in [rel.RelatingProcess.id() for rel in task.IsSuccessorFrom]
|
||||
|
||||
calendar = ifcopenshell.util.sequence.derive_calendar(task)
|
||||
if task.HasAssignments:
|
||||
for rel in task.HasAssignments:
|
||||
if rel.is_a("IfcRelAssignsToControl") and rel.RelatingControl.is_a("IfcWorkCalendar"):
|
||||
item.calendar = calendar.Name if calendar else ""
|
||||
else:
|
||||
item.calendar = ""
|
||||
item.derived_calendar = calendar.Name if calendar else ""
|
||||
|
||||
if task.TaskTime:
|
||||
task_time = task.TaskTime
|
||||
item.start = (
|
||||
canonicalise_time(ifcopenshell.util.date.ifc2datetime(task_time.ScheduleStart))
|
||||
if task_time.ScheduleStart
|
||||
else "-"
|
||||
)
|
||||
item.finish = (
|
||||
canonicalise_time(ifcopenshell.util.date.ifc2datetime(task_time.ScheduleFinish))
|
||||
if task_time.ScheduleFinish
|
||||
else "-"
|
||||
)
|
||||
item.duration = (
|
||||
isodate.duration_isoformat(ifcopenshell.util.date.ifc2datetime(task_time.ScheduleDuration))
|
||||
if task_time.ScheduleDuration
|
||||
else "-"
|
||||
)
|
||||
else:
|
||||
derived_start = helper.derive_date(task, "ScheduleStart", is_earliest=True)
|
||||
derived_finish = helper.derive_date(task, "ScheduleFinish", is_latest=True)
|
||||
item.derived_start = canonicalise_time(derived_start) if derived_start else ""
|
||||
item.derived_finish = canonicalise_time(derived_finish) if derived_finish else ""
|
||||
if derived_start and derived_finish and calendar:
|
||||
derived_duration = ifcopenshell.util.sequence.count_working_days(
|
||||
derived_start, derived_finish, calendar
|
||||
)
|
||||
item.derived_duration = f"P{derived_duration}D"
|
||||
item.start = "-"
|
||||
item.finish = "-"
|
||||
item.duration = "-"
|
||||
|
||||
bpy.context.scene.BIMWorkScheduleProperties.is_task_update_enabled = True
|
||||
|
||||
@classmethod
|
||||
def hide_work_plan_hints(cls):
|
||||
bpy.context.scene.BIMWorkPlanProperties.show_hints = False
|
||||
|
||||
@classmethod
|
||||
def show_work_plan_hints(cls):
|
||||
bpy.context.scene.BIMWorkPlanProperties.show_hints = True
|
||||
|
||||
@classmethod
|
||||
def get_active_work_schedule(cls):
|
||||
if not bpy.context.scene.BIMWorkScheduleProperties.active_work_schedule_id:
|
||||
return None
|
||||
return tool.Ifc.get().by_id(bpy.context.scene.BIMWorkScheduleProperties.active_work_schedule_id)
|
||||
|
||||
@classmethod
|
||||
def get_selected_resource(cls):
|
||||
if bpy.context.scene.BIMResourceTreeProperties.resources:
|
||||
selected_resource_id = bpy.context.scene.BIMResourceTreeProperties.resources[
|
||||
bpy.context.scene.BIMResourceProperties.active_resource_index
|
||||
].ifc_definition_id
|
||||
return tool.Ifc.get().by_id(selected_resource_id)
|
||||
|
||||
@classmethod
|
||||
def expand_task(cls, task):
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
contracted_tasks = json.loads(props.contracted_tasks)
|
||||
contracted_tasks.remove(task.id())
|
||||
props.contracted_tasks = json.dumps(contracted_tasks)
|
||||
|
||||
@classmethod
|
||||
def contract_task(cls, task):
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
contracted_tasks = json.loads(props.contracted_tasks)
|
||||
contracted_tasks.append(task.id())
|
||||
props.contracted_tasks = json.dumps(contracted_tasks)
|
||||
|
||||
@classmethod
|
||||
def disable_work_schedule(cls):
|
||||
bpy.context.scene.BIMWorkScheduleProperties.active_work_schedule_id = 0
|
||||
|
||||
@classmethod
|
||||
def disable_selecting_deleted_task(cls):
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
if props.active_task_id not in [
|
||||
task.ifc_definition_id for task in bpy.context.scene.BIMTaskTreeProperties.tasks
|
||||
]: # Task was deleted
|
||||
bpy.context.scene.BIMWorkScheduleProperties.active_task_id = 0
|
||||
bpy.context.scene.BIMWorkScheduleProperties.active_task_time_id = 0
|
||||
|
||||
@classmethod
|
||||
def get_checked_tasks(cls):
|
||||
return [
|
||||
tool.Ifc.get().by_id(task.ifc_definition_id)
|
||||
for task in bpy.context.scene.BIMTaskTreeProperties.tasks
|
||||
if task.is_selected
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def get_task_attribute_value(cls, attribute_name):
|
||||
return bpy.context.scene.BIMWorkScheduleProperties.task_attributes.get(attribute_name).get_value()
|
||||
|
||||
@classmethod
|
||||
def get_active_task(cls):
|
||||
return tool.Ifc.get().by_id(bpy.context.scene.BIMWorkScheduleProperties.active_task_id)
|
||||
|
||||
@classmethod
|
||||
def get_active_work_time(cls):
|
||||
return tool.Ifc.get().by_id(bpy.context.scene.BIMWorkCalendarProperties.active_work_time_id)
|
||||
|
||||
@classmethod
|
||||
def get_task_time(cls, task):
|
||||
return task.TaskTime if task.TaskTime else None
|
||||
|
||||
@classmethod
|
||||
def load_task_attributes(cls, task):
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
props.task_attributes.clear()
|
||||
blenderbim.bim.helper.import_attributes2(task, props.task_attributes)
|
||||
|
||||
@classmethod
|
||||
def get_selected_products(cls):
|
||||
return [
|
||||
tool.Ifc.get_entity(obj)
|
||||
for obj in bpy.context.selected_objects
|
||||
if obj.BIMObjectProperties.ifc_definition_id
|
||||
] or []
|
||||
|
||||
@classmethod
|
||||
def enable_editing_task(cls, task):
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
props.active_task_id = task.id()
|
||||
props.editing_task_type = "ATTRIBUTES"
|
||||
|
||||
@classmethod
|
||||
def get_task_attributes(cls):
|
||||
return blenderbim.bim.helper.export_attributes(bpy.context.scene.BIMWorkScheduleProperties.task_attributes)
|
||||
|
||||
@classmethod
|
||||
def load_task_time_attributes(cls, task_time):
|
||||
def callback(name, prop, data):
|
||||
if prop.data_type == "string":
|
||||
if name == "ScheduleDuration" and data[name] and isinstance(data[name], str):
|
||||
time_object = ifcopenshell.util.date.ifc2datetime(data[name])
|
||||
minutes = int(round(time_object.seconds/60 % 60))
|
||||
hours = (time_object.seconds - minutes*60)/60/60
|
||||
bpy.context.scene.BIMDuration.duration_days = int(time_object.days)
|
||||
bpy.context.scene.BIMDuration.duration_hours = round(hours)
|
||||
bpy.context.scene.BIMDuration.duration_minutes = minutes # should consider years, months and seconds.
|
||||
if isinstance(data[name], datetime):
|
||||
prop.string_value = "" if prop.is_null else data[name].isoformat()
|
||||
if name == "ScheduleDuration":
|
||||
bpy.context.scene.BIMDuration.duration_days = data[name].days
|
||||
bpy.context.scene.BIMDuration.duration_hours = round(data[name].seconds / 60 / 60)
|
||||
bpy.context.scene.BIMDuration.duration_minutes = data[name].seconds/60 % 60
|
||||
return True
|
||||
elif isinstance(data[name], isodate.Duration):
|
||||
prop.string_value = (
|
||||
"" if prop.is_null else ifcopenshell.util.date.datetime2ifc(data[name], "IfcDuration")
|
||||
)
|
||||
return True
|
||||
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
props.task_time_attributes.clear()
|
||||
blenderbim.bim.helper.import_attributes2(task_time, props.task_time_attributes, callback)
|
||||
|
||||
@classmethod
|
||||
def enable_editing_task_time(cls, task):
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
props.active_task_id = task.id()
|
||||
props.active_task_time_id = task.TaskTime.id()
|
||||
props.editing_task_type = "TASKTIME"
|
||||
|
||||
@classmethod
|
||||
def disable_editing_task(cls):
|
||||
bpy.context.scene.BIMWorkScheduleProperties.active_task_id = 0
|
||||
bpy.context.scene.BIMWorkScheduleProperties.active_task_time_id = 0
|
||||
|
||||
@classmethod
|
||||
def get_task_time_attributes(cls):
|
||||
def callback(attributes, prop):
|
||||
if "Start" in prop.name or "Finish" in prop.name or prop.name == "StatusTime":
|
||||
if prop.is_null:
|
||||
attributes[prop.name] = None
|
||||
return True
|
||||
attributes[prop.name] = helper.parse_datetime(prop.string_value)
|
||||
return True
|
||||
elif prop.name == "ScheduleDuration":
|
||||
if prop.is_null:
|
||||
return True
|
||||
# TODO make this parse PT32 as P4D
|
||||
attributes[prop.name] = helper.parse_duration(prop.string_value)
|
||||
dprops= bpy.context.scene.BIMDuration
|
||||
duration_days = dprops.duration_days if dprops.duration_days else 0
|
||||
duration_hours = dprops.duration_hours if dprops.duration_hours else 0
|
||||
duration_minutes = dprops.duration_minutes if dprops.duration_minutes else 0
|
||||
dprops.duration_days = 0
|
||||
dprops.duration_hours = 0
|
||||
dprops.duration_minutes = 0
|
||||
attributes[prop.name] = helper.parse_duration(f"P{duration_days}DT{duration_hours}H{duration_minutes}M")
|
||||
return True
|
||||
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
return blenderbim.bim.helper.export_attributes(props.task_time_attributes, callback)
|
||||
|
||||
@classmethod
|
||||
def load_task_resources(cls, resources):
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
props.task_resources.clear()
|
||||
if resources:
|
||||
for resource in resources:
|
||||
new = props.task_resources.add()
|
||||
new.ifc_definition_id = resource.id()
|
||||
new.name = resource.Name or "Unnamed"
|
||||
|
||||
@classmethod
|
||||
def load_resources(cls):
|
||||
bpy.ops.bim.load_resources() # remove and refactor
|
||||
|
||||
@classmethod
|
||||
def get_task_inputs(cls, task):
|
||||
inputs = []
|
||||
for rel in task.OperatesOn:
|
||||
for object in rel.RelatedObjects:
|
||||
if object.is_a("IfcProduct"):
|
||||
inputs.append(object)
|
||||
return inputs
|
||||
|
||||
@classmethod
|
||||
def load_task_inputs(cls, inputs):
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
props.task_inputs.clear()
|
||||
for input in inputs:
|
||||
new = props.task_inputs.add()
|
||||
new.ifc_definition_id = input.id()
|
||||
new.name = input.Name or "Unnamed"
|
||||
|
||||
@classmethod
|
||||
def load_task_outputs(cls, outputs):
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
props.task_outputs.clear()
|
||||
if outputs:
|
||||
for output in outputs:
|
||||
new = props.task_outputs.add()
|
||||
new.ifc_definition_id = output.id()
|
||||
new.name = output.Name or "Unnamed"
|
||||
|
||||
@classmethod
|
||||
def get_highlighted_task(cls):
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
task_props = bpy.context.scene.BIMTaskTreeProperties
|
||||
return tool.Ifc.get().by_id(task_props.tasks[props.active_task_index].ifc_definition_id)
|
||||
|
||||
@classmethod
|
||||
def get_task_outputs(cls, task):
|
||||
return [rel.RelatingProduct for rel in task.HasAssignments if rel.is_a("IfcRelAssignsToProduct")]
|
||||
|
||||
@classmethod
|
||||
def get_task_resources(cls, task):
|
||||
resources = []
|
||||
for rel in task.OperatesOn:
|
||||
for object in rel.RelatedObjects:
|
||||
if object.is_a("IfcResource"):
|
||||
resources.append(object)
|
||||
return resources
|
||||
|
||||
@classmethod
|
||||
def enable_editing_work_calendar_times(cls, work_calendar):
|
||||
props = bpy.context.scene.BIMWorkCalendarProperties
|
||||
props.active_work_calendar_id = work_calendar.id()
|
||||
props.editing_type = "WORKTIMES"
|
||||
|
||||
@classmethod
|
||||
def load_work_calendar_attributes(cls, work_calendar):
|
||||
props = bpy.context.scene.BIMWorkCalendarProperties
|
||||
props.work_calendar_attributes.clear()
|
||||
return blenderbim.bim.helper.import_attributes2(work_calendar, props.work_calendar_attributes)
|
||||
|
||||
@classmethod
|
||||
def enable_editing_work_calendar(cls, work_calendar):
|
||||
bpy.context.scene.BIMWorkCalendarProperties.active_work_calendar_id = work_calendar.id()
|
||||
bpy.context.scene.BIMWorkCalendarProperties.editing_type = "ATTRIBUTES"
|
||||
|
||||
@classmethod
|
||||
def disable_editing_work_calendar(cls):
|
||||
bpy.context.scene.BIMWorkCalendarProperties.active_work_calendar_id = 0
|
||||
|
||||
@classmethod
|
||||
def get_work_calendar_attributes(cls):
|
||||
return blenderbim.bim.helper.export_attributes(
|
||||
bpy.context.scene.BIMWorkCalendarProperties.work_calendar_attributes
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def load_work_time_attributes(cls, work_time):
|
||||
def callback(name, prop, data):
|
||||
if name in ["Start", "Finish"]:
|
||||
prop.string_value = "" if prop.is_null else data[name]
|
||||
return True
|
||||
|
||||
props = bpy.context.scene.BIMWorkCalendarProperties
|
||||
props.work_time_attributes.clear()
|
||||
|
||||
blenderbim.bim.helper.import_attributes2(work_time, props.work_time_attributes, callback)
|
||||
|
||||
@classmethod
|
||||
def enable_editing_work_time(cls, work_time):
|
||||
def initialise_recurrence_components(props):
|
||||
if len(props.day_components) == 0:
|
||||
for i in range(0, 31):
|
||||
new = props.day_components.add()
|
||||
new.name = str(i + 1)
|
||||
if len(props.weekday_components) == 0:
|
||||
for d in ["M", "T", "W", "T", "F", "S", "S"]:
|
||||
new = props.weekday_components.add()
|
||||
new.name = d
|
||||
if len(props.month_components) == 0:
|
||||
for m in ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]:
|
||||
new = props.month_components.add()
|
||||
new.name = m
|
||||
|
||||
def load_recurrence_pattern_data(work_time, props):
|
||||
props.position = 0
|
||||
props.interval = 0
|
||||
props.occurrences = 0
|
||||
props.start_time = ""
|
||||
props.end_time = ""
|
||||
for component in props.day_components:
|
||||
component.is_specified = False
|
||||
for component in props.weekday_components:
|
||||
component.is_specified = False
|
||||
for component in props.month_components:
|
||||
component.is_specified = False
|
||||
if not work_time.RecurrencePattern:
|
||||
return
|
||||
recurrence_pattern = work_time.RecurrencePattern
|
||||
for attribute in ["Position", "Interval", "Occurrences"]:
|
||||
if getattr(recurrence_pattern, attribute):
|
||||
setattr(props, attribute.lower(), getattr(recurrence_pattern, attribute))
|
||||
for component in recurrence_pattern.DayComponent or []:
|
||||
props.day_components[component - 1].is_specified = True
|
||||
for component in recurrence_pattern.WeekdayComponent or []:
|
||||
props.weekday_components[component - 1].is_specified = True
|
||||
for component in recurrence_pattern.MonthComponent or []:
|
||||
props.month_components[component - 1].is_specified = True
|
||||
|
||||
props = bpy.context.scene.BIMWorkCalendarProperties
|
||||
initialise_recurrence_components(props)
|
||||
load_recurrence_pattern_data(work_time, props)
|
||||
props.active_work_time_id = work_time.id()
|
||||
props.editing_type = "WORKTIMES"
|
||||
|
||||
@classmethod
|
||||
def get_work_time_attributes(cls):
|
||||
def callback(attributes, prop):
|
||||
if "Start" in prop.name or "Finish" in prop.name:
|
||||
if prop.is_null:
|
||||
attributes[prop.name] = None
|
||||
return True
|
||||
attributes[prop.name] = helper.parse_datetime(prop.string_value)
|
||||
return True
|
||||
|
||||
props = bpy.context.scene.BIMWorkCalendarProperties
|
||||
return blenderbim.bim.helper.export_attributes(props.work_time_attributes, callback)
|
||||
|
||||
@classmethod
|
||||
def get_recurrence_pattern_attributes(cls, recurrence_pattern):
|
||||
props = bpy.context.scene.BIMWorkCalendarProperties
|
||||
attributes = {
|
||||
"Interval": props.interval if props.interval > 0 else None,
|
||||
"Occurrences": props.occurrences if props.occurrences > 0 else None,
|
||||
}
|
||||
applicable_data = {
|
||||
"DAILY": ["Interval", "Occurrences"],
|
||||
"WEEKLY": ["WeekdayComponent", "Interval", "Occurrences"],
|
||||
"MONTHLY_BY_DAY_OF_MONTH": ["DayComponent", "Interval", "Occurrences"],
|
||||
"MONTHLY_BY_POSITION": ["WeekdayComponent", "Position", "Interval", "Occurrences"],
|
||||
"BY_DAY_COUNT": ["Interval", "Occurrences"],
|
||||
"BY_WEEKDAY_COUNT": ["WeekdayComponent", "Interval", "Occurrences"],
|
||||
"YEARLY_BY_DAY_OF_MONTH": ["DayComponent", "MonthComponent", "Interval", "Occurrences"],
|
||||
"YEARLY_BY_POSITION": ["WeekdayComponent", "MonthComponent", "Position", "Interval", "Occurrences"],
|
||||
}
|
||||
if "Position" in applicable_data[recurrence_pattern.RecurrenceType]:
|
||||
attributes["Position"] = props.position if props.position != 0 else None
|
||||
if "DayComponent" in applicable_data[recurrence_pattern.RecurrenceType]:
|
||||
attributes["DayComponent"] = [i + 1 for i, c in enumerate(props.day_components) if c.is_specified]
|
||||
if "WeekdayComponent" in applicable_data[recurrence_pattern.RecurrenceType]:
|
||||
attributes["WeekdayComponent"] = [i + 1 for i, c in enumerate(props.weekday_components) if c.is_specified]
|
||||
if "MonthComponent" in applicable_data[recurrence_pattern.RecurrenceType]:
|
||||
attributes["MonthComponent"] = [i + 1 for i, c in enumerate(props.month_components) if c.is_specified]
|
||||
return attributes
|
||||
|
||||
@classmethod
|
||||
def disable_editing_work_time(cls):
|
||||
bpy.context.scene.BIMWorkCalendarProperties.active_work_time_id = 0
|
||||
|
||||
@classmethod
|
||||
def get_recurrence_pattern_times(cls):
|
||||
props = bpy.context.scene.BIMWorkCalendarProperties
|
||||
try:
|
||||
start_time = parser.parse(props.start_time)
|
||||
end_time = parser.parse(props.end_time)
|
||||
return start_time, end_time
|
||||
except:
|
||||
return # improve UI / refactor to add user hints
|
||||
|
||||
@classmethod
|
||||
def reset_time_period(cls):
|
||||
bpy.context.scene.BIMWorkCalendarProperties.start_time = ""
|
||||
bpy.context.scene.BIMWorkCalendarProperties.end_time = ""
|
||||
|
||||
@classmethod
|
||||
def enable_editing_task_calendar(cls, task):
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
props.active_task_id = task.id()
|
||||
props.editing_task_type = "CALENDAR"
|
||||
|
||||
@classmethod
|
||||
def enable_editing_task_sequence(cls, task):
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
props.active_task_id = task.id()
|
||||
props.editing_task_type = "SEQUENCE"
|
||||
|
||||
@classmethod
|
||||
def disable_editing_task_time(cls):
|
||||
bpy.context.scene.BIMWorkScheduleProperties.active_task_id = 0
|
||||
bpy.context.scene.BIMWorkScheduleProperties.active_task_time_id = 0
|
||||
|
||||
@classmethod
|
||||
def load_rel_sequence_attributes(cls, rel_sequence):
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
props.sequence_attributes.clear()
|
||||
blenderbim.bim.helper.import_attributes2(rel_sequence, props.sequence_attributes)
|
||||
|
||||
@classmethod
|
||||
def enable_editing_rel_sequence_attributes(cls, rel_sequence):
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
props.active_sequence_id = rel_sequence.id()
|
||||
props.editing_sequence_type = "ATTRIBUTES"
|
||||
|
||||
|
||||
@classmethod
|
||||
def load_lag_time_attributes(cls, lag_time):
|
||||
def callback(name, prop, data):
|
||||
if name == "LagValue":
|
||||
prop = bpy.context.scene.BIMWorkScheduleProperties.lag_time_attributes.add()
|
||||
prop.name = name
|
||||
prop.is_null = data[name] is None
|
||||
prop.is_optional = False
|
||||
prop.data_type = "string"
|
||||
prop.string_value = (
|
||||
"" if prop.is_null else ifcopenshell.util.date.datetime2ifc(data[name].wrappedValue, "IfcDuration")
|
||||
)
|
||||
return True
|
||||
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
props.lag_time_attributes.clear()
|
||||
blenderbim.bim.helper.import_attributes2(lag_time, props.lag_time_attributes, callback)
|
||||
|
||||
@classmethod
|
||||
def enable_editing_sequence_lag_time(cls, rel_sequence):
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
props.active_sequence_id = rel_sequence.id()
|
||||
props.editing_sequence_type = "LAG_TIME"
|
||||
|
||||
@classmethod
|
||||
def get_rel_sequence_attributes(cls):
|
||||
return blenderbim.bim.helper.export_attributes(bpy.context.scene.BIMWorkScheduleProperties.sequence_attributes)
|
||||
|
||||
@classmethod
|
||||
def disable_editing_rel_sequence(cls):
|
||||
bpy.context.scene.BIMWorkScheduleProperties.active_sequence_id = 0
|
||||
|
||||
@classmethod
|
||||
def get_lag_time_attributes(cls):
|
||||
return blenderbim.bim.helper.export_attributes(bpy.context.scene.BIMWorkScheduleProperties.lag_time_attributes)
|
||||
|
||||
@classmethod
|
||||
def select_task_products(cls, products):
|
||||
for obj in bpy.context.visible_objects:
|
||||
obj.select_set(False)
|
||||
if obj.BIMObjectProperties.ifc_definition_id in [product.id() for product in products]:
|
||||
obj.select_set(True)
|
||||
|
||||
@classmethod
|
||||
def add_task_column(cls, column_type, name, data_type):
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
new = props.columns.add()
|
||||
new.name = f"{column_type}.{name}"
|
||||
new.data_type = data_type
|
||||
|
||||
@classmethod
|
||||
def remove_task_column(cls, name):
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
props.columns.remove(props.columns.find(name))
|
||||
|
||||
@classmethod
|
||||
def set_task_sort_column(cls, column):
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
props.sort_column = column
|
||||
|
||||
@classmethod
|
||||
def find_related_input_tasks(cls, object):
|
||||
related_tasks = []
|
||||
for assignment in object.HasAssignments:
|
||||
if assignment.is_a("IfcRelAssignsToProcess") and assignment.RelatingProcess.is_a("IfcTask"):
|
||||
related_tasks.append(assignment.RelatingProcess)
|
||||
return related_tasks
|
||||
|
||||
@classmethod
|
||||
def find_related_output_tasks(cls, object):
|
||||
related_tasks = []
|
||||
for reference in object.ReferencedBy:
|
||||
if reference.is_a("IfcRelAssignsToProduct") and reference.RelatedObjects[0].is_a("IfcTask"):
|
||||
related_tasks.append(reference.RelatedObjects[0])
|
||||
return related_tasks
|
||||
|
||||
@classmethod
|
||||
def get_root_task(cls, task):
|
||||
return (
|
||||
task
|
||||
if not task.Nests or not task.Nests[0].RelatingObject.is_a("IfcTask")
|
||||
else cls.get_root_task(task.Nests[0].RelatingObject)
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_task_work_schedule(cls, task):
|
||||
if task.HasAssignments:
|
||||
for rel in task.HasAssignments:
|
||||
if rel.is_a("IfcRelAssignsToControl") and rel.RelatingControl.is_a("IfcWorkSchedule"):
|
||||
return rel.RelatingControl
|
||||
|
||||
@classmethod
|
||||
def is_work_schedule_active(cls, work_schedule):
|
||||
return (
|
||||
True if work_schedule.id() == bpy.context.scene.BIMWorkScheduleProperties.active_work_schedule_id else False
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def highlight_task(cls, task):
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
task_props = bpy.context.scene.BIMTaskTreeProperties
|
||||
task_id = task.id()
|
||||
task_index = [task.ifc_definition_id for task in task_props.tasks].index(task_id)
|
||||
if task_index:
|
||||
props.active_task_index = task_index
|
||||
|
||||
@@ -57,7 +57,7 @@ Scenario: Enable pset editing - work schedule
|
||||
Given an empty IFC project
|
||||
And I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "{ifc}.by_type('IfcWorkSchedule')[0].id()"
|
||||
And I press "bim.enable_editing_tasks(work_schedule={work_schedule})"
|
||||
And I press "bim.enable_editing_work_schedule_tasks(work_schedule={work_schedule})"
|
||||
And I set "scene.WorkSchedulePsetProperties.pset_name" to "Pset_WorkControlCommon"
|
||||
And I press "bim.add_pset(obj_type='WorkSchedule')"
|
||||
And the variable "pset" is "{ifc}.by_type('IfcPropertySet')[-1].id()"
|
||||
@@ -90,7 +90,7 @@ Scenario: Enable pset editing - task
|
||||
Given an empty IFC project
|
||||
And I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()"
|
||||
And I press "bim.enable_editing_tasks(work_schedule={work_schedule})"
|
||||
And I press "bim.enable_editing_work_schedule_tasks(work_schedule={work_schedule})"
|
||||
And I press "bim.add_summary_task(work_schedule={work_schedule})"
|
||||
And I set "scene.TaskPsetProperties.qto_name" to "Qto_TaskBaseQuantities"
|
||||
And I press "bim.add_qto(obj_type='Task')"
|
||||
|
||||
@@ -4,13 +4,225 @@ Feature: Sequence
|
||||
Scenario: Add work plan
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_plan"
|
||||
And the variable "work_plan" is "IfcStore.get_file().by_type('IfcWorkPlan')[0].id()"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Add Work schedule
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Remove work plan
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_plan"
|
||||
And the variable "work_plan" is "IfcStore.get_file().by_type('IfcWorkPlan')[0].id()"
|
||||
When I press "bim.remove_work_plan(work_plan={work_plan})"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Remove work schedule
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()"
|
||||
When I press "bim.remove_work_schedule(work_schedule={work_schedule})"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Enable Editing Work Plan
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_plan"
|
||||
And the variable "work_plan" is "IfcStore.get_file().by_type('IfcWorkPlan')[0].id()"
|
||||
When I press "bim.enable_editing_work_plan(work_plan={work_plan})"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Edit Work Plan
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_plan"
|
||||
And the variable "work_plan" is "IfcStore.get_file().by_type('IfcWorkPlan')[0].id()"
|
||||
And I press "bim.enable_editing_work_plan(work_plan={work_plan})"
|
||||
And I set "scene.BIMWorkPlanProperties.work_plan_attributes.get('Name').string_value" to "FooPlan"
|
||||
When I press "bim.edit_work_plan()"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Edit Work Schedule
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()"
|
||||
And I press "bim.enable_editing_work_schedule(work_schedule={work_schedule})"
|
||||
And I set "scene.BIMWorkScheduleProperties.work_schedule_attributes.get('Name').string_value" to "FooSchedule"
|
||||
When I press "bim.edit_work_schedule()"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Disable Editing Work Plan
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_plan"
|
||||
And the variable "work_plan" is "IfcStore.get_file().by_type('IfcWorkPlan')[0].id()"
|
||||
And I press "bim.enable_editing_work_plan_schedules(work_plan={work_plan})"
|
||||
When I press "bim.disable_editing_work_plan"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Assign work schedule
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()"
|
||||
When I press "bim.add_work_plan"
|
||||
And the variable "work_plan" is "IfcStore.get_file().by_type('IfcWorkPlan')[0].id()"
|
||||
And I press "bim.enable_editing_work_plan_schedules(work_plan={work_plan})"
|
||||
And I press "bim.assign_work_schedule(work_plan={work_plan}, work_schedule={work_schedule})"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Unassign work schedule
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()"
|
||||
When I press "bim.add_work_plan"
|
||||
And the variable "work_plan" is "IfcStore.get_file().by_type('IfcWorkPlan')[0].id()"
|
||||
And I press "bim.enable_editing_work_plan_schedules(work_plan={work_plan})"
|
||||
And I press "bim.assign_work_schedule(work_plan={work_plan}, work_schedule={work_schedule})"
|
||||
And I press "bim.unassign_work_schedule(work_plan={work_plan}, work_schedule={work_schedule})"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Delete assigned work schedule
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()"
|
||||
When I press "bim.add_work_plan"
|
||||
And the variable "work_plan" is "IfcStore.get_file().by_type('IfcWorkPlan')[0].id()"
|
||||
And I press "bim.enable_editing_work_plan_schedules(work_plan={work_plan})"
|
||||
And I press "bim.assign_work_schedule(work_plan={work_plan}, work_schedule={work_schedule})"
|
||||
When I press "bim.remove_work_schedule(work_schedule={work_schedule})"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Remove Assigned work schedule
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()"
|
||||
When I press "bim.add_work_plan"
|
||||
And the variable "work_plan" is "IfcStore.get_file().by_type('IfcWorkPlan')[0].id()"
|
||||
And I press "bim.enable_editing_work_plan_schedules(work_plan={work_plan})"
|
||||
When I press "bim.assign_work_schedule(work_plan={work_plan}, work_schedule={work_schedule})"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Add work calendar
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_calendar"
|
||||
And the variable "work_calendar" is "IfcStore.get_file().by_type('IfcWorkCalendar')[0].id()"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Remove work calendar
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_calendar"
|
||||
And the variable "work_calendar" is "IfcStore.get_file().by_type('IfcWorkCalendar')[0].id()"
|
||||
When I press "bim.remove_work_calendar(work_calendar={work_calendar})"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Edit work calendar attributes
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_calendar"
|
||||
And the variable "work_calendar" is "IfcStore.get_file().by_type('IfcWorkCalendar')[0].id()"
|
||||
When I press "bim.enable_editing_work_calendar(work_calendar={work_calendar})"
|
||||
And I set "scene.BIMWorkCalendarProperties.work_calendar_attributes.get('Name').string_value" to "FooCalendar"
|
||||
When I press "bim.edit_work_calendar()"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Enable editing calendar times
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_calendar"
|
||||
And the variable "work_calendar" is "IfcStore.get_file().by_type('IfcWorkCalendar')[0].id()"
|
||||
When I press "bim.enable_editing_work_calendar_times(work_calendar={work_calendar})"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Add calendar Working Time
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_calendar"
|
||||
And the variable "work_calendar" is "IfcStore.get_file().by_type('IfcWorkCalendar')[0].id()"
|
||||
When I press "bim.enable_editing_work_calendar_times(work_calendar={work_calendar})"
|
||||
When I press "bim.add_work_time(work_calendar={work_calendar}, time_type="WorkingTimes")"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Add calendar Exception Time
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_calendar"
|
||||
And the variable "work_calendar" is "IfcStore.get_file().by_type('IfcWorkCalendar')[0].id()"
|
||||
And I press "bim.enable_editing_work_calendar_times(work_calendar={work_calendar})"
|
||||
When I press "bim.add_work_time(work_calendar={work_calendar}, time_type="ExceptionTimes")"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Enable editing Working Time Attributes
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_calendar"
|
||||
And the variable "work_calendar" is "IfcStore.get_file().by_type('IfcWorkCalendar')[0].id()"
|
||||
When I press "bim.enable_editing_work_calendar_times(work_calendar={work_calendar})"
|
||||
When I press "bim.add_work_time(work_calendar={work_calendar}, time_type="WorkingTimes")"
|
||||
And the variable "work_time" is "IfcStore.get_file().by_type('IfcWorkTime')[0].id()"
|
||||
When I press "bim.enable_editing_work_time(work_time={work_time})"
|
||||
|
||||
Scenario: Edit Working Time Start and End Period
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_calendar"
|
||||
And the variable "work_calendar" is "IfcStore.get_file().by_type('IfcWorkCalendar')[0].id()"
|
||||
When I press "bim.enable_editing_work_calendar_times(work_calendar={work_calendar})"
|
||||
When I press "bim.add_work_time(work_calendar={work_calendar}, time_type='WorkingTimes')"
|
||||
And the variable "work_time" is "IfcStore.get_file().by_type('IfcWorkTime')[0].id()"
|
||||
When I press "bim.enable_editing_work_time(work_time={work_time})"
|
||||
And I set "scene.BIMWorkCalendarProperties.work_time_attributes.get('Start').string_value" to "2021-01-01"
|
||||
And I set "scene.BIMWorkCalendarProperties.work_time_attributes.get('Finish').string_value" to "2022-01-01"
|
||||
When I press "bim.edit_work_time()"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Add Working Time Period
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_calendar"
|
||||
And the variable "work_calendar" is "IfcStore.get_file().by_type('IfcWorkCalendar')[0].id()"
|
||||
When I press "bim.enable_editing_work_calendar_times(work_calendar={work_calendar})"
|
||||
When I press "bim.add_work_time(work_calendar={work_calendar}, time_type='WorkingTimes')"
|
||||
And the variable "work_time" is "IfcStore.get_file().by_type('IfcWorkTime')[0].id()"
|
||||
When I press "bim.enable_editing_work_time(work_time={work_time})"
|
||||
When I press "bim.assign_recurrence_pattern(work_time={work_time}, recurrence_type='DAILY')"
|
||||
And the variable "recurrence_pattern" is "IfcStore.get_file().by_type('IfcRecurrencePattern')[0].id()"
|
||||
And I set "scene.BIMWorkCalendarProperties.start_time" to "9AM"
|
||||
And I set "scene.BIMWorkCalendarProperties.end_time" to "1PM"
|
||||
When I press "bim.add_time_period(recurrence_pattern={recurrence_pattern})"
|
||||
When I press "bim.edit_work_time()"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Edit Working Time start finish and time period
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_calendar"
|
||||
And the variable "work_calendar" is "IfcStore.get_file().by_type('IfcWorkCalendar')[0].id()"
|
||||
When I press "bim.enable_editing_work_calendar_times(work_calendar={work_calendar})"
|
||||
When I press "bim.add_work_time(work_calendar={work_calendar}, time_type='WorkingTimes')"
|
||||
And the variable "work_time" is "IfcStore.get_file().by_type('IfcWorkTime')[0].id()"
|
||||
When I press "bim.enable_editing_work_time(work_time={work_time})"
|
||||
And I set "scene.BIMWorkCalendarProperties.work_time_attributes.get('Start').string_value" to "2021-01-01"
|
||||
And I set "scene.BIMWorkCalendarProperties.work_time_attributes.get('Finish').string_value" to "2022-01-01"
|
||||
When I press "bim.assign_recurrence_pattern(work_time={work_time}, recurrence_type='DAILY')"
|
||||
And the variable "recurrence_pattern" is "IfcStore.get_file().by_type('IfcRecurrencePattern')[0].id()"
|
||||
And I set "scene.BIMWorkCalendarProperties.start_time" to "9AM"
|
||||
And I set "scene.BIMWorkCalendarProperties.end_time" to "1PM"
|
||||
When I press "bim.add_time_period(recurrence_pattern={recurrence_pattern})"
|
||||
When I press "bim.edit_work_time()"
|
||||
Then nothing happens
|
||||
|
||||
|
||||
Scenario: Unassign Calendar to task
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_calendar"
|
||||
And the variable "work_calendar" is "IfcStore.get_file().by_type('IfcWorkCalendar')[0].id()"
|
||||
When I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()"
|
||||
And I press "bim.enable_editing_work_schedule_tasks(work_schedule={work_schedule})"
|
||||
And I press "bim.add_summary_task(work_schedule={work_schedule})"
|
||||
And the variable "task" is "IfcStore.get_file().by_type('IfcTask')[0].id()"
|
||||
And I press "bim.enable_editing_task_calendar(task={task})"
|
||||
And I press "bim.edit_task_calendar(work_calendar={work_calendar}, task={task})"
|
||||
When I press "bim.remove_task_calendar(work_calendar={work_calendar}, task={task})"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Enable editing task
|
||||
Given an empty IFC project
|
||||
And I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()"
|
||||
And I press "bim.enable_editing_tasks(work_schedule={work_schedule})"
|
||||
And I press "bim.enable_editing_work_schedule_tasks(work_schedule={work_schedule})"
|
||||
And I press "bim.add_summary_task(work_schedule={work_schedule})"
|
||||
And the variable "task" is "IfcStore.get_file().by_type('IfcTask')[0].id()"
|
||||
When I press "bim.enable_editing_task(task={task})"
|
||||
@@ -20,7 +232,7 @@ Scenario: Copy task attribute
|
||||
Given an empty IFC project
|
||||
And I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()"
|
||||
And I press "bim.enable_editing_tasks(work_schedule={work_schedule})"
|
||||
And I press "bim.enable_editing_work_schedule_tasks(work_schedule={work_schedule})"
|
||||
And I press "bim.add_summary_task(work_schedule={work_schedule})"
|
||||
And I press "bim.add_summary_task(work_schedule={work_schedule})"
|
||||
And the variable "task" is "IfcStore.get_file().by_type('IfcTask')[0].id()"
|
||||
@@ -30,11 +242,86 @@ Scenario: Copy task attribute
|
||||
And I press "bim.copy_task_attribute(name='Description')"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Unassign task Successor
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()"
|
||||
And I press "bim.enable_editing_work_schedule_tasks(work_schedule={work_schedule})"
|
||||
When I press "bim.add_summary_task(work_schedule={work_schedule})"
|
||||
And the variable "task" is "IfcStore.get_file().by_type('IfcTask')[0].id()"
|
||||
When I press "bim.add_task(task={task})"
|
||||
And the variable "nested_task_one" is "IfcStore.get_file().by_type('IfcTask')[1].id()"
|
||||
When I press "bim.add_task(task={task})"
|
||||
And the variable "nested_task_two" is "IfcStore.get_file().by_type('IfcTask')[2].id()"
|
||||
And I press "bim.enable_editing_task(task={nested_task_one})"
|
||||
And I press "bim.assign_successor(task={nested_task_two})"
|
||||
When I press "bim.unassign_successor(task={nested_task_two})"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Edit time Lag
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()"
|
||||
And I press "bim.enable_editing_work_schedule_tasks(work_schedule={work_schedule})"
|
||||
When I press "bim.add_summary_task(work_schedule={work_schedule})"
|
||||
And the variable "task" is "IfcStore.get_file().by_type('IfcTask')[0].id()"
|
||||
When I press "bim.add_task(task={task})"
|
||||
And the variable "nested_task_one" is "IfcStore.get_file().by_type('IfcTask')[1].id()"
|
||||
When I press "bim.add_task(task={task})"
|
||||
And the variable "nested_task_two" is "IfcStore.get_file().by_type('IfcTask')[2].id()"
|
||||
And I press "bim.enable_editing_task(task={nested_task_one})"
|
||||
When I press "bim.assign_successor(task={nested_task_two})"
|
||||
And the variable "rel_sequence" is "IfcStore.get_file().by_type('IfcRelSequence')[0].id()"
|
||||
When I press "bim.assign_lag_time(sequence={rel_sequence})"
|
||||
And the variable "lag_time" is "IfcStore.get_file().by_type('IfcLagTime')[0].id()"
|
||||
And I press "bim.enable_editing_sequence_lag_time(sequence={rel_sequence}, lag_time={lag_time})"
|
||||
And I set "scene.BIMWorkScheduleProperties.lag_time_attributes.get('LagValue').string_value" to "P5D"
|
||||
When I press "bim.edit_sequence_lag_time(lag_time={lag_time})"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Unassign time Lag
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()"
|
||||
And I press "bim.enable_editing_work_schedule_tasks(work_schedule={work_schedule})"
|
||||
When I press "bim.add_summary_task(work_schedule={work_schedule})"
|
||||
And the variable "task" is "IfcStore.get_file().by_type('IfcTask')[0].id()"
|
||||
When I press "bim.add_task(task={task})"
|
||||
And the variable "nested_task_one" is "IfcStore.get_file().by_type('IfcTask')[1].id()"
|
||||
When I press "bim.add_task(task={task})"
|
||||
And the variable "nested_task_two" is "IfcStore.get_file().by_type('IfcTask')[2].id()"
|
||||
And I press "bim.enable_editing_task(task={nested_task_one})"
|
||||
When I press "bim.assign_successor(task={nested_task_two})"
|
||||
And the variable "rel_sequence" is "IfcStore.get_file().by_type('IfcRelSequence')[0].id()"
|
||||
When I press "bim.assign_lag_time(sequence={rel_sequence})"
|
||||
And the variable "lag_time" is "IfcStore.get_file().by_type('IfcLagTime')[0].id()"
|
||||
When I press "bim.unassign_lag_time(sequence={rel_sequence})"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Edit Sequence Relationship
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()"
|
||||
And I press "bim.enable_editing_work_schedule_tasks(work_schedule={work_schedule})"
|
||||
When I press "bim.add_summary_task(work_schedule={work_schedule})"
|
||||
And the variable "task" is "IfcStore.get_file().by_type('IfcTask')[0].id()"
|
||||
When I press "bim.add_task(task={task})"
|
||||
And the variable "nested_task_one" is "IfcStore.get_file().by_type('IfcTask')[1].id()"
|
||||
When I press "bim.add_task(task={task})"
|
||||
And the variable "nested_task_two" is "IfcStore.get_file().by_type('IfcTask')[2].id()"
|
||||
And I press "bim.enable_editing_task(task={nested_task_one})"
|
||||
When I press "bim.assign_successor(task={nested_task_two})"
|
||||
And the variable "rel_sequence" is "IfcStore.get_file().by_type('IfcRelSequence')[0].id()"
|
||||
And I press "bim.enable_editing_sequence_attributes(sequence={rel_sequence})"
|
||||
And I set "scene.BIMWorkScheduleProperties.sequence_attributes.get('SequenceType').enum_value" to "START_START"
|
||||
When I press "bim.edit_sequence_attributes()"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: See the current frame date as text
|
||||
Given an empty IFC project
|
||||
And I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()"
|
||||
And I press "bim.enable_editing_tasks(work_schedule={work_schedule})"
|
||||
And I press "bim.enable_editing_work_schedule_tasks(work_schedule={work_schedule})"
|
||||
And I set "scene.BIMWorkScheduleProperties.visualisation_start" to "01/01/21"
|
||||
And I set "scene.BIMWorkScheduleProperties.visualisation_finish" to "01/02/21"
|
||||
And I set "scene.BIMWorkScheduleProperties.speed_types" to "FRAME_SPEED"
|
||||
@@ -50,7 +337,7 @@ Scenario: Animate the construction of a wall
|
||||
Given an empty IFC project
|
||||
And I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()"
|
||||
And I press "bim.enable_editing_tasks(work_schedule={work_schedule})"
|
||||
And I press "bim.enable_editing_work_schedule_tasks(work_schedule={work_schedule})"
|
||||
And I press "bim.add_summary_task(work_schedule={work_schedule})"
|
||||
And the variable "task" is "IfcStore.get_file().by_type('IfcTask')[0].id()"
|
||||
And I press "bim.enable_editing_task(task={task})"
|
||||
@@ -65,7 +352,7 @@ Scenario: Animate the construction of a wall
|
||||
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
|
||||
And I press "bim.assign_class"
|
||||
And the object "IfcWall/Cube" is selected
|
||||
And I press "bim.assign_product(task={task}, relating_product='')"
|
||||
And I press "bim.assign_product(task={task})"
|
||||
And I set "scene.BIMWorkScheduleProperties.visualisation_start" to "01/01/21"
|
||||
And I set "scene.BIMWorkScheduleProperties.visualisation_finish" to "01/02/21"
|
||||
And I set "scene.BIMWorkScheduleProperties.speed_types" to "FRAME_SPEED"
|
||||
@@ -86,7 +373,7 @@ Scenario: Animate the demolition of a wall
|
||||
Given an empty IFC project
|
||||
And I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()"
|
||||
And I press "bim.enable_editing_tasks(work_schedule={work_schedule})"
|
||||
And I press "bim.enable_editing_work_schedule_tasks(work_schedule={work_schedule})"
|
||||
And I press "bim.add_summary_task(work_schedule={work_schedule})"
|
||||
And the variable "task" is "IfcStore.get_file().by_type('IfcTask')[0].id()"
|
||||
And I press "bim.enable_editing_task(task={task})"
|
||||
@@ -101,7 +388,7 @@ Scenario: Animate the demolition of a wall
|
||||
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
|
||||
And I press "bim.assign_class"
|
||||
And the object "IfcWall/Cube" is selected
|
||||
And I press "bim.assign_product(task={task}, relating_product='')"
|
||||
And I press "bim.assign_product(task={task}, relating_product=0)"
|
||||
And I set "scene.BIMWorkScheduleProperties.visualisation_start" to "01/01/21"
|
||||
And I set "scene.BIMWorkScheduleProperties.visualisation_finish" to "01/02/21"
|
||||
And I set "scene.BIMWorkScheduleProperties.speed_types" to "FRAME_SPEED"
|
||||
@@ -125,7 +412,7 @@ Scenario: Animate the operation of a wall
|
||||
Given an empty IFC project
|
||||
And I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()"
|
||||
And I press "bim.enable_editing_tasks(work_schedule={work_schedule})"
|
||||
And I press "bim.enable_editing_work_schedule_tasks(work_schedule={work_schedule})"
|
||||
And I press "bim.add_summary_task(work_schedule={work_schedule})"
|
||||
And the variable "task" is "IfcStore.get_file().by_type('IfcTask')[0].id()"
|
||||
And I press "bim.enable_editing_task(task={task})"
|
||||
@@ -140,7 +427,7 @@ Scenario: Animate the operation of a wall
|
||||
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
|
||||
And I press "bim.assign_class"
|
||||
And the object "IfcWall/Cube" is selected
|
||||
And I press "bim.assign_product(task={task}, relating_product='')"
|
||||
And I press "bim.assign_product(task={task}, relating_product=0)"
|
||||
And I set "scene.BIMWorkScheduleProperties.visualisation_start" to "01/01/21"
|
||||
And I set "scene.BIMWorkScheduleProperties.visualisation_finish" to "01/02/21"
|
||||
And I set "scene.BIMWorkScheduleProperties.speed_types" to "FRAME_SPEED"
|
||||
@@ -158,7 +445,7 @@ Scenario: Animate the movement of a wall
|
||||
Given an empty IFC project
|
||||
And I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()"
|
||||
And I press "bim.enable_editing_tasks(work_schedule={work_schedule})"
|
||||
And I press "bim.enable_editing_work_schedule_tasks(work_schedule={work_schedule})"
|
||||
And I press "bim.add_summary_task(work_schedule={work_schedule})"
|
||||
And the variable "task" is "IfcStore.get_file().by_type('IfcTask')[0].id()"
|
||||
And I press "bim.enable_editing_task(task={task})"
|
||||
@@ -174,13 +461,13 @@ Scenario: Animate the movement of a wall
|
||||
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
|
||||
And I press "bim.assign_class"
|
||||
And the object "IfcWall/ToObject" is selected
|
||||
And I press "bim.assign_product(task={task}, relating_product='')"
|
||||
And I press "bim.assign_product(task={task}, relating_product=0)"
|
||||
When I add a cube
|
||||
And I rename the object "Cube" to "FromObject"
|
||||
And the object "FromObject" is selected
|
||||
And I press "bim.assign_class"
|
||||
And the object "IfcWall/FromObject" is selected
|
||||
And I press "bim.assign_process(task={task}, related_object_type='PRODUCT', related_object='')"
|
||||
And I press "bim.assign_process(task={task}, related_object_type='PRODUCT', related_object=0)"
|
||||
And I set "scene.BIMWorkScheduleProperties.visualisation_start" to "01/01/21"
|
||||
And I set "scene.BIMWorkScheduleProperties.visualisation_finish" to "01/02/21"
|
||||
And I set "scene.BIMWorkScheduleProperties.speed_types" to "FRAME_SPEED"
|
||||
@@ -212,7 +499,7 @@ Scenario: Animate the consumption of a wall
|
||||
Given an empty IFC project
|
||||
And I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()"
|
||||
And I press "bim.enable_editing_tasks(work_schedule={work_schedule})"
|
||||
And I press "bim.enable_editing_work_schedule_tasks(work_schedule={work_schedule})"
|
||||
And I press "bim.add_summary_task(work_schedule={work_schedule})"
|
||||
And the variable "task" is "IfcStore.get_file().by_type('IfcTask')[0].id()"
|
||||
And I press "bim.enable_editing_task_time(task={task})"
|
||||
@@ -224,7 +511,7 @@ Scenario: Animate the consumption of a wall
|
||||
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
|
||||
And I press "bim.assign_class"
|
||||
And the object "IfcWall/Cube" is selected
|
||||
And I press "bim.assign_process(task={task}, related_object_type='PRODUCT', related_object='')"
|
||||
And I press "bim.assign_process(task={task}, related_object_type='PRODUCT', related_object=0)"
|
||||
And I set "scene.BIMWorkScheduleProperties.visualisation_start" to "01/01/21"
|
||||
And I set "scene.BIMWorkScheduleProperties.visualisation_finish" to "01/02/21"
|
||||
And I set "scene.BIMWorkScheduleProperties.speed_types" to "FRAME_SPEED"
|
||||
@@ -243,3 +530,135 @@ Scenario: Animate the consumption of a wall
|
||||
Then "scene.objects.get('IfcWall/Cube').color" is "[0.0, 0.0, 0.0, 1]"
|
||||
Then "scene.objects.get('IfcWall/Cube').hide_viewport" is "True"
|
||||
Then "scene.objects.get('IfcWall/Cube').hide_render" is "True"
|
||||
|
||||
|
||||
Scenario: Generate Gantt Chart
|
||||
Given an empty IFC project
|
||||
And I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()"
|
||||
And I press "bim.enable_editing_work_schedule_tasks(work_schedule={work_schedule})"
|
||||
And I press "bim.add_summary_task(work_schedule={work_schedule})"
|
||||
And the variable "task" is "IfcStore.get_file().by_type('IfcTask')[0].id()"
|
||||
And I press "bim.enable_editing_task(task={task})"
|
||||
And I set "scene.BIMWorkScheduleProperties.task_attributes.get('PredefinedType').enum_value" to "CONSTRUCTION"
|
||||
And I press "bim.edit_task"
|
||||
And I press "bim.enable_editing_task_time(task={task})"
|
||||
And I set "scene.BIMWorkScheduleProperties.task_time_attributes.get('ScheduleStart').string_value" to "2021-01-02"
|
||||
And I set "scene.BIMWorkScheduleProperties.task_time_attributes.get('ScheduleFinish').string_value" to "2021-01-06"
|
||||
And I press "bim.edit_task_time"
|
||||
And I press "bim.generate_gantt_chart(work_schedule={work_schedule})"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Edit task with calendar
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_calendar"
|
||||
And the variable "work_calendar" is "IfcStore.get_file().by_type('IfcWorkCalendar')[0].id()"
|
||||
When I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()"
|
||||
And I press "bim.enable_editing_work_schedule_tasks(work_schedule={work_schedule})"
|
||||
And I press "bim.add_summary_task(work_schedule={work_schedule})"
|
||||
And the variable "task" is "IfcStore.get_file().by_type('IfcTask')[0].id()"
|
||||
When I press "bim.add_task(task={task})"
|
||||
And the variable "nested_task_one" is "IfcStore.get_file().by_type('IfcTask')[1].id()"
|
||||
When I press "bim.add_task(task={task})"
|
||||
And the variable "nested_task_two" is "IfcStore.get_file().by_type('IfcTask')[2].id()"
|
||||
When I press "bim.add_task(task={task})"
|
||||
And the variable "nested_task_three" is "IfcStore.get_file().by_type('IfcTask')[3].id()"
|
||||
When I press "bim.enable_editing_work_calendar_times(work_calendar={work_calendar})"
|
||||
When I press "bim.add_work_time(work_calendar={work_calendar}, time_type="WorkingTimes")"
|
||||
When I press "bim.add_work_time(work_calendar={work_calendar}, time_type="ExceptionTimes")"
|
||||
And I press "bim.disable_editing_work_calendar"
|
||||
And I press "bim.enable_editing_task_sequence(task={nested_task_one})"
|
||||
And I press "bim.assign_successor(task={nested_task_two})"
|
||||
And I press "bim.disable_editing_task"
|
||||
And I press "bim.enable_editing_task_sequence(task={nested_task_three})"
|
||||
And I press "bim.assign_predecessor(task={nested_task_two})"
|
||||
And I press "bim.disable_editing_task"
|
||||
And I press "bim.enable_editing_task_time(task={nested_task_three})"
|
||||
And I set "scene.BIMWorkScheduleProperties.task_time_attributes.get('ScheduleStart').string_value" to "2021-01-02"
|
||||
And I set "scene.BIMWorkScheduleProperties.task_time_attributes.get('ScheduleFinish').string_value" to "2021-01-06"
|
||||
And I press "bim.edit_task_time"
|
||||
And I press "bim.enable_editing_task_calendar(task={task})"
|
||||
And I press "bim.edit_task_calendar(work_calendar={work_calendar}, task={task})"
|
||||
And I press "bim.enable_editing_task_sequence(task={nested_task_one})"
|
||||
And I press "bim.disable_editing_task()"
|
||||
Then nothing happens
|
||||
|
||||
|
||||
Scenario: Assign task calendar with Working Time
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_calendar"
|
||||
And the variable "work_calendar" is "IfcStore.get_file().by_type('IfcWorkCalendar')[0].id()"
|
||||
When I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()"
|
||||
And I press "bim.enable_editing_work_schedule_tasks(work_schedule={work_schedule})"
|
||||
And I press "bim.add_summary_task(work_schedule={work_schedule})"
|
||||
And the variable "task" is "IfcStore.get_file().by_type('IfcTask')[0].id()"
|
||||
When I press "bim.add_task(task={task})"
|
||||
And the variable "nested_task_one" is "IfcStore.get_file().by_type('IfcTask')[1].id()"
|
||||
When I press "bim.add_task(task={task})"
|
||||
And the variable "nested_task_two" is "IfcStore.get_file().by_type('IfcTask')[2].id()"
|
||||
When I press "bim.add_task(task={task})"
|
||||
And the variable "nested_task_three" is "IfcStore.get_file().by_type('IfcTask')[3].id()"
|
||||
When I press "bim.enable_editing_work_calendar_times(work_calendar={work_calendar})"
|
||||
When I press "bim.add_work_time(work_calendar={work_calendar}, time_type="WorkingTimes")"
|
||||
When I press "bim.add_work_time(work_calendar={work_calendar}, time_type="ExceptionTimes")"
|
||||
And I press "bim.disable_editing_work_calendar"
|
||||
And I press "bim.enable_editing_task_sequence(task={nested_task_one})"
|
||||
And I press "bim.assign_successor(task={nested_task_two})"
|
||||
And I press "bim.disable_editing_task"
|
||||
And I press "bim.enable_editing_task_sequence(task={nested_task_three})"
|
||||
And I press "bim.assign_predecessor(task={nested_task_two})"
|
||||
And I press "bim.disable_editing_task"
|
||||
And I press "bim.enable_editing_task_calendar(task={task})"
|
||||
And I press "bim.edit_task_calendar(work_calendar={work_calendar}, task={nested_task_three})"
|
||||
And I press "bim.disable_editing_task()"
|
||||
And I press "bim.enable_editing_task_time(task={nested_task_three})"
|
||||
And I set "scene.BIMWorkScheduleProperties.task_time_attributes.get('ScheduleStart').string_value" to "2021-01-02"
|
||||
And I set "scene.BIMWorkScheduleProperties.task_time_attributes.get('ScheduleFinish').string_value" to "2021-01-06"
|
||||
# And I press "bim.edit_task_time"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Assign task calendar with no working time
|
||||
Given an empty IFC project
|
||||
When I press "bim.add_work_calendar"
|
||||
And the variable "work_calendar" is "IfcStore.get_file().by_type('IfcWorkCalendar')[0].id()"
|
||||
When I press "bim.add_work_schedule"
|
||||
And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()"
|
||||
And I press "bim.enable_editing_work_schedule_tasks(work_schedule={work_schedule})"
|
||||
And I press "bim.add_summary_task(work_schedule={work_schedule})"
|
||||
And the variable "task" is "IfcStore.get_file().by_type('IfcTask')[0].id()"
|
||||
When I press "bim.add_task(task={task})"
|
||||
And the variable "nested_task_one" is "IfcStore.get_file().by_type('IfcTask')[1].id()"
|
||||
When I press "bim.add_task(task={task})"
|
||||
And the variable "nested_task_two" is "IfcStore.get_file().by_type('IfcTask')[2].id()"
|
||||
When I press "bim.add_task(task={task})"
|
||||
And the variable "nested_task_three" is "IfcStore.get_file().by_type('IfcTask')[3].id()"
|
||||
And I press "bim.enable_editing_task_sequence(task={nested_task_one})"
|
||||
And I press "bim.assign_successor(task={nested_task_two})"
|
||||
And I press "bim.disable_editing_task"
|
||||
And I press "bim.enable_editing_task_sequence(task={nested_task_three})"
|
||||
And I press "bim.assign_predecessor(task={nested_task_two})"
|
||||
And I press "bim.disable_editing_task"
|
||||
And I press "bim.enable_editing_task_calendar(task={task})"
|
||||
And I press "bim.edit_task_calendar(work_calendar={work_calendar}, task={nested_task_three})"
|
||||
And I press "bim.disable_editing_task()"
|
||||
When I press "bim.enable_editing_work_calendar_times(work_calendar={work_calendar})"
|
||||
When I press "bim.add_work_time(work_calendar={work_calendar}, time_type="WorkingTimes")"
|
||||
And the variable "work_time" is "IfcStore.get_file().by_type('IfcWorkTime')[0].id()"
|
||||
When I press "bim.enable_editing_work_time(work_time={work_time})"
|
||||
And I set "scene.BIMWorkCalendarProperties.work_time_attributes.get('Start').string_value" to "01-08-2021"
|
||||
And I set "scene.BIMWorkCalendarProperties.work_time_attributes.get('Finish').string_value" to "01-08-2022"
|
||||
When I press "bim.assign_recurrence_pattern(work_time={work_time}, recurrence_type='DAILY')"
|
||||
And the variable "recurrence_pattern" is "IfcStore.get_file().by_type('IfcRecurrencePattern')[0].id()"
|
||||
And I set "scene.BIMWorkCalendarProperties.start_time" to "9AM"
|
||||
And I set "scene.BIMWorkCalendarProperties.end_time" to "1PM"
|
||||
When I press "bim.add_time_period(recurrence_pattern={recurrence_pattern})"
|
||||
And I press "bim.edit_work_time"
|
||||
# When I press "bim.add_work_time(work_calendar={work_calendar}, time_type="ExceptionTimes")"
|
||||
And I press "bim.disable_editing_work_calendar"
|
||||
And I press "bim.enable_editing_task_time(task={nested_task_three})"
|
||||
And I set "scene.BIMWorkScheduleProperties.task_time_attributes.get('ScheduleStart').string_value" to "2021-01-02"
|
||||
And I set "scene.BIMWorkScheduleProperties.task_time_attributes.get('ScheduleFinish').string_value" to "2021-01-06"
|
||||
And I press "bim.edit_task_time"
|
||||
Then nothing happens
|
||||
@@ -62,7 +62,7 @@ class Usecase:
|
||||
predecessor = rel.RelatingProcess
|
||||
predecessor_duration = (
|
||||
ifcopenshell.util.date.ifc2datetime(predecessor.TaskTime.ScheduleDuration)
|
||||
if predecessor.TaskTime.ScheduleDuration
|
||||
if predecessor.TaskTime and predecessor.TaskTime.ScheduleDuration
|
||||
else datetime.timedelta()
|
||||
)
|
||||
if rel.SequenceType == "FINISH_START":
|
||||
|
||||
@@ -21,7 +21,6 @@ import ifcopenshell.util.date
|
||||
|
||||
class Data:
|
||||
is_loaded = False
|
||||
work_plans = {}
|
||||
work_schedules = {}
|
||||
work_calendars = {}
|
||||
work_times = {}
|
||||
@@ -35,7 +34,6 @@ class Data:
|
||||
@classmethod
|
||||
def purge(cls):
|
||||
cls.is_loaded = False
|
||||
cls.work_plans = {}
|
||||
cls.work_schedules = {}
|
||||
cls.work_calendars = {}
|
||||
cls.work_times = {}
|
||||
@@ -51,7 +49,6 @@ class Data:
|
||||
cls._file = file
|
||||
if not cls._file:
|
||||
return
|
||||
cls.load_work_plans()
|
||||
cls.load_work_schedules()
|
||||
cls.load_work_calendars()
|
||||
cls.load_work_times()
|
||||
@@ -63,23 +60,6 @@ class Data:
|
||||
cls.load_sequences()
|
||||
cls.is_loaded = True
|
||||
|
||||
@classmethod
|
||||
def load_work_plans(cls):
|
||||
cls.work_plans = {}
|
||||
for work_plan in cls._file.by_type("IfcWorkPlan"):
|
||||
data = work_plan.get_info()
|
||||
del data["OwnerHistory"]
|
||||
if data["Creators"]:
|
||||
data["Creators"] = [p.id() for p in data["Creators"]]
|
||||
data["CreationDate"] = ifcopenshell.util.date.ifc2datetime(data["CreationDate"])
|
||||
data["StartTime"] = ifcopenshell.util.date.ifc2datetime(data["StartTime"])
|
||||
if data["FinishTime"]:
|
||||
data["FinishTime"] = ifcopenshell.util.date.ifc2datetime(data["FinishTime"])
|
||||
data["IsDecomposedBy"] = []
|
||||
for rel in work_plan.IsDecomposedBy:
|
||||
data["IsDecomposedBy"].extend([o.id() for o in rel.RelatedObjects])
|
||||
cls.work_plans[work_plan.id()] = data
|
||||
|
||||
@classmethod
|
||||
def load_work_schedules(cls):
|
||||
cls.work_schedules = {}
|
||||
|
||||
@@ -34,4 +34,11 @@ class Usecase:
|
||||
definition=self.settings["work_calendar"],
|
||||
relating_context=self.file.by_type("IfcContext")[0],
|
||||
)
|
||||
if self.settings["work_calendar"].Controls:
|
||||
for rel in self.settings["work_calendar"].Controls:
|
||||
for object in rel.RelatedObjects:
|
||||
ifcopenshell.api.run(
|
||||
"control.unassign_control",
|
||||
self.file,
|
||||
**{"relating_control": self.settings["work_calendar"], "related_object": object})
|
||||
self.file.remove(self.settings["work_calendar"])
|
||||
|
||||
Reference in New Issue
Block a user