Fix bug where copying types with parametric materials could lead to invalidly reused material set items.

This commit is contained in:
Dion Moult
2023-03-20 20:40:11 +11:00
parent d71e34f073
commit b6aa5c57c0
2 changed files with 18 additions and 4 deletions
@@ -131,9 +131,11 @@ class Usecase:
inverse = ifcopenshell.util.element.copy(self.file, inverse)
inverse.RelatingMaterial = ifcopenshell.util.element.copy(self.file, inverse.RelatingMaterial)
inverse.RelatedObjects = [to_element]
elif inverse.is_a("IfcRelAssociatesMaterial") and from_element.is_a("IfcTypeProduct"):
elif inverse.is_a("IfcRelAssociatesMaterial") and "Set" in inverse.RelatingMaterial.is_a():
inverse = ifcopenshell.util.element.copy(self.file, inverse)
inverse.RelatingMaterial = ifcopenshell.util.element.copy(self.file, inverse.RelatingMaterial)
inverse.RelatingMaterial = ifcopenshell.util.element.copy_deep(
self.file, inverse.RelatingMaterial, exclude=["IfcMaterial"]
)
inverse.RelatedObjects = [to_element]
else:
for i, value in enumerate(inverse):
@@ -146,6 +146,14 @@ class TestCopyClass(test.bootstrap.IFC4):
new = ifcopenshell.api.run("root.copy_class", self.file, product=door)
assert not new.FillsVoids
def test_retaining_a_single_material(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
material = self.file.createIfcMaterial()
self.file.createIfcRelAssociatesMaterial(RelatedObjects=[element], RelatingMaterial=material)
new = ifcopenshell.api.run("root.copy_class", self.file, product=element)
assert new.HasAssociations[0].RelatingMaterial == element.HasAssociations[0].RelatingMaterial
assert new.HasAssociations[0].RelatingMaterial.is_a("IfcMaterial")
def test_copying_material_set_usages(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
material = self.file.createIfcMaterialLayerSetUsage()
@@ -156,11 +164,15 @@ class TestCopyClass(test.bootstrap.IFC4):
def test_copying_material_sets_for_type_elements_only(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
material = self.file.createIfcMaterialLayerSet()
single_material = self.file.createIfcMaterial()
layer = self.file.createIfcMaterialLayer(Material=single_material)
material = self.file.createIfcMaterialLayerSet(MaterialLayers=[layer])
self.file.createIfcRelAssociatesMaterial(RelatedObjects=[element], RelatingMaterial=material)
new = ifcopenshell.api.run("root.copy_class", self.file, product=element)
assert new.HasAssociations[0].RelatingMaterial != element.HasAssociations[0].RelatingMaterial
assert new.HasAssociations[0].RelatingMaterial.is_a("IfcMaterialLayerSet")
assert new.HasAssociations[0].RelatingMaterial != element.HasAssociations[0].RelatingMaterial
assert new.HasAssociations[0].RelatingMaterial.MaterialLayers[0] != element.HasAssociations[0].RelatingMaterial.MaterialLayers[0]
assert new.HasAssociations[0].RelatingMaterial.MaterialLayers[0].Material == element.HasAssociations[0].RelatingMaterial.MaterialLayers[0].Material
def test_copying_a_type_and_purging_type_relationships(self):
type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")