move to existing traversal
This commit is contained in:
@@ -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,
|
||||
)
|
||||
|
||||
@@ -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 [
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user