From 67955b4e35c5facb54fa1652b789498fc7b7aee9 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Thu, 20 Oct 2022 18:25:14 +1100 Subject: [PATCH] Batch reassign utility to address performance issues in #2408. --- .../ifcopenshell/util/schema.py | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/ifcopenshell-python/ifcopenshell/util/schema.py b/src/ifcopenshell-python/ifcopenshell/util/schema.py index d4713e9a98..9472d149c3 100644 --- a/src/ifcopenshell-python/ifcopenshell/util/schema.py +++ b/src/ifcopenshell-python/ifcopenshell/util/schema.py @@ -66,6 +66,44 @@ def reassign_class(ifc_file, element, new_class): return new_element +class BatchReassignClass: + def __init__(self, file): + self.file = file + self.purge() + + def reassign(self, element, new_class): + try: + new_element = self.file.create_entity(new_class) + except: + print(f"Class of {element} could not be changed to {new_class}") + return element + new_attributes = [new_element.attribute_name(i) for i, attribute in enumerate(new_element)] + for i, attribute in enumerate(element): + try: + new_element[new_attributes.index(element.attribute_name(i))] = attribute + except: + continue + for inverse in self.file.get_inverse(element): + self.replacements.setdefault(inverse, {})[element] = new_element + self.to_delete.add(element) + return new_element + + def unbatch(self): + for element, replacements in self.replacements.items(): + for i, attribute in enumerate(element): + new = element.walk(lambda v: v in replacements.keys(), lambda v: replacements[v], attribute) + if attribute != new: + element[i] = new + + for element in self.to_delete: + self.file.remove(element) + self.purge() + + def purge(self): + self.replacements = {} + self.to_delete = set() + + class Migrator: def __init__(self): self.migrated_ids = {}