mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 01:41:57 +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)
|
||||
show_task_operators: BoolProperty(name="Show Task Options", default=True)
|
||||
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):
|
||||
|
||||
@@ -977,7 +977,7 @@ class BIM_PT_4D_Tools(Panel):
|
||||
self.props = context.scene.BIMWorkScheduleProperties
|
||||
row = self.layout.row()
|
||||
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)
|
||||
col1 = grid.column()
|
||||
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):
|
||||
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):
|
||||
|
||||
@@ -641,7 +641,6 @@ class Sequence:
|
||||
def contract_task(cls, task): pass
|
||||
def create_bars(cls, tasks): 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 disable_editing_rel_sequence(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_sequence_lag_time(cls, rel_sequence): 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_sequence(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(cls, work_calendar): 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_time_attributes(cls): 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_plan_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 has_task_assignments(cls, product, cost_schedule=None): 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 load_lag_time_attributes(cls, lag_time): 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_resources(cls,resources): 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_plan_attributes(cls, work_plan): 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"))
|
||||
|
||||
@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.product_input_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 []:
|
||||
new = props.product_input_tasks.add()
|
||||
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):
|
||||
parent_task = get_parent_task(task)
|
||||
if parent_task:
|
||||
get_task_work_schedule(parent_task)
|
||||
return get_task_work_schedule(parent_task) or get_task_work_schedule(task)
|
||||
else:
|
||||
schedules = [
|
||||
rel.RelatingControl
|
||||
for rel in task.HasAssignments
|
||||
if rel.is_a("IfcRelAssignsToControl")
|
||||
and rel.RelatingControl.is_a("IfcWorkSchedule")
|
||||
]
|
||||
return schedules
|
||||
for rel in task.HasAssignments:
|
||||
if rel.is_a("IfcRelAssignsToControl") and rel.RelatingControl.is_a(
|
||||
"IfcWorkSchedule"
|
||||
):
|
||||
return rel.RelatingControl
|
||||
return None
|
||||
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
|
||||
def get_task_inputs(task, is_deep=False):
|
||||
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:
|
||||
return [
|
||||
output
|
||||
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):
|
||||
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:
|
||||
return [
|
||||
output
|
||||
resource
|
||||
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):
|
||||
return len(get_task_outputs(task)) > 0
|
||||
|
||||
|
||||
def has_task_inputs(task):
|
||||
return len(get_task_inputs(task)) > 0
|
||||
|
||||
def get_tasks_for_product(product):
|
||||
inputs = []
|
||||
outputs = []
|
||||
for assignment in product.HasAssignments:
|
||||
if assignment.is_a("IfcRelAssignsToProcess") and assignment.RelatingProcess.is_a("IfcTask"):
|
||||
inputs.append(assignment.RelatingProcess)
|
||||
for reference in product.ReferencedBy:
|
||||
if reference.is_a("IfcRelAssignsToProduct") and reference.RelatedObjects[0].is_a("IfcTask"):
|
||||
outputs.extend([obj for obj in reference.RelatedObjects if obj.is_a("IfcTask")])
|
||||
return inputs, outputs
|
||||
|
||||
def get_tasks_for_product(product, schedule=None):
|
||||
"""
|
||||
Get all tasks assigned to or referenced by the given product.
|
||||
|
||||
Args:
|
||||
product: An object that is assigned tasks or references tasks.
|
||||
schedule: An optional string representing the schedule name to filter tasks by.
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user