mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-29 03:37:21 +00:00
Fix util.element for cases with multiple rels #5713
Got report that there was an issue with get_parts not returning all parts if there are multiple IfcRelAggregates involved though it is valid ifc. Fixed the same possible issue for ContainsElements, IsNestedBy
This commit is contained in:
@@ -1166,10 +1166,13 @@ def get_parts(element: ifcopenshell.entity_instance) -> list[ifcopenshell.entity
|
|||||||
element = file.by_type("IfcElementAssembly")[0]
|
element = file.by_type("IfcElementAssembly")[0]
|
||||||
parts = ifcopenshell.util.element.get_parts(element)
|
parts = ifcopenshell.util.element.get_parts(element)
|
||||||
"""
|
"""
|
||||||
if (is_decomposed_by := getattr(element, "IsDecomposedBy", None)) is not None and is_decomposed_by:
|
objects: list[ifcopenshell.entity_instance] = []
|
||||||
if is_decomposed_by[0].is_a("IfcRelAggregates"):
|
is_not_ifc2x3 = element.file.schema != "IFC2X3"
|
||||||
return is_decomposed_by[0].RelatedObjects
|
if is_decomposed_by := getattr(element, "IsDecomposedBy", ()):
|
||||||
return []
|
for rel in is_decomposed_by:
|
||||||
|
if is_not_ifc2x3 or rel.is_a("IfcRelAggregates"):
|
||||||
|
objects.extend(rel.RelatedObjects)
|
||||||
|
return objects
|
||||||
|
|
||||||
|
|
||||||
def get_contained(element: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]:
|
def get_contained(element: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]:
|
||||||
@@ -1186,12 +1189,16 @@ def get_contained(element: ifcopenshell.entity_instance) -> list[ifcopenshell.en
|
|||||||
element = file.by_type("IfcBuildingStorey")[0]
|
element = file.by_type("IfcBuildingStorey")[0]
|
||||||
elements = ifcopenshell.util.element.get_contained(element)
|
elements = ifcopenshell.util.element.get_contained(element)
|
||||||
"""
|
"""
|
||||||
if (rel := getattr(element, "ContainsElements", None)) is not None and rel:
|
objects: list[ifcopenshell.entity_instance] = []
|
||||||
return rel[0].RelatedElements
|
if contains_elements := getattr(element, "ContainsElements", ()):
|
||||||
return []
|
for rel in contains_elements:
|
||||||
|
objects.extend(rel.RelatedElements)
|
||||||
|
return objects
|
||||||
|
|
||||||
|
|
||||||
def get_components(element: ifcopenshell.entity_instance, include_ports=False) -> list[ifcopenshell.entity_instance]:
|
def get_components(
|
||||||
|
element: ifcopenshell.entity_instance, include_ports: bool = False
|
||||||
|
) -> list[ifcopenshell.entity_instance]:
|
||||||
"""
|
"""
|
||||||
Retrieves the components of an element that have an nest relationship.
|
Retrieves the components of an element that have an nest relationship.
|
||||||
|
|
||||||
@@ -1208,15 +1215,20 @@ def get_components(element: ifcopenshell.entity_instance, include_ports=False) -
|
|||||||
element = file.by_type("IfcElementAssembly")[0]
|
element = file.by_type("IfcElementAssembly")[0]
|
||||||
components = ifcopenshell.util.element.get_components(element)
|
components = ifcopenshell.util.element.get_components(element)
|
||||||
"""
|
"""
|
||||||
if (is_nested_by := getattr(element, "IsNestedBy", None)) is not None:
|
objects: list[ifcopenshell.entity_instance] = []
|
||||||
if is_nested_by:
|
is_ifc2x3 = element.file.schema == "IFC2X3"
|
||||||
if include_ports:
|
if is_ifc2x3:
|
||||||
return is_nested_by[0].RelatedObjects
|
if is_decomposed_by := getattr(element, "IsDecomposedBy", ()):
|
||||||
return [e for e in is_nested_by[0].RelatedObjects if not e.is_a("IfcPort")]
|
for rel in is_decomposed_by:
|
||||||
elif (is_decomposed_by := getattr(element, "IsDecomposedBy", None)) is not None and is_decomposed_by:
|
if rel.is_a("IfcRelNests"):
|
||||||
if is_decomposed_by[0].is_a("IfcRelNests"):
|
objects.extend(rel.RelatedObjects)
|
||||||
return is_decomposed_by[0].RelatedObjects
|
else:
|
||||||
return []
|
if is_nested_by := getattr(element, "IsNestedBy", None):
|
||||||
|
for rel in is_nested_by:
|
||||||
|
objects.extend(rel.RelatedObjects)
|
||||||
|
if include_ports:
|
||||||
|
return objects
|
||||||
|
return [e for e in objects if not e.is_a("IfcPort")]
|
||||||
|
|
||||||
|
|
||||||
ReferenceData = namedtuple("ReferenceData", "inverse_attribute, rel_class, relating_element_attribute")
|
ReferenceData = namedtuple("ReferenceData", "inverse_attribute, rel_class, relating_element_attribute")
|
||||||
|
|||||||
Reference in New Issue
Block a user