From b4256c504f76de6d59201dac7caf86f4e00b6312 Mon Sep 17 00:00:00 2001 From: bosonprojets Date: Mon, 16 Aug 2021 01:35:14 +0100 Subject: [PATCH] Implement metric constraints in the ifcopenshell.api --- .../ifcopenshell/api/constraint/add_metric.py | 21 ++++++++++ .../api/constraint/assign_constraint.py | 1 + .../ifcopenshell/api/constraint/data.py | 40 +++++++++++++++++++ .../api/constraint/edit_metric.py | 13 ++++++ .../api/constraint/remove_metric.py | 15 +++++++ 5 files changed, 90 insertions(+) create mode 100644 src/ifcopenshell-python/ifcopenshell/api/constraint/add_metric.py create mode 100644 src/ifcopenshell-python/ifcopenshell/api/constraint/edit_metric.py create mode 100644 src/ifcopenshell-python/ifcopenshell/api/constraint/remove_metric.py diff --git a/src/ifcopenshell-python/ifcopenshell/api/constraint/add_metric.py b/src/ifcopenshell-python/ifcopenshell/api/constraint/add_metric.py new file mode 100644 index 0000000000..ce273a61ec --- /dev/null +++ b/src/ifcopenshell-python/ifcopenshell/api/constraint/add_metric.py @@ -0,0 +1,21 @@ +import ifcopenshell + +class Usecase: + def __init__(self, file, **settings): + self.file = file + self.settings = { + "objective": None, + } + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + metric = self.file.create_entity("IfcMetric", **{ + "Name": "Unnamed", + "ConstraintGrade": "NOTDEFINED", + "Benchmark": "EQUALTO", + }) + if self.settings["objective"]: + benchmark_values = list(self.settings["objective"].BenchmarkValues or []) + benchmark_values.append(metric) + return metric diff --git a/src/ifcopenshell-python/ifcopenshell/api/constraint/assign_constraint.py b/src/ifcopenshell-python/ifcopenshell/api/constraint/assign_constraint.py index 7dc946e911..0489af80d6 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/constraint/assign_constraint.py +++ b/src/ifcopenshell-python/ifcopenshell/api/constraint/assign_constraint.py @@ -16,6 +16,7 @@ class Usecase: related_objects = set(rel.RelatedObjects) if rel.RelatedObjects else set() related_objects.add(self.settings["product"]) rel.RelatedObjects = list(related_objects) + return rel def get_constraint_rel(self): for rel in self.file.by_type("IfcRelAssociatesConstraint"): diff --git a/src/ifcopenshell-python/ifcopenshell/api/constraint/data.py b/src/ifcopenshell-python/ifcopenshell/api/constraint/data.py index aaae145eaf..3a4791feeb 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/constraint/data.py +++ b/src/ifcopenshell-python/ifcopenshell/api/constraint/data.py @@ -7,12 +7,17 @@ class Data: is_loaded = False products = {} objectives = {} + metrics = {} + references = {} @classmethod def purge(cls): cls.is_loaded = False cls.products = {} cls.objectives = {} + cls.metrics ={} + cls.references = {} + @classmethod def load(cls, file, product_id=None): @@ -22,6 +27,8 @@ class Data: if product_id: return cls.load_product(product_id) cls.load_objectives() + cls.load_metrics() + cls.load_references() cls.is_loaded = True @classmethod @@ -41,8 +48,41 @@ class Data: cls.objectives = {} for constraint in cls._file.by_type("IfcObjective"): data = constraint.get_info() + for key, value in data.items(): + if not value: + continue + if cls._file.schema == "IFC2X3": for attribute in ["CreationTime"]: if data[attribute]: data[attribute] = ifcopenshell.util.date.ifc2datetime(data[attribute]).isoformat() + data["BenchmarkValues"] = [metric.id() for metric in constraint.BenchmarkValues or []] cls.objectives[constraint.id()] = data + + @classmethod + def load_metrics(cls): + cls.metrics = {} + for metric in cls._file.by_type("IfcMetric"): + data = metric.get_info() + for key, value in data.items(): + if not value: + continue + data["ConstrainedObjects"] = [] + for association in cls._file.by_type("IfcRelAssociatesConstraint"): + if association.RelatingConstraint.id() == metric.id(): + data["ConstrainedObjects"] = [o.id() for o in association.RelatedObjects or []] + if metric.DataValue: + data["DataValue"] = data["DataValue"].id() + if metric.ReferencePath: + data["ReferencePath"] = data["ReferencePath"].id() + cls.metrics[metric.id()] = data + + @classmethod + def load_references(cls): + cls.references = {} + for reference in cls._file.by_type("IfcReference"): + data = reference.get_info() + for key, value in data.items(): + if not value: + continue + cls.references[refenrece.id()] = data diff --git a/src/ifcopenshell-python/ifcopenshell/api/constraint/edit_metric.py b/src/ifcopenshell-python/ifcopenshell/api/constraint/edit_metric.py new file mode 100644 index 0000000000..f2859769c2 --- /dev/null +++ b/src/ifcopenshell-python/ifcopenshell/api/constraint/edit_metric.py @@ -0,0 +1,13 @@ +class Usecase: + def __init__(self, file, **settings): + self.file = file + self.settings = { + "metric": None, + "attributes": {} + } + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + for name, value in self.settings["attributes"].items(): + setattr(self.settings["metric"], name, value) diff --git a/src/ifcopenshell-python/ifcopenshell/api/constraint/remove_metric.py b/src/ifcopenshell-python/ifcopenshell/api/constraint/remove_metric.py new file mode 100644 index 0000000000..addec2e94f --- /dev/null +++ b/src/ifcopenshell-python/ifcopenshell/api/constraint/remove_metric.py @@ -0,0 +1,15 @@ +class Usecase: + def __init__(self, file, **settings): + self.file = file + self.settings = {"metric": None} + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + self.file.remove(self.settings["metric"]) + for rel in self.file.by_type("IfcRelAssociatesConstraint"): + if not rel.RelatingConstraint: + self.file.remove(rel) + for resource_rel in self.file.by_type("IfcResourceConstraintRelationship"): + if not resource_rel.RelatingConstraint: + self.file.remove(resource_rel)