diff --git a/src/ifcopenshell-python/ifcopenshell/api/project/append_asset.py b/src/ifcopenshell-python/ifcopenshell/api/project/append_asset.py index 50e29994fd..edea2b586f 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/project/append_asset.py +++ b/src/ifcopenshell-python/ifcopenshell/api/project/append_asset.py @@ -183,20 +183,21 @@ class Usecase: existing_element = self.get_existing_element(element) if existing_element: return existing_element - # if element.id() in self.added_elements: - # return self.added_elements[element.id()] new = self.file.add(element) self.added_elements[element.id()] = new self.check_inverses(element) - for subelement in self.settings["library"].traverse(element)[1:]: + subelement_queue = self.settings["library"].traverse(element, max_levels=1)[1:] + while subelement_queue: + subelement = subelement_queue.pop(0) existing_element = self.get_existing_element(subelement) if existing_element: self.added_elements[subelement.id()] = existing_element if not self.has_whitelisted_inverses(existing_element): self.check_inverses(subelement) - break - self.added_elements[subelement.id()] = self.file.add(subelement) - self.check_inverses(subelement) + else: + self.added_elements[subelement.id()] = self.file.add(subelement) + self.check_inverses(subelement) + subelement_queue.extend(self.settings["library"].traverse(subelement, max_levels=1)[1:]) return new def has_whitelisted_inverses(self, element): diff --git a/src/ifcopenshell-python/test/api/project/test_append_asset.py b/src/ifcopenshell-python/test/api/project/test_append_asset.py index db67461438..9641cefb1e 100644 --- a/src/ifcopenshell-python/test/api/project/test_append_asset.py +++ b/src/ifcopenshell-python/test/api/project/test_append_asset.py @@ -116,6 +116,16 @@ class TestAppendAsset(test.bootstrap.IFC4): def test_append_a_type_product_with_its_styles(self): library = ifcopenshell.api.run("project.create_file") element = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWallType") + history = library.createIfcOwnerHistory() + element.OwnerHistory = history + + material = ifcopenshell.api.run("material.add_material", library, name="Material") + rel = ifcopenshell.api.run("material.assign_material", library, product=element, material=material) + # We share a history. This ensures that we continue to check all + # whitelisted inverses even though one of the subelements (i.e. this + # shared history) is already processed. See bug #2837. + rel.OwnerHistory = history + item = library.createIfcBoundingBox() library.createIfcStyledItem(Item=item) mapped_rep = library.createIfcShapeRepresentation(Items=[item])