mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-06 07:51:47 +00:00
Bonsai - cache get_user and get_application for a speed-up
This commit is contained in:
@@ -24,6 +24,7 @@ import ifcopenshell.util.unit
|
||||
import ifcopenshell.api.owner.settings
|
||||
import bonsai.bim
|
||||
import bonsai.tool as tool
|
||||
import weakref
|
||||
from bpy.app.handlers import persistent
|
||||
from bonsai.bim.ifc import IfcStore
|
||||
from bonsai.bim.module.model.data import AuthoringData
|
||||
@@ -257,24 +258,61 @@ def redo_post(scene: bpy.types.Scene) -> None:
|
||||
tool.Ifc.rebuild_element_maps()
|
||||
|
||||
|
||||
# Cache is important as those entities will be retrieved very often,
|
||||
# for every IfcOwnerHistory creation or update.
|
||||
class SettingsCache:
|
||||
APPLICATION_ID: Union[int, None] = None
|
||||
USER_ID: Union[int, None] = None
|
||||
|
||||
_file: Union[weakref.ReferenceType[ifcopenshell.file], None] = None
|
||||
|
||||
@classmethod
|
||||
def get_file(cls) -> Union[ifcopenshell.file, None]:
|
||||
if cls._file is None:
|
||||
return None
|
||||
return cls._file()
|
||||
|
||||
@classmethod
|
||||
def set_file(cls, file: ifcopenshell.file) -> None:
|
||||
cls._file = weakref.ref(file)
|
||||
|
||||
|
||||
def get_application(ifc: ifcopenshell.file) -> ifcopenshell.entity_instance:
|
||||
# TODO: cache this for even faster application retrieval. It honestly makes a difference on long scripts.
|
||||
if SettingsCache.get_file() is ifc and SettingsCache.APPLICATION_ID is not None:
|
||||
try:
|
||||
app = ifc.by_id(SettingsCache.APPLICATION_ID)
|
||||
return app
|
||||
except RuntimeError:
|
||||
pass
|
||||
|
||||
# Use only main part from the version to avoid flooding advanced users projects with IfcApplications.
|
||||
version = tool.Blender.get_bonsai_version().split("-")[0]
|
||||
for element in ifc.by_type("IfcApplication"):
|
||||
if element.ApplicationIdentifier == "Bonsai" and element.Version == version:
|
||||
return element
|
||||
return ifcopenshell.api.owner.add_application(
|
||||
application = ifcopenshell.api.owner.add_application(
|
||||
ifc,
|
||||
version=version,
|
||||
application_full_name="Bonsai",
|
||||
application_identifier="Bonsai",
|
||||
)
|
||||
SettingsCache.APPLICATION_ID = application.id()
|
||||
SettingsCache.set_file(ifc)
|
||||
return application
|
||||
|
||||
|
||||
def get_user(ifc: ifcopenshell.file) -> Union[ifcopenshell.entity_instance, None]:
|
||||
# TODO: cache this for even faster application retrieval. It honestly makes a difference on long scripts.
|
||||
if SettingsCache.get_file() is ifc and SettingsCache.USER_ID is not None:
|
||||
try:
|
||||
user = ifc.by_id(SettingsCache.USER_ID)
|
||||
return user
|
||||
except RuntimeError:
|
||||
pass
|
||||
|
||||
if pao := next(iter(ifc.by_type("IfcPersonAndOrganization")), None):
|
||||
SettingsCache.USER_ID = pao.id()
|
||||
SettingsCache.set_file(ifc)
|
||||
return pao
|
||||
elif ifc.schema == "IFC2X3":
|
||||
if (person := next(iter(ifc.by_type("IfcPerson")), None)) is None:
|
||||
@@ -282,6 +320,8 @@ def get_user(ifc: ifcopenshell.file) -> Union[ifcopenshell.entity_instance, None
|
||||
if (organization := next(iter(ifc.by_type("IfcOrganization")), None)) is None:
|
||||
organization = ifcopenshell.api.owner.add_organisation(ifc)
|
||||
pao = ifcopenshell.api.owner.add_person_and_organisation(ifc, person=person, organisation=organization)
|
||||
SettingsCache.USER_ID = pao.id()
|
||||
SettingsCache.set_file(ifc)
|
||||
return pao
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user