Project library dropdown - show only libraries compatible with the current schema

To prevent errors trying to append elements from the wrong schema library
This commit is contained in:
Andrej730
2024-09-27 17:47:52 +05:00
parent 24a6ed0e5c
commit 0dff19ba6a
2 changed files with 27 additions and 2 deletions
+26 -2
View File
@@ -19,7 +19,10 @@
import os import os
import bpy import bpy
import bonsai.tool as tool import bonsai.tool as tool
import ifcopenshell.util.file
from bonsai.bim.ifc import IfcStore from bonsai.bim.ifc import IfcStore
from pathlib import Path
from typing import Union
def refresh(): def refresh():
@@ -30,6 +33,7 @@ def refresh():
class ProjectData: class ProjectData:
data = {} data = {}
is_loaded = False is_loaded = False
filepath_schema_cache: dict[Path, Union[str, None]] = {}
@classmethod @classmethod
def load(cls): def load(cls):
@@ -41,15 +45,35 @@ class ProjectData:
} }
cls.is_loaded = True cls.is_loaded = True
@classmethod
def get_file_schema(cls, filepath: Path) -> Union[str, None]:
# Let's assume that filepath won't be changing schema during current Blender session
# to avoid reading header from the library files on every UI update.
# If it will be an issue, we can also consider last modified time.
if filepath not in cls.filepath_schema_cache:
extractor = ifcopenshell.util.file.IfcHeaderExtractor(str(filepath))
schema_name = extractor.extract().get("schema_name")
cls.filepath_schema_cache[filepath] = schema_name
return cls.filepath_schema_cache[filepath]
@classmethod @classmethod
def get_export_schema(cls): def get_export_schema(cls):
return [(s, "IFC4X3" if s == "IFC4X3_ADD2" else s, "") for s in IfcStore.schema_identifiers] return [(s, "IFC4X3" if s == "IFC4X3_ADD2" else s, "") for s in IfcStore.schema_identifiers]
@classmethod @classmethod
def library_file(cls): def library_file(cls):
files = os.listdir(os.path.join(bpy.context.scene.BIMProperties.data_dir, "libraries")) ifc_file = tool.Ifc.get()
if not ifc_file:
return []
current_schema = tool.Ifc.get().schema_identifier
files = (Path(bpy.context.scene.BIMProperties.data_dir) / "libraries").iterdir()
results = [("0", "Custom Library", "")] results = [("0", "Custom Library", "")]
results.extend([(f, os.path.splitext(f)[0], "") for f in files if ".ifc" in f]) for f in files:
if not f.suffix.lower().startswith(".ifc"):
continue
if cls.get_file_schema(f) != current_schema:
continue
results.append((f.name, f.stem, "Library"))
return results return results
@classmethod @classmethod
@@ -23,6 +23,7 @@ from typing_extensions import NotRequired
class HeaderMetadata(TypedDict): class HeaderMetadata(TypedDict):
name: NotRequired[str] name: NotRequired[str]
# FILE_DESCRIPTION, not the description from FILE_NAME.
description: NotRequired[str] description: NotRequired[str]
implementation_level: NotRequired[str] implementation_level: NotRequired[str]
time_stamp: NotRequired[str] time_stamp: NotRequired[str]