Files
speckleifc/src/speckleifc/root_object_builder.py
T
Jedd Morgan f937df95e0 first pass
2025-06-19 10:04:15 +01:00

82 lines
2.4 KiB
Python

from collections.abc import Sequence
from typing import cast
from attrs import define
from ifcopenshell.ifcopenshell_wrapper import Element
from specklepy.objects.base import Base
from specklepy.objects.graph_traversal.commit_object_builder import (
get_detached_prop,
set_detached_prop,
)
ROOT: int = -1
ELEMENTS = "elements"
PARENT_INFO = tuple[int | None, str]
@define(slots=True)
class RootObjectBuilder:
converted: dict[int, Base]
_parent_infos: dict[int, Sequence[PARENT_INFO]]
def __init__(self) -> None:
self.converted = {}
self._parent_infos = {}
def include_shape(self, conversion_result: Base, shape: Element) -> None:
step_id = cast(int, shape.id)
self.converted[step_id] = conversion_result
self.set_relationship(
step_id, ((cast(int, shape.parent_id), ELEMENTS), (ROOT, ELEMENTS))
)
def build_commit_object(self, root_commit_object: Base) -> None:
self.apply_relationships(root_commit_object)
def set_relationship(
self, step_id: int, parent_info: Sequence[PARENT_INFO]
) -> None:
self._parent_infos[step_id] = parent_info
def apply_relationships(self, root_commit_object: Base) -> None:
for step_id, c in self.converted.items():
try:
self.apply_relationship(c, step_id, root_commit_object)
except Exception as ex:
print(f"Failed to add object {type(c)} to commit object: {ex}")
def apply_relationship(
self, current: Base, step_id: int, root_commit_object: Base
) -> None:
parents = self._parent_infos[step_id]
for parent_id, prop_name in parents:
if not parent_id:
continue
parent: Base | None
if parent_id == ROOT:
parent = root_commit_object
else:
parent = self.converted.get(parent_id, None)
if not parent:
continue
elements = get_detached_prop(parent, prop_name)
if not isinstance(elements, list):
elements = []
set_detached_prop(parent, prop_name, elements)
elements.append(current)
return
raise Exception(
f"Could not find a valid parent for object of type {type(current)}."
f"Checked {len(parents)} potential parent, and non were converted!"
)