move to existing traversal

This commit is contained in:
bimgeek
2025-08-19 21:54:40 +03:00
parent 1afabcae12
commit 5f8efecdcc
4 changed files with 42 additions and 46 deletions
@@ -11,13 +11,20 @@ def data_object_to_speckle(
display_value: list[Base],
step_element: entity_instance,
children: list[Base],
current_storey: str | None = None,
) -> DataObject:
guid = cast(str, step_element.GlobalId)
name = cast(str, step_element.Name or guid)
properties = extract_properties(step_element)
# Add building storey information if available and not a building storey itself
if current_storey and not step_element.is_a("IfcBuildingStorey"):
properties["Building Storey"] = current_storey
data_object = DataObject(
applicationId=guid,
properties=extract_properties(step_element),
properties=properties,
name=name or guid,
displayValue=display_value,
)
@@ -12,8 +12,11 @@ def spatial_element_to_speckle(
display_value: list[Base],
step_element: entity_instance,
relational_children: list[Base],
current_storey: str | None = None,
) -> Collection:
direct_geometry = _convert_as_data_object(display_value, step_element)
direct_geometry = _convert_as_data_object(
display_value, step_element, current_storey
)
all_children = [direct_geometry] + relational_children
guid = cast(str, step_element.GlobalId)
@@ -26,13 +29,22 @@ def spatial_element_to_speckle(
def _convert_as_data_object(
display_value: list[Base], step_element: entity_instance
display_value: list[Base],
step_element: entity_instance,
current_storey: str | None = None,
) -> DataObject:
guid = cast(str, step_element.GlobalId)
name = cast(str, step_element.Name or step_element.LongName or guid)
properties = extract_properties(step_element)
# Add building storey information if available and not a building storey itself
if current_storey and not step_element.is_a("IfcBuildingStorey"):
properties["Building Storey"] = current_storey
data_object = DataObject(
applicationId=guid,
properties=extract_properties(step_element),
properties=properties,
name=name,
displayValue=display_value,
)
+19 -3
View File
@@ -26,8 +26,16 @@ class ImportJob:
)
geometries_count: int = 0
geometries_used: int = 0
_current_storey: str | None = field(default=None, init=False)
def convert_element(self, step_element: entity_instance) -> Base:
# Track current storey context
previous_storey = self._current_storey
if step_element.is_a("IfcBuildingStorey"):
self._current_storey = (
step_element.Name or step_element.LongName or step_element.GlobalId
)
children = self._convert_children(step_element)
display_value = self.cached_display_values.get(step_element.id(), [])
@@ -35,11 +43,19 @@ class ImportJob:
self.geometries_used += 1
if step_element.is_a("IfcProject"):
return project_to_speckle(step_element, children)
result = project_to_speckle(step_element, children)
elif step_element.is_a("IfcSpatialStructureElement"):
return spatial_element_to_speckle(display_value, step_element, children)
result = spatial_element_to_speckle(
display_value, step_element, children, self._current_storey
)
else:
return data_object_to_speckle(display_value, step_element, children)
result = data_object_to_speckle(
display_value, step_element, children, self._current_storey
)
# Restore previous storey context
self._current_storey = previous_storey
return result
def _convert_children(self, step_element: entity_instance) -> list[Base]:
return [
-39
View File
@@ -10,10 +10,6 @@ def extract_properties(element: entity_instance) -> dict[str, object]:
"Property Sets": _get_ifc_object_properties(element),
}
# Add building storey information if element is contained in a storey
if storey_name := _get_containing_storey(element):
properties["Building Storey"] = storey_name
if (ifc_type := get_type(element)) is not None:
properties["Element Type Property Sets"] = _get_ifc_element_type_properties(
ifc_type,
@@ -94,38 +90,3 @@ def _get_properties(properties: entity_instance) -> dict[str, Any]:
# elif prop.is_a("IfcPropertyTableValue"):
# properties[name] = #not sure if we want to support these...
return result
def _get_containing_storey(element: entity_instance) -> str | None:
"""
Find the containing IfcBuildingStorey for an element by traversing up
the spatial hierarchy. Returns the storey name if found, None otherwise.
"""
# Check if element has spatial containment relationships
containment_rels = getattr(element, "ContainedInStructure", None)
if not containment_rels:
return None
# Traverse the spatial containment relationships
for rel in containment_rels:
if not rel.is_a("IfcRelContainedInSpatialStructure"):
continue
relating_structure = getattr(rel, "RelatingStructure", None)
if not relating_structure:
continue
# Check if this structure is a building storey
if relating_structure.is_a("IfcBuildingStorey"):
return (
relating_structure.Name
or relating_structure.LongName
or relating_structure.GlobalId
)
# If not, recursively check the parent structure
parent_storey = _get_containing_storey(relating_structure)
if parent_storey:
return parent_storey
return None