append_asset option to avoid assuming unique names for assets #5391

This commit is contained in:
Andrej730
2024-10-02 17:22:56 +05:00
parent d5fddd5f1b
commit 104b6f5564
@@ -44,6 +44,7 @@ def append_asset(
library: ifcopenshell.file, library: ifcopenshell.file,
element: ifcopenshell.entity_instance, element: ifcopenshell.entity_instance,
reuse_identities: Optional[dict[int, ifcopenshell.entity_instance]] = None, reuse_identities: Optional[dict[int, ifcopenshell.entity_instance]] = None,
assume_asset_uniqueness_by_name: bool = True,
) -> ifcopenshell.entity_instance: ) -> ifcopenshell.entity_instance:
"""Appends an asset from a library into the active project """Appends an asset from a library into the active project
@@ -61,18 +62,16 @@ def append_asset(
Do not mix units. Do not mix units.
:param library: The file object containing the asset. :param library: The file object containing the asset.
:type library: ifcopenshell.file
:param element: An element in the library file of the asset. It may be :param element: An element in the library file of the asset. It may be
an IfcTypeProduct, IfcProduct, IfcMaterial, IfcCostSchedule, or an IfcTypeProduct, IfcProduct, IfcMaterial, IfcCostSchedule, or
IfcProfileDef. IfcProfileDef.
:type element: ifcopenshell.entity_instance
:param reuse_identities: Optional dictionary of mapped entities' identities to the :param reuse_identities: Optional dictionary of mapped entities' identities to the
already created elements. It will be used to avoid creating already created elements. It will be used to avoid creating
duplicated inverse elements during multiple `project.append_asset` calls. If you want duplicated inverse elements during multiple `project.append_asset` calls. If you want
to add just 1 asset or if added assets won't have any shared elements, then it can be left empty. to add just 1 asset or if added assets won't have any shared elements, then it can be left empty.
:type reuse_identities: dict[int, ifcopenshell.entity_instance] :param assume_asset_uniqueness_by_name: If True, checks if elements (profiles, materials, styles)
with the same name already exist in the project and reuses them instead of appending new ones.
:return: The appended element :return: The appended element
:rtype: ifcopenshell.entity_instance
Example: Example:
@@ -135,6 +134,7 @@ def append_asset(
"library": library, "library": library,
"element": element, "element": element,
"reuse_identities": {} if reuse_identities is None else reuse_identities, "reuse_identities": {} if reuse_identities is None else reuse_identities,
"assume_asset_uniqueness_by_name": assume_asset_uniqueness_by_name,
} }
return usecase.execute() return usecase.execute()
@@ -142,6 +142,7 @@ def append_asset(
class Usecase: class Usecase:
file: ifcopenshell.file file: ifcopenshell.file
settings: dict[str, Any] settings: dict[str, Any]
assume_asset_uniqueness_by_name: bool
def execute(self): def execute(self):
# mapping of old element ids to new elements # mapping of old element ids to new elements
@@ -149,6 +150,7 @@ class Usecase:
self.reuse_identities: dict[int, ifcopenshell.entity_instance] = self.settings["reuse_identities"] self.reuse_identities: dict[int, ifcopenshell.entity_instance] = self.settings["reuse_identities"]
self.whitelisted_inverse_attributes = {} self.whitelisted_inverse_attributes = {}
self.base_material_class = "IfcMaterial" if self.file.schema == "IFC2X3" else "IfcMaterialDefinition" self.base_material_class = "IfcMaterial" if self.file.schema == "IFC2X3" else "IfcMaterialDefinition"
self.assume_asset_uniqueness_by_name = self.settings["assume_asset_uniqueness_by_name"]
if self.settings["element"].is_a("IfcTypeProduct"): if self.settings["element"].is_a("IfcTypeProduct"):
self.target_class = "IfcTypeProduct" self.target_class = "IfcTypeProduct"
@@ -177,6 +179,8 @@ class Usecase:
return self.file.by_guid(element.GlobalId) return self.file.by_guid(element.GlobalId)
except RuntimeError: except RuntimeError:
return None return None
elif not self.assume_asset_uniqueness_by_name:
return None
elif element.is_a("IfcMaterial"): elif element.is_a("IfcMaterial"):
material_name = element.Name material_name = element.Name
return next((e for e in self.file.by_type("IfcMaterial") if e.Name == material_name), None) return next((e for e in self.file.by_type("IfcMaterial") if e.Name == material_name), None)