diff --git a/src/speckleifc/converter/spatial_element_to_speckle.py b/src/speckleifc/converter/spatial_element_converter.py similarity index 57% rename from src/speckleifc/converter/spatial_element_to_speckle.py rename to src/speckleifc/converter/spatial_element_converter.py index 6afae05..ba90fce 100644 --- a/src/speckleifc/converter/spatial_element_to_speckle.py +++ b/src/speckleifc/converter/spatial_element_converter.py @@ -1,31 +1,38 @@ from typing import cast from ifcopenshell.entity_instance import entity_instance -from ifcopenshell.ifcopenshell_wrapper import Triangulation +from ifcopenshell.ifcopenshell_wrapper import Triangulation, TriangulationElement from specklepy.objects.data_objects import DataObject from speckleifc.converter.geometry_converter import geometry_to_speckle -from speckleifc.ifc_geometry_processing import get_shape -def spatial_element_to_speckle(step_element: entity_instance) -> DataObject: - if step_element.Representation is not None: - shape = get_shape(step_element) +def spatial_element_to_speckle( + step_element: entity_instance, shape: TriangulationElement | None +) -> DataObject: + + if shape is not None: geometry = cast(Triangulation, shape.geometry) display_value = geometry_to_speckle(geometry) else: display_value = [] + guid = cast(str, step_element.GlobalId) + name = cast(str, step_element.Name or step_element.LongName or guid) data_object = DataObject( - applicationId=cast(str, shape.guid), + applicationId=guid, properties={}, - name=cast(str, shape.name) or cast(str, shape.guid), + name=name, displayValue=display_value, ) # TODO: children as "elements" # data_object["@elements"] = children_converter.convert_children(shape, ifc_model) - data_object["ifcType"] = step_element.is_a() data_object["expressId"] = step_element.id() + data_object["ifcType"] = step_element.is_a() data_object["description"] = cast(str | None, step_element.Description) + data_object["objectType"] = step_element.ObjectType + data_object["compositionType"] = step_element.CompositionType + data_object["longName"] = step_element.LongName + return data_object diff --git a/src/speckleifc/importer.py b/src/speckleifc/importer.py index 36bf6ca..81da767 100644 --- a/src/speckleifc/importer.py +++ b/src/speckleifc/importer.py @@ -8,7 +8,8 @@ from specklepy.objects import Base from specklepy.objects.models.collections.collection import Collection from speckleifc.converter.data_object_converter import data_object_to_speckle -from speckleifc.ifc_geometry_processing import create_geometry_iterator +from speckleifc.converter.spatial_element_converter import spatial_element_to_speckle +from speckleifc.ifc_geometry_processing import create_geometry_iterator, get_shape from speckleifc.root_object_builder import RootObjectBuilder @@ -40,16 +41,23 @@ class ImportJob: step_element = self._ifc_file.by_id(step_id) converted = self.convert_geometry_element(shape, step_element) - self.builder.include_shape(converted, shape) + self.builder.include_object(converted, step_element, shape) if not geometry_iterator.next(): break def _convert_spatial_elements(self) -> None: - spatial_elements = self._ifc_file.by_type("IfcSpatialElement") + spatial_elements = self._ifc_file.by_type("IfcProject") - for element in spatial_elements: - element + for step_element in spatial_elements: + shape = ( + get_shape(step_element) + if step_element.Representation is not None + else None + ) + + converted = spatial_element_to_speckle(step_element, shape) + self.builder.include_object(converted, step_element, shape) @staticmethod def convert_geometry_element( diff --git a/src/speckleifc/root_object_builder.py b/src/speckleifc/root_object_builder.py index af5dc14..42759db 100644 --- a/src/speckleifc/root_object_builder.py +++ b/src/speckleifc/root_object_builder.py @@ -2,7 +2,9 @@ from collections.abc import Sequence from typing import cast from attrs import define +from ifcopenshell.entity_instance import entity_instance from ifcopenshell.ifcopenshell_wrapper import Element +from ifcopenshell.util.element import get_container from specklepy.objects.base import Base from specklepy.objects.graph_traversal.commit_object_builder import ( get_detached_prop, @@ -24,14 +26,22 @@ class RootObjectBuilder: self.converted = {} self._parent_infos = {} - def include_shape(self, conversion_result: Base, shape: Element) -> None: - step_id = cast(int, shape.id) - + def include_object( + self, + conversion_result: Base, + step_element: entity_instance, + shape: Element | None, + ) -> None: + step_id = cast(int, step_element.id) self.converted[step_id] = conversion_result - self.set_relationship( - step_id, ((cast(int, shape.parent_id), ELEMENTS), (ROOT, ELEMENTS)) - ) + if shape is None: + parent = get_container(step_element) + parent_id = cast(int, parent.id) if parent else None + else: + parent_id = cast(int, shape.parent_id) + + self.set_relationship(step_id, ((parent_id, ELEMENTS), (ROOT, ELEMENTS))) def build_commit_object(self, root_commit_object: Base) -> None: self.apply_relationships(root_commit_object)