From 6b46ff71a610b170344b6a8c162fb6dee65eb260 Mon Sep 17 00:00:00 2001 From: bosonprojets Date: Sun, 2 May 2021 01:44:56 +0000 Subject: [PATCH] Implement feature to select all products related to a task in blenderBIM, and the ifcopenshell.api --- .../bim/module/sequence/__init__.py | 1 + .../bim/module/sequence/operator.py | 19 +++++++++++++ .../blenderbim/bim/module/sequence/ui.py | 6 +--- .../api/sequence/get_related_products.py | 28 +++++++++++++++++++ 4 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 src/ifcopenshell-python/ifcopenshell/api/sequence/get_related_products.py diff --git a/src/blenderbim/blenderbim/bim/module/sequence/__init__.py b/src/blenderbim/blenderbim/bim/module/sequence/__init__.py index d1e8ffaf88..a10ea33681 100644 --- a/src/blenderbim/blenderbim/bim/module/sequence/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/sequence/__init__.py @@ -58,6 +58,7 @@ classes = ( operator.GenerateGanttChart, operator.ImportP6, operator.LoadTaskProperties, + operator.SelectTaskRelatedProducts, prop.WorkPlan, prop.BIMWorkPlanProperties, prop.Task, diff --git a/src/blenderbim/blenderbim/bim/module/sequence/operator.py b/src/blenderbim/blenderbim/bim/module/sequence/operator.py index 353277af33..9eb62c750a 100644 --- a/src/blenderbim/blenderbim/bim/module/sequence/operator.py +++ b/src/blenderbim/blenderbim/bim/module/sequence/operator.py @@ -1250,3 +1250,22 @@ class DisableEditingSequenceAttributes(bpy.types.Operator): def execute(self, context): context.scene.BIMWorkScheduleProperties.active_sequence_id = 0 return {"FINISHED"} + + +class SelectTaskRelatedProducts(bpy.types.Operator): + bl_idname = "bim.select_task_related_products" + bl_label = "Select Similar Type" + task: bpy.props.IntProperty() + + def execute(self, context): + self.file = IfcStore.get_file() + related_products = ifcopenshell.api.run( + "sequence.get_related_products", + self.file, + **{"related_object": self.file.by_id(self.task)} + ) + for obj in bpy.context.visible_objects: + obj.select_set(False) + if obj.BIMObjectProperties.ifc_definition_id in related_products: + obj.select_set(True) + return {"FINISHED"} diff --git a/src/blenderbim/blenderbim/bim/module/sequence/ui.py b/src/blenderbim/blenderbim/bim/module/sequence/ui.py index 482a924b7b..02c0a1b3bb 100644 --- a/src/blenderbim/blenderbim/bim/module/sequence/ui.py +++ b/src/blenderbim/blenderbim/bim/module/sequence/ui.py @@ -172,17 +172,13 @@ class BIM_PT_work_schedules(Panel): row.label(text=task["Identification"] or "XXX") row.label(text=task["Name"] or "Unnamed") row.label(text=sequence["SequenceType"] or "N/A") - if self.props.active_sequence_id == sequence["id"]: - row = self.layout.row() row.operator("bim.edit_sequence_attributes", text="", icon="CHECKMARK") row.operator("bim.disable_editing_sequence_attributes", text="", icon="X") self.draw_editable_sequence_attributes_ui() else: - row = self.layout.row() row.operator("bim.enable_editing_sequence_attributes", text="", icon="GREASEPENCIL").sequence = sequence["id"] - def draw_editable_sequence_attributes_ui(self): for attribute in self.props.sequence_attributes: row = self.layout.row(align=True) @@ -199,7 +195,6 @@ class BIM_PT_work_schedules(Panel): if attribute.is_optional: row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="") - def draw_editable_task_calendar_ui(self): task = Data.tasks[self.props.active_task_id] if task["HasAssignmentsWorkCalendar"]: @@ -317,6 +312,7 @@ class BIM_UL_tasks(UIList): row.operator("bim.remove_task", text="", icon="X").task = item.ifc_definition_id else: row.operator("bim.enable_editing_task_sequence", text="", icon="TRACKING").task = item.ifc_definition_id + row.operator("bim.select_task_related_products", icon="RESTRICT_SELECT_OFF", text="").task = item.ifc_definition_id row.operator("bim.enable_editing_task_time", text="", icon="TIME").task = item.ifc_definition_id row.operator("bim.enable_editing_task_calendar", text="", icon="VIEW_ORTHO").task = item.ifc_definition_id row.operator("bim.enable_editing_task", text="", icon="GREASEPENCIL").task = item.ifc_definition_id diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/get_related_products.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/get_related_products.py new file mode 100644 index 0000000000..f58404c3b1 --- /dev/null +++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/get_related_products.py @@ -0,0 +1,28 @@ +import ifcopenshell + + +class Usecase: + def __init__(self, file, **settings): + self.file = file + self.settings = { + "relating_product": None, + "related_object": None, + } + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + products = set() + related_object = None + if self.settings["related_object"]: + related_object = self.settings["related_object"] + elif self.settings["relating_product"]: + for reference in self.settings["relating_product"].ReferencedBy: + if reference.is_a("IfcRelAssignsToProduct"): + related_object = referenced_by.RelatedObjects[0] + if related_object: + assignments = self.settings["related_object"].HasAssignments + for assignment in assignments: + if assignment.is_a("IfcRelAssignsToProduct"): + products.add(assignment.RelatingProduct.id()) + return products