mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 02:02:22 +00:00
Derive start and finish dates and elapsed durations where possible in the task tree
This commit is contained in:
@@ -307,12 +307,43 @@ class LoadTaskProperties(bpy.types.Operator):
|
||||
isodate.duration_isoformat(task_time["ScheduleDuration"]) if task_time["ScheduleDuration"] else "-"
|
||||
)
|
||||
else:
|
||||
derived_start = self.derive_start(item.ifc_definition_id)
|
||||
derived_finish = self.derive_finish(item.ifc_definition_id)
|
||||
item.derived_start = self.canonicalise_time(derived_start) if derived_start else ""
|
||||
item.derived_finish = self.canonicalise_time(derived_finish) if derived_finish else ""
|
||||
if derived_start and derived_finish:
|
||||
derived_duration = ifcopenshell.util.date.timedelta2duration(derived_finish - derived_start)
|
||||
item.derived_duration = isodate.duration_isoformat(derived_duration)
|
||||
item.start = "-"
|
||||
item.finish = "-"
|
||||
item.duration = "-"
|
||||
self.props.is_task_update_enabled = True
|
||||
return {"FINISHED"}
|
||||
|
||||
def derive_start(self, ifc_definition_id, start=None):
|
||||
task = Data.tasks[ifc_definition_id]
|
||||
if task["TaskTime"]:
|
||||
schedule_start = Data.task_times[task["TaskTime"]]["ScheduleStart"]
|
||||
if schedule_start:
|
||||
return schedule_start
|
||||
for subtask in task["RelatedObjects"]:
|
||||
schedule_start = self.derive_start(subtask, start)
|
||||
if schedule_start and (start is None or schedule_start < start):
|
||||
start = schedule_start
|
||||
return start
|
||||
|
||||
def derive_finish(self, ifc_definition_id, finish=None):
|
||||
task = Data.tasks[ifc_definition_id]
|
||||
if task["TaskTime"]:
|
||||
schedule_finish = Data.task_times[task["TaskTime"]]["ScheduleFinish"]
|
||||
if schedule_finish:
|
||||
return schedule_finish
|
||||
for subtask in task["RelatedObjects"]:
|
||||
schedule_finish = self.derive_finish(subtask, finish)
|
||||
if schedule_finish and (finish is None or schedule_finish > finish):
|
||||
finish = schedule_finish
|
||||
return finish
|
||||
|
||||
def canonicalise_time(self, time):
|
||||
if not time:
|
||||
return "-"
|
||||
@@ -850,7 +881,7 @@ class ImportP6(bpy.types.Operator, ImportHelper):
|
||||
p62ifc = P62Ifc()
|
||||
p62ifc.xml = self.filepath
|
||||
p62ifc.file = self.file
|
||||
p62ifc.work_plan = self.file.by_type("IfcWorkPlan")[0]
|
||||
p62ifc.work_plan = self.file.by_type("IfcWorkPlan")[0] if self.file.by_type("IfcWorkPlan") else None
|
||||
p62ifc.execute()
|
||||
Data.load(IfcStore.get_file())
|
||||
print("Import finished in {:.2f} seconds".format(time.time() - start))
|
||||
@@ -1284,7 +1315,9 @@ class UnassignLagTime(bpy.types.Operator):
|
||||
|
||||
def execute(self, context):
|
||||
self.file = IfcStore.get_file()
|
||||
ifcopenshell.api.run("sequence.unassign_lag_time", self.file, **{"rel_sequence": self.file.by_id(self.sequence)})
|
||||
ifcopenshell.api.run(
|
||||
"sequence.unassign_lag_time", self.file, **{"rel_sequence": self.file.by_id(self.sequence)}
|
||||
)
|
||||
Data.load(IfcStore.get_file())
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -1296,12 +1329,15 @@ class AssignLagTime(bpy.types.Operator):
|
||||
|
||||
def execute(self, context):
|
||||
self.file = IfcStore.get_file()
|
||||
ifcopenshell.api.run("sequence.assign_lag_time", self.file, **{"rel_sequence": self.file.by_id(self.sequence), "lag_value": "P0D"})
|
||||
ifcopenshell.api.run(
|
||||
"sequence.assign_lag_time",
|
||||
self.file,
|
||||
**{"rel_sequence": self.file.by_id(self.sequence), "lag_value": "P0D"},
|
||||
)
|
||||
Data.load(IfcStore.get_file())
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
|
||||
class EditSequenceAttributes(bpy.types.Operator):
|
||||
bl_idname = "bim.edit_sequence_attributes"
|
||||
bl_label = "Edit Sequence"
|
||||
@@ -1357,7 +1393,6 @@ class EditSequenceTimeLag(bpy.types.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
|
||||
class DisableEditingSequence(bpy.types.Operator):
|
||||
bl_idname = "bim.disable_editing_sequence"
|
||||
bl_label = "Disable Editing Sequence Attributes"
|
||||
|
||||
@@ -128,6 +128,9 @@ class Task(PropertyGroup):
|
||||
duration: StringProperty(name="Duration")
|
||||
start: StringProperty(name="Start", update=updateTaskTimeStart)
|
||||
finish: StringProperty(name="Finish", update=updateTaskTimeFinish)
|
||||
derived_start: StringProperty(name="Derived Start")
|
||||
derived_finish: StringProperty(name="Derived Finish")
|
||||
derived_duration: StringProperty(name="Derived Duration")
|
||||
is_predecessor: BoolProperty(name="Is Predecessor")
|
||||
is_successor: BoolProperty(name="Is Successor")
|
||||
|
||||
|
||||
@@ -298,9 +298,20 @@ class BIM_UL_tasks(UIList):
|
||||
row.prop(item, "name", emboss=False, text="")
|
||||
|
||||
if props.should_show_times:
|
||||
row.prop(item, "start", emboss=False, text="")
|
||||
row.prop(item, "finish", emboss=False, text="")
|
||||
row.prop(item, "duration", emboss=False, text="")
|
||||
if item.derived_start:
|
||||
row.label(text=item.derived_start + "*")
|
||||
else:
|
||||
row.prop(item, "start", emboss=False, text="")
|
||||
|
||||
if item.derived_finish:
|
||||
row.label(text=item.derived_finish + "*")
|
||||
else:
|
||||
row.prop(item, "finish", emboss=False, text="")
|
||||
|
||||
if item.derived_duration:
|
||||
row.label(text=item.derived_duration + "*")
|
||||
else:
|
||||
row.prop(item, "duration", emboss=False, text="")
|
||||
|
||||
if context.active_object:
|
||||
oprops = context.active_object.BIMObjectProperties
|
||||
|
||||
@@ -7,21 +7,25 @@ except:
|
||||
pass # Duration parsing not supported
|
||||
|
||||
|
||||
def timedelta2duration(timedelta):
|
||||
components = {
|
||||
"days": getattr(timedelta, "days", 0),
|
||||
"hours": 0,
|
||||
"minutes": 0,
|
||||
"seconds": getattr(timedelta, "seconds", 0),
|
||||
}
|
||||
if components["seconds"]:
|
||||
components["hours"], components["minutes"], components["seconds"] = [
|
||||
int(i) for i in str(datetime.timedelta(seconds=components["seconds"])).split(":")
|
||||
]
|
||||
return isodate.Duration(**components)
|
||||
|
||||
|
||||
def ifc2datetime(element):
|
||||
if isinstance(element, str) and element[0] == "P": # IfcDuration
|
||||
duration = isodate.parse_duration(element)
|
||||
if isinstance(duration, datetime.timedelta):
|
||||
components = {
|
||||
"days": getattr(duration, "days", 0),
|
||||
"hours": 0,
|
||||
"minutes": 0,
|
||||
"seconds": getattr(duration, "seconds", 0),
|
||||
}
|
||||
if components["seconds"]:
|
||||
components["hours"], components["minutes"], components["seconds"] = [
|
||||
int(i) for i in str(datetime.timedelta(seconds=components["seconds"])).split(":")
|
||||
]
|
||||
duration = isodate.Duration(**components)
|
||||
return timedelta2duration(duration)
|
||||
return duration
|
||||
elif isinstance(element, str) and element[2] == ":": # IfcTime
|
||||
return datetime.time.fromisoformat(element)
|
||||
|
||||
Reference in New Issue
Block a user