mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-22 16:31:10 +00:00
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:
@@ -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),
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user