ExtractElements - fix bug where IfcElementAssembly elements wasn't added to the spatial tree

Example issue - https://community.osarch.org/discussion/2054/bbim-extractelements-patch-and-missing-elements-in-ifcelementassembly
This commit is contained in:
Andrej730
2024-03-27 16:59:10 +05:00
parent a37c87cf4c
commit c2de964dce
@@ -52,8 +52,8 @@ class Patcher:
self.query = query self.query = query
def patch(self): def patch(self):
self.contained_ins = {} self.contained_ins: dict[str, set[ifcopenshell.entity_instance]] = {}
self.aggregates = {} self.aggregates: dict[str, set[ifcopenshell.entity_instance]] = {}
self.new = ifcopenshell.file(schema=self.file.wrapped_data.schema) self.new = ifcopenshell.file(schema=self.file.wrapped_data.schema)
self.owner_history = None self.owner_history = None
self.reuse_identities: dict[int, ifcopenshell.entity_instance] = {} self.reuse_identities: dict[int, ifcopenshell.entity_instance] = {}
@@ -66,18 +66,14 @@ class Patcher:
self.create_spatial_tree() self.create_spatial_tree()
self.file = self.new self.file = self.new
def add_element(self, element) -> None: def add_element(self, element: ifcopenshell.entity_instance) -> None:
new_element = self.append_asset(element) new_element = self.append_asset(element)
if not new_element: if not new_element:
return return
for rel in getattr(element, "ContainedInStructure", []): self.add_spatial_structures(element, new_element)
spatial_element = rel.RelatingStructure
new_spatial_element = self.append_asset(spatial_element)
self.contained_ins.setdefault(spatial_element.GlobalId, set()).add(new_element)
self.add_decomposition_parents(spatial_element, new_spatial_element)
self.add_decomposition_parents(element, new_element) self.add_decomposition_parents(element, new_element)
def append_asset(self, element) -> Union[ifcopenshell.entity_instance, None]: def append_asset(self, element: ifcopenshell.entity_instance) -> Union[ifcopenshell.entity_instance, None]:
try: try:
return self.new.by_guid(element.GlobalId) return self.new.by_guid(element.GlobalId)
except: except:
@@ -88,29 +84,43 @@ class Patcher:
"project.append_asset", self.new, library=self.file, element=element, reuse_identities=self.reuse_identities "project.append_asset", self.new, library=self.file, element=element, reuse_identities=self.reuse_identities
) )
def add_decomposition_parents(self, element, new_element) -> None: def add_spatial_structures(
self, element: ifcopenshell.entity_instance, new_element: ifcopenshell.entity_instance
) -> None:
"""element is IfcElement"""
for rel in getattr(element, "ContainedInStructure", []):
spatial_element = rel.RelatingStructure
new_spatial_element = self.append_asset(spatial_element)
self.contained_ins.setdefault(spatial_element.GlobalId, set()).add(new_element)
self.add_decomposition_parents(spatial_element, new_spatial_element)
def add_decomposition_parents(
self, element: ifcopenshell.entity_instance, new_element: ifcopenshell.entity_instance
) -> None:
"""element is IfcObjectDefinition"""
for rel in element.Decomposes: for rel in element.Decomposes:
parent = rel.RelatingObject parent = rel.RelatingObject
new_parent = self.append_asset(parent) new_parent = self.append_asset(parent)
self.aggregates.setdefault(parent.GlobalId, set()).add(new_element) self.aggregates.setdefault(parent.GlobalId, set()).add(new_element)
self.add_decomposition_parents(parent, new_parent) self.add_decomposition_parents(parent, new_parent)
self.add_spatial_structures(parent, new_parent)
def create_spatial_tree(self) -> None: def create_spatial_tree(self) -> None:
for relating_structure, related_elements in self.contained_ins.items(): for relating_structure_guid, related_elements in self.contained_ins.items():
self.new.createIfcRelContainedInSpatialStructure( self.new.createIfcRelContainedInSpatialStructure(
ifcopenshell.guid.new(), ifcopenshell.guid.new(),
self.owner_history, self.owner_history,
None, None,
None, None,
list(related_elements), list(related_elements),
self.new.by_guid(relating_structure), self.new.by_guid(relating_structure_guid),
) )
for relating_object, related_objects in self.aggregates.items(): for relating_object_guid, related_objects in self.aggregates.items():
self.new.createIfcRelAggregates( self.new.createIfcRelAggregates(
ifcopenshell.guid.new(), ifcopenshell.guid.new(),
self.owner_history, self.owner_history,
None, None,
None, None,
self.new.by_guid(relating_object), self.new.by_guid(relating_object_guid),
list(related_objects), list(related_objects),
) )