Bonsai - support loading element types from ifcsqlite

This commit is contained in:
Andrej730
2025-09-05 10:50:54 +05:00
parent 0cf3bb3da9
commit 7b490bbc69
2 changed files with 43 additions and 1 deletions
+40 -1
View File
@@ -520,11 +520,50 @@ class IfcImporter:
def create_element_types(self):
# TODO:
if isinstance(self.file, ifcopenshell.sqlite):
print("WARNING. Loading element types from IFCSQLite is not supported.")
self.create_element_types_sqlite(self.element_types)
return
for element_type in self.element_types:
self.create_element_type(element_type)
def create_element_types_sqlite(self, element_types: set[ifcopenshell.entity_instance]) -> None:
assert isinstance(self.file, ifcopenshell.sqlite)
geometry_cache = self.file.get_geometry([e.id() for e in element_types])
geometry_meshes: dict[str, bpy.types.Mesh] = {}
for geometry_id, geometry in geometry_cache["geometry"].items():
verts = geometry["verts"]
fake_geometry = type("Geometry", (), {"id": geometry_id})
mesh_name = tool.Loader.get_mesh_name_from_shape(fake_geometry) # pyright: ignore[reportArgumentType]
mesh = bpy.data.meshes.new(mesh_name)
if geometry["faces"].size:
mesh = tool.Loader.create_mesh_from_shape(
mesh=mesh, faces=geometry["faces"].reshape(-1, 3), verts=verts.reshape(-1, 3)
)
else:
vertices = verts.reshape(-1, 3).tolist()
edges = geometry["edges"].reshape(-1, 2).tolist()
mesh.from_pydata(vertices, edges, [])
tool.Loader.link_mesh(fake_geometry, mesh) # pyright: ignore[reportArgumentType]
mesh["ios_materials"] = geometry["materials"]
mesh["ios_material_ids"] = geometry["material_ids"]
self.meshes[mesh_name] = mesh
geometry_meshes[geometry_id] = mesh
shapes = geometry_cache["shapes"]
for element in element_types:
# Allow missing element types to accomodate older ifcsqlite files
# that didn't store element types geometry.
shape = shapes.get(element.id())
if shape:
geometry_id = shapes[element.id()]["geometry"]
else:
geometry_id = None
mesh = None if geometry_id is None else geometry_meshes[geometry_id]
obj = bpy.data.objects.new(tool.Loader.get_name(element), mesh)
self.link_element(element, obj)
self.material_creator.create(element, obj, mesh, False)
def create_element_type(self, element: ifcopenshell.entity_instance) -> None:
self.ifc_import_settings.logger.info("Creating object %s", element)
mesh = None
+3
View File
@@ -1085,6 +1085,9 @@ class Model(bonsai.core.tool.Model):
# No need to preview to update, Blender will do it in background,
# `preview.icon_id` doesn't change after `asset_generate_preview()`.
obj.asset_generate_preview()
# Avoid issues with sqlite files.
elif type(tool.Ifc.get()) is not ifcopenshell.file:
return
else:
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
size = 128