get_shape_aspects to consider element's type #6374

See diagram in https://github.com/IfcOpenShell/IfcOpenShell/issues/5839#issuecomment-2661296683 when IfcShapeAspect assigned to IfcRepresentationMap instead of being assigned to IfcProductDefinitionShape directly.
This commit is contained in:
Andrej730
2025-03-17 16:33:32 +05:00
parent 102de32737
commit 778a839e5f
2 changed files with 31 additions and 2 deletions
@@ -591,10 +591,16 @@ def get_types(type: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_in
return []
def get_shape_aspects(element: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]:
def get_shape_aspects(
element: ifcopenshell.entity_instance,
should_inherit: bool = True,
) -> list[ifcopenshell.entity_instance]:
"""Get element's shape aspects.
:param element: IfcProduct or IfcTypeProduct.
:param should_inherit: If True, the shape aspects of the element's type will be considered.
Useful in cases when IfcShapeAspects are assigned to the type's IfcRepresentationMap
instead of the element's IfcProductDefinitionShape.
:return: The associated shape aspects of the element.
Example:
@@ -607,7 +613,11 @@ def get_shape_aspects(element: ifcopenshell.entity_instance) -> list[ifcopenshel
# IfcProduct
if (representation := getattr(element, "Representation", ...)) != ...:
return representation.HasShapeAspects
shape_aspects: list[ifcopenshell.entity_instance] = []
if should_inherit and (element_type := get_type(element)):
shape_aspects.extend(get_shape_aspects(element_type))
shape_aspects.extend(representation.HasShapeAspects)
return shape_aspects
if element.file.schema == "IFC2X3":
return []
@@ -387,6 +387,25 @@ class TestGetShapeAspects(test.bootstrap.IFC4):
shape_aspect.PartOfProductDefinitionShape = product_shape
assert tuple(subject.get_shape_aspects(element)) == (shape_aspect,)
def test_getting_the_shape_aspects_of_a_product_with_inheritance(self):
element = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWallType")
ifcopenshell.api.type.assign_type(self.file, related_objects=[element], relating_type=element_type)
# Setup type shape aspect.
type_shape_aspect = self.file.create_entity("IfcShapeAspect")
representation_map = self.file.create_entity("IfcRepresentationMap")
element_type.RepresentationMaps = (representation_map,)
type_shape_aspect.PartOfProductDefinitionShape = representation_map
# Setup occurrence shape aspect.
occurrence_shape_aspect = self.file.create_entity("IfcShapeAspect")
product_shape = self.file.create_entity("IfcProductDefinitionShape")
element.Representation = product_shape
occurrence_shape_aspect.PartOfProductDefinitionShape = product_shape
assert subject.get_shape_aspects(element) == [type_shape_aspect, occurrence_shape_aspect]
class TestGetMaterial(test.bootstrap.IFC4):
def test_getting_the_material_of_a_product(self):