mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
api.project.append_asset deduplicate material sets
When appending a wall type and a slab type in turn, if their material layer sets have the same name then the slab type would have a wall construction. Now the material sets are compared before reusing an existing material set.
This commit is contained in:
@@ -243,6 +243,59 @@ class Usecase:
|
||||
except RuntimeError:
|
||||
return None
|
||||
|
||||
def material_sets_are_equal(self, set1: ifcopenshell.entity_instance, set2: ifcopenshell.entity_instance) -> bool:
|
||||
"""Check if two material sets are structurally equivalent."""
|
||||
if set1.is_a() != set2.is_a():
|
||||
return False
|
||||
|
||||
ifc_class = set1.is_a()
|
||||
|
||||
if ifc_class == "IfcMaterialLayerSet":
|
||||
layers1 = set1.MaterialLayers or []
|
||||
layers2 = set2.MaterialLayers or []
|
||||
if len(layers1) != len(layers2):
|
||||
return False
|
||||
for l1, l2 in zip(layers1, layers2):
|
||||
if (l1.Material is None) != (l2.Material is None):
|
||||
return False
|
||||
if l1.Material and l1.Material.Name != l2.Material.Name:
|
||||
return False
|
||||
if l1.LayerThickness != l2.LayerThickness:
|
||||
return False
|
||||
|
||||
elif ifc_class == "IfcMaterialConstituentSet":
|
||||
constituents1 = set1.MaterialConstituents or []
|
||||
constituents2 = set2.MaterialConstituents or []
|
||||
if len(constituents1) != len(constituents2):
|
||||
return False
|
||||
for c1, c2 in zip(constituents1, constituents2):
|
||||
if (c1.Material is None) != (c2.Material is None):
|
||||
return False
|
||||
if c1.Material and c1.Material.Name != c2.Material.Name:
|
||||
return False
|
||||
if c1.Name != c2.Name:
|
||||
return False
|
||||
|
||||
elif ifc_class == "IfcMaterialProfileSet":
|
||||
profiles1 = set1.MaterialProfiles or []
|
||||
profiles2 = set2.MaterialProfiles or []
|
||||
if len(profiles1) != len(profiles2):
|
||||
return False
|
||||
for p1, p2 in zip(profiles1, profiles2):
|
||||
if (p1.Material is None) != (p2.Material is None):
|
||||
return False
|
||||
if p1.Material and p1.Material.Name != p2.Material.Name:
|
||||
return False
|
||||
if (p1.Profile is None) != (p2.Profile is None):
|
||||
return False
|
||||
if p1.Profile:
|
||||
profile_name1 = getattr(p1.Profile, "ProfileName", None)
|
||||
profile_name2 = getattr(p2.Profile, "ProfileName", None)
|
||||
if profile_name1 != profile_name2:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def get_existing_element(self, element: ifcopenshell.entity_instance) -> Union[ifcopenshell.entity_instance, None]:
|
||||
"""Get existing element for a library element.
|
||||
|
||||
@@ -270,7 +323,11 @@ class Usecase:
|
||||
material_set_name = getattr(element, name_attr)
|
||||
if material_set_name is None:
|
||||
return
|
||||
return next((e for e in self.file.by_type(ifc_class) if getattr(e, name_attr) == material_set_name), None)
|
||||
for candidate in self.file.by_type(ifc_class):
|
||||
if getattr(candidate, name_attr) == material_set_name:
|
||||
if self.material_sets_are_equal(element, candidate):
|
||||
return candidate
|
||||
return None
|
||||
|
||||
elif element.is_a("IfcProfileDef"):
|
||||
profile_name = element.ProfileName
|
||||
@@ -665,12 +722,11 @@ class Usecase:
|
||||
name_attr = "LayerSetName" if ifc_class == "IfcMaterialLayerSet" else "Name"
|
||||
material_set_name = getattr(element, name_attr)
|
||||
if material_set_name is not None:
|
||||
existing_material_set = next(
|
||||
(e for e in ifc_file.by_type(ifc_class) if getattr(e, name_attr) == material_set_name), None
|
||||
)
|
||||
if existing_material_set is not None:
|
||||
reuse_identities[element_identity] = existing_material_set
|
||||
return existing_material_set
|
||||
for candidate in ifc_file.by_type(ifc_class):
|
||||
if getattr(candidate, name_attr) == material_set_name:
|
||||
if self.material_sets_are_equal(element, candidate):
|
||||
reuse_identities[element_identity] = candidate
|
||||
return candidate
|
||||
|
||||
elif element.is_a("IfcPresentationStyle"):
|
||||
style_name = element.Name
|
||||
|
||||
Reference in New Issue
Block a user