From f8651430e6da1f4992d33cc425c66cebcedeaa78 Mon Sep 17 00:00:00 2001 From: "Sigma Dimensions (Yass)" <79010126+myoualid@users.noreply.github.com> Date: Wed, 23 Aug 2023 02:11:18 +0100 Subject: [PATCH] consolidate constraint utilities into ifcopenshell.util.constraint and refactor --- .../blenderbim/bim/module/resource/data.py | 18 +++++- src/blenderbim/blenderbim/core/tool.py | 1 - .../ifcopenshell/util/constraint.py | 62 +++++++++++++++++++ 3 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 src/ifcopenshell-python/ifcopenshell/util/constraint.py diff --git a/src/blenderbim/blenderbim/bim/module/resource/data.py b/src/blenderbim/blenderbim/bim/module/resource/data.py index b854002ce4..269535125a 100644 --- a/src/blenderbim/blenderbim/bim/module/resource/data.py +++ b/src/blenderbim/blenderbim/bim/module/resource/data.py @@ -56,7 +56,7 @@ class ResourceData: "type": resource.is_a(), "BaseQuantity": base_quantity, } - results[resource.id()]["Benchmarks"] = tool.Resource.get_resource_benchmarks(resource) + results[resource.id()]["Benchmarks"] = cls.get_resource_benchmarks(resource) if resource.is_a() in ["IfcLaborResource", "IfcConstructionEquipmentResource"]: results[resource.id()]["Productivity"] = {} results[resource.id()]["InheritedProductivity"] = {} @@ -87,6 +87,22 @@ class ResourceData: ) return results + @classmethod + def get_resource_benchmarks(cls, resource): + constraints = [] + for constraint in ifcopenshell.util.constraint.get_constraints(resource) or []: + metrics = [] + for metric in ifcopenshell.util.constraint.get_metrics(constraint) or []: + metrics.append( + { + "reference": ifcopenshell.util.constraint.get_metric_reference(metric), + "Benchmark": metric.Benchmark, + "ConstraintGrade": metric.ConstraintGrade, + } + ) + constraints.append({"ObjectiveQualifier": constraint.ObjectiveQualifier, "metrics": metrics}) + return constraints + @classmethod def get_productivity(cls, resource): return ifcopenshell.util.resource.get_productivity(resource, should_inherit=False) diff --git a/src/blenderbim/blenderbim/core/tool.py b/src/blenderbim/blenderbim/core/tool.py index 4b75600581..484b13f340 100644 --- a/src/blenderbim/blenderbim/core/tool.py +++ b/src/blenderbim/blenderbim/core/tool.py @@ -620,7 +620,6 @@ class Resource: def get_constraints(cls, resource): pass def get_metrics(cls, constraint): pass def get_metric_reference(cls, metric, is_deep): pass - def get_resource_benchmarks(cls, resource): pass def has_metric_constraint(cls, resource, attribute): pass def has_usage_metric(cls, resource): pass diff --git a/src/ifcopenshell-python/ifcopenshell/util/constraint.py b/src/ifcopenshell-python/ifcopenshell/util/constraint.py new file mode 100644 index 0000000000..66397bb58c --- /dev/null +++ b/src/ifcopenshell-python/ifcopenshell/util/constraint.py @@ -0,0 +1,62 @@ +# IfcOpenShell - IFC toolkit and geometry engine +# Copyright (C) 2023 Dion Moult, Yassine Oualid +# +# This file is part of IfcOpenShell. +# +# IfcOpenShell is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# IfcOpenShell is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with IfcOpenShell. If not, see . +# +# + +def get_constraints(product): + constraints = [] + if product.HasAssociations: + for rel in product.HasAssociations: + if rel.is_a("IfcRelAssociatesConstraint"): + constraints.append(rel.RelatingConstraint) + return constraints + +def get_metrics(constraint): + metrics = [] + for metric in constraint.BenchmarkValues or []: + metrics.append(metric) + return metrics + +def get_metric_reference(metric, is_deep=True): + def get_reference_Attribute(ref, path): + if ref: + if is_deep: + if not path: + path = ref.AttributeIdentifier + else: + path += ".{}".format(ref.AttributeIdentifier) if ref.AttributeIdentifier else "" + return get_reference_Attribute(ref.InnerReference, path) + else: + return ref.AttributeIdentifier + return path + + reference = metric.ReferencePath + return get_reference_Attribute(reference, "") + +def has_metric_constraints(resource, attribute): + metrics = [] + for constraint in get_constraints(resource) or []: + for metric in get_metrics(constraint) or []: + if bool( + get_metric_reference(metric, is_deep=False) == attribute + or get_metric_reference(metric, is_deep=True) == attribute + ): + metrics.append(metric) + if metrics: + return metrics + return None \ No newline at end of file