Allow Undefined topology representations for IfcStructuralPointConnection #6459

Because apparently it's not invalid IFC.
IfcStructuralPointConnection documentation says that they should have a topology representation with a IfcVertexPoint but it doesn't restict this representation from having Undefined type if it does have a IfcVertexPoint as it's item.
This commit is contained in:
Andrej730
2025-04-14 17:14:00 +05:00
parent 53cd5f834e
commit 1516237537
3 changed files with 49 additions and 3 deletions
+9 -3
View File
@@ -717,9 +717,15 @@ class IfcImporter:
def create_structural_point_connections(self):
for product in self.file.by_type("IfcStructuralPointConnection"):
# TODO: make this based off ifcopenshell. See #1409
representation: ifcopenshell.entity_instance = next(
rep for rep in product.Representation.Representations if rep.RepresentationType == "Vertex"
)
representation = tool.Structural.get_vertex_representation(product)
if not representation:
print(
"WARNING. Skipping invalid IfcStructuralPointConnection - "
f"element has no valid representation:\n{product}."
)
continue
mesh = tool.Loader.create_structural_point_connection_mesh(representation)
if mesh is None:
continue
+1
View File
@@ -799,6 +799,7 @@ class Loader(bonsai.core.tool.Loader):
# TODO implement non cartesian point vertices.
if not point.is_a("IfcCartesianPoint"):
print(f"WARNING. Unsupported point type for IfcStructuralPointConnection: {point}.")
return
ifc_file = tool.Ifc.get()
+39
View File
@@ -172,3 +172,42 @@ class Structural(bonsai.core.tool.Structural):
new = props.structural_analysis_models.add()
new.ifc_definition_id = ifc_definition_id
new.name = model["Name"] or "Unnamed"
@classmethod
def get_vertex_representation(
cls, product: ifcopenshell.entity_instance
) -> Union[ifcopenshell.entity_instance, None]:
"""
:param product: IfcStructuralPointConnection
:return: IfcTopologyRepresentation if it's valid.
"""
vertex_representation, undefined_representation = None, None
# At least 1 representation is mandatory in IFC for IfcStructuralPointConnection.
for rep in product.Representation.Representations:
rep: ifcopenshell.entity_instance
rep_type: str = rep.RepresentationType
if rep_type == "Vertex":
vertex_representation = rep
break
# It's possible to have 'Undefined' or some other non-predefined type.
elif rep_type not in ("Edge", "Path", "Face", "Shell"):
undefined_representation = rep
if not vertex_representation and not undefined_representation:
return
# All other checks in this case are covered by IFC validation.
if vertex_representation:
items = vertex_representation.Items
if len(items) != 1:
return None
return vertex_representation
if undefined_representation is None:
return
items = undefined_representation.Items
if len(items) != 1 or not all(item.is_a("IfcVertex") for item in items):
return None
return undefined_representation