mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-18 06:21:40 +00:00
BBIM4D: Enable filtering by active work schedule when retrieve tasks related to objects
This commit is contained in:
@@ -420,6 +420,7 @@ class BIMWorkScheduleProperties(PropertyGroup):
|
|||||||
enable_reorder: BoolProperty(name="Enable Reorder", default=False)
|
enable_reorder: BoolProperty(name="Enable Reorder", default=False)
|
||||||
show_task_operators: BoolProperty(name="Show Task Options", default=True)
|
show_task_operators: BoolProperty(name="Show Task Options", default=True)
|
||||||
should_show_schedule_baseline_ui: BoolProperty(name="Baselines", default=False)
|
should_show_schedule_baseline_ui: BoolProperty(name="Baselines", default=False)
|
||||||
|
filter_by_active_schedule: BoolProperty(name="Filter By Active Schedule", default=False)
|
||||||
|
|
||||||
|
|
||||||
class BIMTaskTreeProperties(PropertyGroup):
|
class BIMTaskTreeProperties(PropertyGroup):
|
||||||
|
|||||||
@@ -977,7 +977,7 @@ class BIM_PT_4D_Tools(Panel):
|
|||||||
self.props = context.scene.BIMWorkScheduleProperties
|
self.props = context.scene.BIMWorkScheduleProperties
|
||||||
row = self.layout.row()
|
row = self.layout.row()
|
||||||
row.operator("bim.load_product_related_tasks", text="Load Tasks", icon="FILE_REFRESH")
|
row.operator("bim.load_product_related_tasks", text="Load Tasks", icon="FILE_REFRESH")
|
||||||
|
row.prop(self.props, "filter_by_active_schedule", text="Filter by Active Schedule")
|
||||||
grid = self.layout.grid_flow(columns=2, even_columns=True)
|
grid = self.layout.grid_flow(columns=2, even_columns=True)
|
||||||
col1 = grid.column()
|
col1 = grid.column()
|
||||||
col1.label(text="Product Input Tasks")
|
col1.label(text="Product Input Tasks")
|
||||||
|
|||||||
@@ -553,7 +553,13 @@ def generate_gantt_chart(sequence, work_schedule):
|
|||||||
|
|
||||||
|
|
||||||
def load_product_related_tasks(sequence, product=None):
|
def load_product_related_tasks(sequence, product=None):
|
||||||
sequence.load_product_related_tasks(product)
|
filter_by_schedule = sequence.is_filter_by_active_schedule()
|
||||||
|
if filter_by_schedule:
|
||||||
|
work_schedule = sequence.get_active_work_schedule()
|
||||||
|
task_inputs, task_ouputs = sequence.get_tasks_for_product(product, work_schedule)
|
||||||
|
else:
|
||||||
|
task_inputs, task_ouputs = sequence.get_tasks_for_product(product)
|
||||||
|
sequence.load_product_related_tasks(task_inputs, task_ouputs)
|
||||||
|
|
||||||
|
|
||||||
def reorder_task_nesting(ifc, sequence, task, new_index):
|
def reorder_task_nesting(ifc, sequence, task, new_index):
|
||||||
|
|||||||
@@ -641,7 +641,6 @@ class Sequence:
|
|||||||
def contract_task(cls, task): pass
|
def contract_task(cls, task): pass
|
||||||
def create_bars(cls, tasks): pass
|
def create_bars(cls, tasks): pass
|
||||||
def create_new_task_json(cls, task, json, type_map=None): pass
|
def create_new_task_json(cls, task, json, type_map=None): pass
|
||||||
def load_task_tree(cls, work_schedule): pass
|
|
||||||
def create_tasks_json(cls, work_schedule=None): pass
|
def create_tasks_json(cls, work_schedule=None): pass
|
||||||
def disable_editing_rel_sequence(cls): pass
|
def disable_editing_rel_sequence(cls): pass
|
||||||
def disable_editing_task_animation_colors(cls): pass
|
def disable_editing_task_animation_colors(cls): pass
|
||||||
@@ -656,10 +655,10 @@ class Sequence:
|
|||||||
def enable_editing_rel_sequence_attributes(cls, rel_sequence): pass
|
def enable_editing_rel_sequence_attributes(cls, rel_sequence): pass
|
||||||
def enable_editing_sequence_lag_time(cls, rel_sequence): pass
|
def enable_editing_sequence_lag_time(cls, rel_sequence): pass
|
||||||
def enable_editing_task_animation_colors(cls): pass
|
def enable_editing_task_animation_colors(cls): pass
|
||||||
|
def enable_editing_task_attributes(cls, task): pass
|
||||||
def enable_editing_task_calendar(cls, task): pass
|
def enable_editing_task_calendar(cls, task): pass
|
||||||
def enable_editing_task_sequence(cls, task): pass
|
def enable_editing_task_sequence(cls, task): pass
|
||||||
def enable_editing_task_time(cls, task): pass
|
def enable_editing_task_time(cls, task): pass
|
||||||
def enable_editing_task_attributes(cls, task): pass
|
|
||||||
def enable_editing_work_calendar_times(cls, work_calendar): pass
|
def enable_editing_work_calendar_times(cls, work_calendar): pass
|
||||||
def enable_editing_work_calendar(cls, work_calendar): pass
|
def enable_editing_work_calendar(cls, work_calendar): pass
|
||||||
def enable_editing_work_plan_schedules(cls, work_plan): pass
|
def enable_editing_work_plan_schedules(cls, work_plan): pass
|
||||||
@@ -695,6 +694,7 @@ class Sequence:
|
|||||||
def get_task_resources(cls, task):pass
|
def get_task_resources(cls, task):pass
|
||||||
def get_task_time_attributes(cls): pass
|
def get_task_time_attributes(cls): pass
|
||||||
def get_task_time(cls, task): pass
|
def get_task_time(cls, task): pass
|
||||||
|
def get_tasks_for_product(cls, product, work_schedule): pass
|
||||||
def get_work_calendar_attributes(cls): pass
|
def get_work_calendar_attributes(cls): pass
|
||||||
def get_work_plan_attributes(cls): pass
|
def get_work_plan_attributes(cls): pass
|
||||||
def get_work_schedule_attributes(cls): pass
|
def get_work_schedule_attributes(cls): pass
|
||||||
@@ -704,6 +704,7 @@ class Sequence:
|
|||||||
def guess_date_range(cls, work_schedule): pass
|
def guess_date_range(cls, work_schedule): pass
|
||||||
def has_task_assignments(cls, product, cost_schedule=None): pass
|
def has_task_assignments(cls, product, cost_schedule=None): pass
|
||||||
def highlight_task(cls, task): pass
|
def highlight_task(cls, task): pass
|
||||||
|
def is_filter_by_active_schedule(cls): pass
|
||||||
def is_work_schedule_active(cls, work_schedule): pass
|
def is_work_schedule_active(cls, work_schedule): pass
|
||||||
def load_lag_time_attributes(cls, lag_time): pass
|
def load_lag_time_attributes(cls, lag_time): pass
|
||||||
def load_product_related_tasks(cls, product): pass
|
def load_product_related_tasks(cls, product): pass
|
||||||
@@ -716,6 +717,7 @@ class Sequence:
|
|||||||
def load_task_properties(cls, task): pass
|
def load_task_properties(cls, task): pass
|
||||||
def load_task_resources(cls,resources): pass
|
def load_task_resources(cls,resources): pass
|
||||||
def load_task_time_attributes(cls, task_time): pass
|
def load_task_time_attributes(cls, task_time): pass
|
||||||
|
def load_task_tree(cls, work_schedule): pass
|
||||||
def load_work_calendar_attributes(cls, work_calendar): pass
|
def load_work_calendar_attributes(cls, work_calendar): pass
|
||||||
def load_work_plan_attributes(cls, work_plan): pass
|
def load_work_plan_attributes(cls, work_plan): pass
|
||||||
def load_work_schedule_attributes(cls, work_schedule): pass
|
def load_work_schedule_attributes(cls, work_schedule): pass
|
||||||
|
|||||||
@@ -1555,11 +1555,18 @@ class Sequence(blenderbim.core.tool.Sequence):
|
|||||||
webbrowser.open("file://" + os.path.join(bpy.context.scene.BIMProperties.data_dir, "gantt", "index.html"))
|
webbrowser.open("file://" + os.path.join(bpy.context.scene.BIMProperties.data_dir, "gantt", "index.html"))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load_product_related_tasks(cls, product):
|
def is_filter_by_active_schedule(cls):
|
||||||
|
return bpy.context.scene.BIMWorkScheduleProperties.filter_by_active_schedule
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_tasks_for_product(cls, product, work_schedule=None):
|
||||||
|
return ifcopenshell.util.sequence.get_tasks_for_product(product, work_schedule)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load_product_related_tasks(cls, task_inputs, task_ouputs):
|
||||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||||
props.product_input_tasks.clear()
|
props.product_input_tasks.clear()
|
||||||
props.product_output_tasks.clear()
|
props.product_output_tasks.clear()
|
||||||
task_inputs, task_ouputs = ifcopenshell.util.sequence.get_tasks_for_product(product)
|
|
||||||
for task in task_inputs or []:
|
for task in task_inputs or []:
|
||||||
new = props.product_input_tasks.add()
|
new = props.product_input_tasks.add()
|
||||||
new.name = task.Name or "Unnamed"
|
new.name = task.Name or "Unnamed"
|
||||||
|
|||||||
@@ -237,15 +237,14 @@ def is_work_time_applicable_to_day(work_time, day):
|
|||||||
def get_task_work_schedule(task):
|
def get_task_work_schedule(task):
|
||||||
parent_task = get_parent_task(task)
|
parent_task = get_parent_task(task)
|
||||||
if parent_task:
|
if parent_task:
|
||||||
get_task_work_schedule(parent_task)
|
return get_task_work_schedule(parent_task) or get_task_work_schedule(task)
|
||||||
else:
|
else:
|
||||||
schedules = [
|
for rel in task.HasAssignments:
|
||||||
rel.RelatingControl
|
if rel.is_a("IfcRelAssignsToControl") and rel.RelatingControl.is_a(
|
||||||
for rel in task.HasAssignments
|
"IfcWorkSchedule"
|
||||||
if rel.is_a("IfcRelAssignsToControl")
|
):
|
||||||
and rel.RelatingControl.is_a("IfcWorkSchedule")
|
return rel.RelatingControl
|
||||||
]
|
return None
|
||||||
return schedules
|
|
||||||
|
|
||||||
|
|
||||||
def get_nested_tasks(task):
|
def get_nested_tasks(task):
|
||||||
@@ -332,39 +331,98 @@ def get_task_outputs(task, is_deep=False):
|
|||||||
for output in get_direct_task_outputs(nested_task)
|
for output in get_direct_task_outputs(nested_task)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def get_task_inputs(task, is_deep=False):
|
def get_task_inputs(task, is_deep=False):
|
||||||
if not is_deep:
|
if not is_deep:
|
||||||
return [object for rel in task.OperatesOn if rel.is_a("IfcRelAssignsToProcess") for object in rel.RelatedObjects if object.is_a("IfcProduct")]
|
return [
|
||||||
|
object
|
||||||
|
for rel in task.OperatesOn
|
||||||
|
if rel.is_a("IfcRelAssignsToProcess")
|
||||||
|
for object in rel.RelatedObjects
|
||||||
|
if object.is_a("IfcProduct")
|
||||||
|
]
|
||||||
else:
|
else:
|
||||||
return [
|
return [
|
||||||
output
|
output
|
||||||
for nested_task in get_all_nested_tasks(task)
|
for nested_task in get_all_nested_tasks(task)
|
||||||
for output in [object for rel in nested_task.OperatesOn if rel.is_a("IfcRelAssignsToProcess") for object in rel.RelatedObjects if object.is_a("IfcProduct")]
|
for output in [
|
||||||
|
object
|
||||||
|
for rel in nested_task.OperatesOn
|
||||||
|
if rel.is_a("IfcRelAssignsToProcess")
|
||||||
|
for object in rel.RelatedObjects
|
||||||
|
if object.is_a("IfcProduct")
|
||||||
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def get_task_resources(task, is_deep=False):
|
def get_task_resources(task, is_deep=False):
|
||||||
if not is_deep:
|
if not is_deep:
|
||||||
return [object for rel in task.OperatesOn if rel.is_a("IfcRelAssignsToProcess") for object in rel.RelatedObjects if object.is_a("IfcResource")]
|
return [
|
||||||
|
object
|
||||||
|
for rel in task.OperatesOn
|
||||||
|
if rel.is_a("IfcRelAssignsToProcess")
|
||||||
|
for object in rel.RelatedObjects
|
||||||
|
if object.is_a("IfcResource")
|
||||||
|
]
|
||||||
else:
|
else:
|
||||||
return [
|
return [
|
||||||
output
|
resource
|
||||||
for nested_task in get_all_nested_tasks(task)
|
for nested_task in get_all_nested_tasks(task)
|
||||||
for output in [object for rel in nested_task.OperatesOn if rel.is_a("IfcRelAssignsToProcess") for object in rel.RelatedObjects if object.is_a("IfcResource")]
|
for resource in [
|
||||||
|
object
|
||||||
|
for rel in nested_task.OperatesOn
|
||||||
|
if rel.is_a("IfcRelAssignsToProcess")
|
||||||
|
for object in rel.RelatedObjects
|
||||||
|
if object.is_a("IfcResource")
|
||||||
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def has_task_outputs(task):
|
def has_task_outputs(task):
|
||||||
return len(get_task_outputs(task)) > 0
|
return len(get_task_outputs(task)) > 0
|
||||||
|
|
||||||
|
|
||||||
def has_task_inputs(task):
|
def has_task_inputs(task):
|
||||||
return len(get_task_inputs(task)) > 0
|
return len(get_task_inputs(task)) > 0
|
||||||
|
|
||||||
def get_tasks_for_product(product):
|
|
||||||
inputs = []
|
def get_tasks_for_product(product, schedule=None):
|
||||||
outputs = []
|
"""
|
||||||
for assignment in product.HasAssignments:
|
Get all tasks assigned to or referenced by the given product.
|
||||||
if assignment.is_a("IfcRelAssignsToProcess") and assignment.RelatingProcess.is_a("IfcTask"):
|
|
||||||
inputs.append(assignment.RelatingProcess)
|
Args:
|
||||||
for reference in product.ReferencedBy:
|
product: An object that is assigned tasks or references tasks.
|
||||||
if reference.is_a("IfcRelAssignsToProduct") and reference.RelatedObjects[0].is_a("IfcTask"):
|
schedule: An optional string representing the schedule name to filter tasks by.
|
||||||
outputs.extend([obj for obj in reference.RelatedObjects if obj.is_a("IfcTask")])
|
|
||||||
|
Returns:
|
||||||
|
A tuple of two lists:
|
||||||
|
- The first list contains all tasks assigned to the product.
|
||||||
|
- The second list contains all tasks referenced by the product that are part of the given schedule.
|
||||||
|
"""
|
||||||
|
inputs = [
|
||||||
|
assignement.RelatingProcess
|
||||||
|
for assignement in product.HasAssignments
|
||||||
|
if assignement.is_a("IfcRelAssignsToProcess")
|
||||||
|
and assignement.RelatingProcess.is_a("IfcTask")
|
||||||
|
]
|
||||||
|
outputs = [
|
||||||
|
obj
|
||||||
|
for ref in product.ReferencedBy
|
||||||
|
if ref.is_a("IfcRelAssignsToProduct")
|
||||||
|
for obj in ref.RelatedObjects
|
||||||
|
if obj.is_a("IfcTask")
|
||||||
|
]
|
||||||
|
|
||||||
|
if schedule:
|
||||||
|
inputs = [
|
||||||
|
task
|
||||||
|
for task in inputs
|
||||||
|
if get_task_work_schedule(task).id() == schedule.id()
|
||||||
|
]
|
||||||
|
outputs = [
|
||||||
|
task
|
||||||
|
for task in outputs
|
||||||
|
if get_task_work_schedule(task).id() == schedule.id()
|
||||||
|
]
|
||||||
|
|
||||||
return inputs, outputs
|
return inputs, outputs
|
||||||
Reference in New Issue
Block a user