From 9f49cbe0c9429db9bd76a84a503508ebc76d242c Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Thu, 14 Nov 2024 16:18:09 +0500 Subject: [PATCH] bim.calculate_resource_quantity #5744 Added operator to calculate resource quantity based on the output products and the quantity Name. See video demo - https://imgchest.com/p/9rydjlbmnyk --- src/bonsai/bonsai/bim/module/resource/__init__.py | 1 + src/bonsai/bonsai/bim/module/resource/operator.py | 12 ++++++++++++ src/bonsai/bonsai/bim/module/resource/ui.py | 3 +++ src/bonsai/bonsai/core/resource.py | 4 ++++ src/bonsai/bonsai/tool/resource.py | 6 ++++++ .../api/cost/calculate_cost_item_resource_value.py | 1 + 6 files changed, 27 insertions(+) diff --git a/src/bonsai/bonsai/bim/module/resource/__init__.py b/src/bonsai/bonsai/bim/module/resource/__init__.py index 8d5c4e26fd..002952b3c1 100644 --- a/src/bonsai/bonsai/bim/module/resource/__init__.py +++ b/src/bonsai/bonsai/bim/module/resource/__init__.py @@ -25,6 +25,7 @@ classes = ( operator.AddProductivityData, operator.AssignResource, operator.CalculateResourceWork, + operator.CalculateResourceQuantity, operator.ConstrainResourceWork, operator.ContractResource, operator.DisableEditingResource, diff --git a/src/bonsai/bonsai/bim/module/resource/operator.py b/src/bonsai/bonsai/bim/module/resource/operator.py index 9280d8ce17..9d33c2d79e 100644 --- a/src/bonsai/bonsai/bim/module/resource/operator.py +++ b/src/bonsai/bonsai/bim/module/resource/operator.py @@ -429,3 +429,15 @@ class CalculateResourceUsage(bpy.types.Operator, tool.Ifc.Operator): def _execute(self, context): core.calculate_resource_usage(tool.Ifc, tool.Resource, resource=tool.Resource.get_highlighted_resource()) + + +class CalculateResourceQuantity(bpy.types.Operator, tool.Ifc.Operator): + bl_idname = "bim.calculate_resource_quantity" + bl_label = "Calculate Resource Quantity" + bl_description = "Calcule resource quantity based on the same name quantities from the output products" + bl_options = {"REGISTER", "UNDO"} + resource: bpy.props.IntProperty(name="Resource ID") + + def _execute(self, context): + core.calculate_resource_quantity(tool.Resource, resource=tool.Ifc.get().by_id(self.resource)) + return {"FINISHED"} diff --git a/src/bonsai/bonsai/bim/module/resource/ui.py b/src/bonsai/bonsai/bim/module/resource/ui.py index fe5d85acd7..1560cb027f 100644 --- a/src/bonsai/bonsai/bim/module/resource/ui.py +++ b/src/bonsai/bonsai/bim/module/resource/ui.py @@ -258,6 +258,9 @@ class BIM_PT_resources(Panel): else: op = row.operator("bim.enable_editing_resource_quantity", text="", icon="GREASEPENCIL") op.resource = self.props.active_resource_id + if resource["type"] == "IfcConstructionMaterialResource": + op = row.operator("bim.calculate_resource_quantity", text="", icon="FILE_REFRESH") + op.resource = self.props.active_resource_id op = row.operator("bim.remove_resource_quantity", text="", icon="X") op.resource = self.props.active_resource_id diff --git a/src/bonsai/bonsai/core/resource.py b/src/bonsai/bonsai/core/resource.py index b53fcc131b..12c6dc2b14 100644 --- a/src/bonsai/bonsai/core/resource.py +++ b/src/bonsai/bonsai/core/resource.py @@ -262,3 +262,7 @@ def calculate_resource_usage( ) -> None: ifc.run("resource.calculate_resource_usage", resource=resource) resource_tool.load_resources() + + +def calculate_resource_quantity(resource_tool: tool.Resource, resource: ifcopenshell.entity_instance) -> None: + resource_tool.calculate_resource_quantity(resource) diff --git a/src/bonsai/bonsai/tool/resource.py b/src/bonsai/bonsai/tool/resource.py index a1513fd948..b9bc5938f4 100644 --- a/src/bonsai/bonsai/tool/resource.py +++ b/src/bonsai/bonsai/tool/resource.py @@ -443,6 +443,12 @@ class Resource(bonsai.core.tool.Resource): def run_calculate_resource_usage(cls, resource: ifcopenshell.entity_instance) -> None: tool.Ifc.run("resource.calculate_resource_usage", resource=resource) + @classmethod + def calculate_resource_quantity(cls, resource: ifcopenshell.entity_instance) -> None: + quantity: ifcopenshell.entity_instance = resource.BaseQuantity + quantity_from_products = ifcopenshell.util.resource.get_total_quantity_produced(resource, quantity.Name) + quantity[3] = quantity_from_products + @classmethod def get_task_assignments(cls, resource: ifcopenshell.entity_instance) -> Union[ifcopenshell.entity_instance, None]: return ifcopenshell.util.resource.get_task_assignments(resource) diff --git a/src/ifcopenshell-python/ifcopenshell/api/cost/calculate_cost_item_resource_value.py b/src/ifcopenshell-python/ifcopenshell/api/cost/calculate_cost_item_resource_value.py index 3371d3e200..fcdd4084ce 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/cost/calculate_cost_item_resource_value.py +++ b/src/ifcopenshell-python/ifcopenshell/api/cost/calculate_cost_item_resource_value.py @@ -101,6 +101,7 @@ def calculate_cost_item_resource_value(file: ifcopenshell.file, cost_item: ifcop for resource in resources: cost, unit = ifcopenshell.util.resource.get_cost(resource) + # TODO: cost is never None because get_cost always returns a float. if cost is None: # Concept to standardise - Not defined in schema, but this makes manual scheduling of resources 10x faster and less duplicate data. parent_cost = ifcopenshell.util.resource.get_parent_cost(resource)