Fix #5271. Prevent duplicate entries when getting a decomposition.

This commit is contained in:
Dion Moult
2024-09-02 17:35:43 +10:00
parent 04bbfc04ad
commit 521b0ab58d
@@ -947,7 +947,7 @@ def get_structure_referenced_elements(structure: ifcopenshell.entity_instance) -
return referenced return referenced
def get_decomposition(element: ifcopenshell.entity_instance, is_recursive=True) -> list[ifcopenshell.entity_instance]: def get_decomposition(element: ifcopenshell.entity_instance, is_recursive=True) -> set[ifcopenshell.entity_instance]:
""" """
Retrieves all subelements of an element based on the spatial decomposition Retrieves all subelements of an element based on the spatial decomposition
hierarchy. This includes all subspaces and elements contained in subspaces, hierarchy. This includes all subspaces and elements contained in subspaces,
@@ -966,29 +966,29 @@ def get_decomposition(element: ifcopenshell.entity_instance, is_recursive=True)
decomposition = ifcopenshell.util.element.get_decomposition(element) decomposition = ifcopenshell.util.element.get_decomposition(element)
""" """
queue = [element] queue = [element]
results = [] results = set()
while queue: while queue:
element = queue.pop() element = queue.pop()
for rel in getattr(element, "ContainsElements", []): for rel in getattr(element, "ContainsElements", []):
related = rel.RelatedElements related = rel.RelatedElements
queue.extend(related) queue.extend(related)
results.extend(related) results.update(related)
for rel in getattr(element, "IsDecomposedBy", []): for rel in getattr(element, "IsDecomposedBy", []):
related = rel.RelatedObjects related = rel.RelatedObjects
queue.extend(related) queue.extend(related)
results.extend(related) results.update(related)
for rel in getattr(element, "HasOpenings", []): for rel in getattr(element, "HasOpenings", []):
related = rel.RelatedOpeningElement related = rel.RelatedOpeningElement
queue.append(related) queue.append(related)
results.append(related) results.add(related)
for rel in getattr(element, "HasFillings", []): for rel in getattr(element, "HasFillings", []):
related = rel.RelatedBuildingElement related = rel.RelatedBuildingElement
queue.append(related) queue.append(related)
results.append(related) results.add(related)
for rel in getattr(element, "IsNestedBy", []): for rel in getattr(element, "IsNestedBy", []):
related = rel.RelatedObjects related = rel.RelatedObjects
queue.extend(related) queue.extend(related)
results.extend(related) results.update(related)
if not is_recursive: if not is_recursive:
break break
return results return results