diff --git a/src/ifcpatch/ifcpatch/recipes/MergeProject.py b/src/ifcpatch/ifcpatch/recipes/MergeProject.py index 8a4a36f388..f59d647291 100644 --- a/src/ifcpatch/ifcpatch/recipes/MergeProject.py +++ b/src/ifcpatch/ifcpatch/recipes/MergeProject.py @@ -46,10 +46,46 @@ class Patcher: def patch(self): source = ifcopenshell.open(self.filepath) + self.existing_contexts = self.file.by_type("IfcGeometricRepresentationContext") + self.added_contexts = set() original_project = self.file.by_type("IfcProject")[0] merged_project = self.file.add(source.by_type("IfcProject")[0]) + for element in source.by_type("IfcGeometricRepresentationContext"): + new = self.file.add(element) + self.added_contexts.add(new) for element in source: self.file.add(element) for inverse in self.file.get_inverse(merged_project): ifcopenshell.util.element.replace_attribute(inverse, merged_project, original_project) self.file.remove(merged_project) + self.reuse_existing_contexts() + + def reuse_existing_contexts(self): + to_delete = set() + + for added_context in self.added_contexts: + equivalent_existing_context = self.get_equivalent_existing_context(added_context) + if equivalent_existing_context: + for inverse in self.file.get_inverse(added_context): + ifcopenshell.util.element.replace_attribute(inverse, added_context, equivalent_existing_context) + to_delete.add(added_context) + + for added_context in to_delete: + ifcopenshell.util.element.remove_deep2(self.file, added_context) + + def get_equivalent_existing_context(self, added_context): + for context in self.existing_contexts: + if context.is_a() != added_context.is_a(): + continue + if context.is_a("IfcGeometricRepresentationSubContext"): + if ( + context.ContextType == added_context.ContextType + and context.ContextIdentifier == added_context.ContextIdentifier + and context.TargetView == added_context.TargetView + ): + return context + elif ( + context.ContextType == added_context.ContextType + and context.ContextIdentifier == added_context.ContextIdentifier + ): + return context