Profiles UI - add safety check for missing profiles #6284

Example - https://imgur.com/a/bVdV5oB
This commit is contained in:
Andrej730
2025-03-07 13:41:45 +05:00
parent 9076deddbc
commit 85fc97eb84
3 changed files with 45 additions and 12 deletions
+26 -6
View File
@@ -21,6 +21,7 @@ import bpy.utils
import bpy.utils.previews
import ifcopenshell.util.doc
import bonsai.tool as tool
from typing import Any
def refresh():
@@ -28,7 +29,7 @@ def refresh():
class ProfileData:
data = {}
data: dict[str, Any] = {}
failed_previews: set[int] = set()
preview_collection = bpy.utils.previews.new()
is_loaded = False
@@ -37,6 +38,7 @@ class ProfileData:
def load(cls):
cls.data = {
"total_profiles": cls.total_profiles(),
"does_active_profile_exist": cls.does_active_profile_exist(),
"active_profile_users": cls.active_profile_users(),
"profile_classes": cls.profile_classes(),
"is_arbitrary_profile": cls.is_arbitrary_profile(),
@@ -50,12 +52,30 @@ class ProfileData:
return len([p for p in tool.Ifc.get().by_type("IfcProfileDef") if p.ProfileName])
@classmethod
def active_profile_users(cls):
profiles_props = tool.Profile.get_profile_props()
if profiles_props.active_profile_index >= len(profiles_props.profiles):
def update_active_profile_data(cls) -> None:
cls.data["does_active_profile_exist"] = cls.does_active_profile_exist()
cls.data["active_profile_users"] = cls.active_profile_users()
@classmethod
def does_active_profile_exist(cls) -> bool:
"""
Currently not sure if our UI is always preserving existing named profiles,
so this check is added to avoid breaking UI in case of a missing profile.
"""
active_profile = tool.Profile.get_active_profile_ui()
if active_profile is None:
return False
profile_ifc = tool.Ifc.get_entity_by_id(active_profile.ifc_definition_id)
return profile_ifc is not None
@classmethod
def active_profile_users(cls) -> int:
active_profile = tool.Profile.get_active_profile_ui()
if active_profile is None:
return 0
profile_ifc = tool.Ifc.get_entity_by_id(active_profile.ifc_definition_id)
if profile_ifc is None:
return 0
profile_prop = profiles_props.profiles[profiles_props.active_profile_index]
profile_ifc = tool.Ifc.get().by_id(profile_prop.ifc_definition_id)
return tool.Ifc.get().get_total_inverses(profile_ifc)
@classmethod
+8 -4
View File
@@ -46,7 +46,9 @@ def get_profile_classes(self: "BIMProfileProperties", context: bpy.types.Context
def update_profile_name(self: "Profile", context: bpy.types.Context) -> None:
from bonsai.bim.handler import refresh_ui_data
profile = tool.Ifc.get().by_id(self.ifc_definition_id)
profile = tool.Ifc.get_entity_by_id(self.ifc_definition_id)
if not profile:
return
profile.ProfileName = self.name
refresh_ui_data()
@@ -63,15 +65,17 @@ class Profile(PropertyGroup):
def update_active_profile_index(self: "BIMProfileProperties", context: bpy.types.Context) -> None:
ProfileData.data["active_profile_users"] = ProfileData.active_profile_users()
ProfileData.update_active_profile_data()
class BIMProfileProperties(PropertyGroup):
is_editing: BoolProperty(name="Is Editing")
profiles: CollectionProperty(name="Profiles", type=Profile)
active_profile_index: IntProperty(name="Active Profile Index", update=update_active_profile_index)
active_profile_id: IntProperty(name="Active Profile Id")
active_arbitrary_profile_id: IntProperty(name="Active Arbitrary Profile Id")
active_profile_id: IntProperty(name="Active Profile Id", description="Currently edited profile ID (attributes).")
active_arbitrary_profile_id: IntProperty(
name="Active Arbitrary Profile Id", description="Currently edited arbitrary profile ID."
)
profile_attributes: CollectionProperty(name="Profile Attributes", type=Attribute)
profile_classes: EnumProperty(items=get_profile_classes, name="Profile Classes")
is_filtering_material_profiles: bpy.props.BoolProperty(
+11 -2
View File
@@ -75,6 +75,8 @@ class BIM_PT_profiles(Panel):
if not self.props.is_editing:
return
does_active_profile_exist: bool = ProfileData.data["does_active_profile_exist"]
row = self.layout.row(align=True)
if self.props.profile_classes == "IfcArbitraryClosedProfileDef":
split = row.split(factor=0.5, align=True)
@@ -86,7 +88,14 @@ class BIM_PT_profiles(Panel):
row.prop(self.props, "profile_classes", text="")
row.operator("bim.add_profile_def", text="", icon="ADD")
if active_profile:
if active_profile and not does_active_profile_exist:
box = self.layout.box()
box.label(icon="ERROR", text=f"Active profile is missing from IFC project.")
row = box.row(align=True)
row.label(text="Reload Profiles UI.")
row.operator("bim.load_profiles", text="", icon="FILE_REFRESH")
elif active_profile and does_active_profile_exist:
row = self.layout.row(align=True)
row.alignment = "RIGHT"
@@ -122,7 +131,7 @@ class BIM_PT_profiles(Panel):
row = self.layout.row()
row.prop(self.props, "is_filtering_material_profiles", text="Filter Material Profiles")
if active_profile:
if active_profile and does_active_profile_exist:
users_of_profile = ProfileData.data["active_profile_users"]
self.layout.label(icon="INFO", text=f"Profile has {users_of_profile} inverse relationship(s) in project")