mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 06:58:56 +00:00
append_asset - extend existing rels matching them by project guid
Mentioned in #6039
This commit is contained in:
@@ -206,14 +206,17 @@ class Usecase:
|
|||||||
self.target_class = "IfcPresentationStyle"
|
self.target_class = "IfcPresentationStyle"
|
||||||
return self.append_presentation_style()
|
return self.append_presentation_style()
|
||||||
|
|
||||||
|
def by_guid(self, guid: str) -> Union[ifcopenshell.entity_instance, None]:
|
||||||
|
try:
|
||||||
|
return self.file.by_guid(guid)
|
||||||
|
except RuntimeError:
|
||||||
|
return None
|
||||||
|
|
||||||
def get_existing_element(self, element: ifcopenshell.entity_instance) -> Union[ifcopenshell.entity_instance, None]:
|
def get_existing_element(self, element: ifcopenshell.entity_instance) -> Union[ifcopenshell.entity_instance, None]:
|
||||||
if element.id() in self.added_elements:
|
if element.id() in self.added_elements:
|
||||||
return self.added_elements[element.id()]
|
return self.added_elements[element.id()]
|
||||||
if element.is_a("IfcRoot"):
|
if element.is_a("IfcRoot"):
|
||||||
try:
|
return self.by_guid(element.GlobalId)
|
||||||
return self.file.by_guid(element.GlobalId)
|
|
||||||
except RuntimeError:
|
|
||||||
return None
|
|
||||||
elif not self.assume_asset_uniqueness_by_name:
|
elif not self.assume_asset_uniqueness_by_name:
|
||||||
return None
|
return None
|
||||||
elif element.is_a("IfcMaterial"):
|
elif element.is_a("IfcMaterial"):
|
||||||
@@ -364,10 +367,13 @@ class Usecase:
|
|||||||
# Check if inverse element was created before.
|
# Check if inverse element was created before.
|
||||||
# Still need to recreate it again - e.g. it could be some rel
|
# Still need to recreate it again - e.g. it could be some rel
|
||||||
# that now needs it's RelatingObjects to be extended by the current asset.
|
# that now needs it's RelatingObjects to be extended by the current asset.
|
||||||
|
existing_rel = None
|
||||||
if (new := self.reuse_identities.get(element_identity)) is not None:
|
if (new := self.reuse_identities.get(element_identity)) is not None:
|
||||||
# Currently known cases requiring attributes reassignment are rels.
|
# Currently known cases requiring attributes reassignment are rels.
|
||||||
if not new.is_a("IfcRelationship"):
|
if not new.is_a("IfcRelationship"):
|
||||||
return
|
return
|
||||||
|
elif element.is_a("IfcRelationship") and (existing_rel := self.by_guid(element.GlobalId)):
|
||||||
|
new = existing_rel
|
||||||
else:
|
else:
|
||||||
new = self.file.create_entity(element.is_a())
|
new = self.file.create_entity(element.is_a())
|
||||||
self.reuse_identities[element_identity] = new
|
self.reuse_identities[element_identity] = new
|
||||||
@@ -382,6 +388,11 @@ class Usecase:
|
|||||||
for item in attribute:
|
for item in attribute:
|
||||||
if not self.is_another_asset(item):
|
if not self.is_another_asset(item):
|
||||||
new_attribute.append(self.add_element(item))
|
new_attribute.append(self.add_element(item))
|
||||||
|
# If rel exists we need to make sure previously assigned elements are untouched
|
||||||
|
# e.g. not to assign a material or a pset from element.
|
||||||
|
if existing_rel:
|
||||||
|
new_attribute.extend(existing_rel[i])
|
||||||
|
new_attribute = list(set(new_attribute))
|
||||||
else:
|
else:
|
||||||
new_attribute = attribute
|
new_attribute = attribute
|
||||||
if new_attribute is not None:
|
if new_attribute is not None:
|
||||||
@@ -389,19 +400,12 @@ class Usecase:
|
|||||||
|
|
||||||
def is_another_asset(self, element: ifcopenshell.entity_instance) -> bool:
|
def is_another_asset(self, element: ifcopenshell.entity_instance) -> bool:
|
||||||
"""Is IFC entity from inverse attribute is another asset to append that should be skipped."""
|
"""Is IFC entity from inverse attribute is another asset to append that should be skipped."""
|
||||||
|
|
||||||
def by_guid(guid: str) -> Union[ifcopenshell.entity_instance, None]:
|
|
||||||
try:
|
|
||||||
return self.file.by_guid(guid)
|
|
||||||
except RuntimeError:
|
|
||||||
return None
|
|
||||||
|
|
||||||
if element == self.settings["element"]:
|
if element == self.settings["element"]:
|
||||||
return False
|
return False
|
||||||
elif element.is_a("IfcFeatureElement"):
|
elif element.is_a("IfcFeatureElement"):
|
||||||
# Feature elements match the target class but aren't considered "assets"
|
# Feature elements match the target class but aren't considered "assets"
|
||||||
return False
|
return False
|
||||||
elif element.is_a("IfcRoot") and by_guid(element.GlobalId) is not None:
|
elif element.is_a("IfcRoot") and self.by_guid(element.GlobalId) is not None:
|
||||||
return False
|
return False
|
||||||
elif element.is_a(self.target_class):
|
elif element.is_a(self.target_class):
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -459,6 +459,24 @@ class TestAppendAssetIFC2X3(test.bootstrap.IFC2X3):
|
|||||||
assert "Test" in pset_data
|
assert "Test" in pset_data
|
||||||
assert ifcopenshell.util.element.get_psets(element2_) == pset_data
|
assert ifcopenshell.util.element.get_psets(element2_) == pset_data
|
||||||
|
|
||||||
|
def test_update_rels_appending_subsequent_assets_identifying_rels_by_guids(self):
|
||||||
|
library = ifcopenshell.api.project.create_file(version=self.file.schema)
|
||||||
|
element1 = ifcopenshell.api.root.create_entity(library, ifc_class="IfcWall")
|
||||||
|
pset = ifcopenshell.api.pset.add_pset(library, product=element1, name="Test")
|
||||||
|
element2 = ifcopenshell.api.root.create_entity(library, ifc_class="IfcWall")
|
||||||
|
pset_rel = ifcopenshell.api.pset.assign_pset(library, pset=pset, products=[element2])
|
||||||
|
assert pset_rel
|
||||||
|
pset_rel_guid: str = pset_rel.GlobalId
|
||||||
|
|
||||||
|
element1_ = ifcopenshell.api.project.append_asset(self.file, library, element1)
|
||||||
|
element2_ = ifcopenshell.api.project.append_asset(self.file, library, element2)
|
||||||
|
pset_data = ifcopenshell.util.element.get_psets(element1_)
|
||||||
|
|
||||||
|
appended_rels = [e for e in self.file.by_type("IfcRelDefinesByProperties") if e.GlobalId == pset_rel_guid]
|
||||||
|
assert len(appended_rels) == 1
|
||||||
|
assert set(appended_rels[0].RelatedObjects) == {element1_, element2_}
|
||||||
|
assert ifcopenshell.util.element.get_psets(element2_) == pset_data
|
||||||
|
|
||||||
def test_reuse_identities_to_avoid_removed_entities_and_possible_crashes(self):
|
def test_reuse_identities_to_avoid_removed_entities_and_possible_crashes(self):
|
||||||
self.file.create_entity("IfcProject")
|
self.file.create_entity("IfcProject")
|
||||||
context = ifcopenshell.api.context.add_context(self.file, context_type="Model")
|
context = ifcopenshell.api.context.add_context(self.file, context_type="Model")
|
||||||
|
|||||||
Reference in New Issue
Block a user