mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 01:11:40 +00:00
simpler way to check if enum property is valid
Well, it's simpler to use but not really simpler in implementation 😅 Thanks to @Gorgious56 for helping out Hopefully, it's a farewell to those annoying warnings see https://blenderartists.org/t/best-way-to-handle-dynamic-enum-items-without-pyrna-enum-to-py-current-value-matches-no-enum
This commit is contained in:
@@ -121,9 +121,10 @@ class AuthoringData:
|
||||
def type_thumbnail(cls):
|
||||
if not cls.data["relating_type_id"]:
|
||||
return 0
|
||||
if not tool.Blender.enum_property_has_valid_index(cls.props, "relating_type_id", cls.data["relating_type_id"]):
|
||||
relating_type_id = tool.Blender.get_enum_safe(cls.props, "relating_type_id")
|
||||
if relating_type_id is None:
|
||||
return 0
|
||||
element = tool.Ifc.get().by_id(int(cls.props.relating_type_id))
|
||||
element = tool.Ifc.get().by_id(int(relating_type_id))
|
||||
return cls.type_thumbnails.get(element.id(), None) or 0
|
||||
|
||||
@classmethod
|
||||
@@ -251,10 +252,8 @@ class AuthoringData:
|
||||
|
||||
@classmethod
|
||||
def predefined_type(cls):
|
||||
if not tool.Blender.enum_property_has_valid_index(cls.props, "relating_type_id", cls.data["relating_type_id"]):
|
||||
return
|
||||
relating_type_id = cls.props.relating_type_id
|
||||
if not relating_type_id:
|
||||
relating_type_id = tool.Blender.get_enum_safe(cls.props, "relating_type_id")
|
||||
if relating_type_id is None:
|
||||
return
|
||||
relating_type = tool.Ifc.get().by_id(int(relating_type_id))
|
||||
if not hasattr(relating_type, "PredefinedType"):
|
||||
|
||||
@@ -60,7 +60,7 @@ def update_ifc_class(self, context):
|
||||
bpy.ops.bim.load_type_thumbnails(ifc_class=self.ifc_class)
|
||||
AuthoringData.data["relating_type_id"] = AuthoringData.relating_type_id()
|
||||
AuthoringData.data["type_thumbnail"] = AuthoringData.type_thumbnail()
|
||||
if not tool.Blender.enum_property_has_valid_index(self, "relating_type_id", AuthoringData.data["relating_type_id"]):
|
||||
if tool.Blender.get_enum_safe(self, "relating_type_id") is None:
|
||||
self["relating_type_id"] = 0
|
||||
|
||||
|
||||
|
||||
@@ -468,20 +468,41 @@ class Blender(blenderbim.core.tool.Blender):
|
||||
active_object.select_set(True)
|
||||
|
||||
@classmethod
|
||||
def enum_property_has_valid_index(cls, props: bpy.types.PropertyGroup, prop_name: str, enum_items: tuple) -> bool:
|
||||
def get_enum_safe(cls, props: bpy.types.PropertyGroup, prop_name: str) -> Union[str, None]:
|
||||
"""method created for readibility and to avoid console warnings like
|
||||
`pyrna_enum_to_py: current value '17' matches no enum in 'BIMModelProperties', '', 'relating_type_id'`
|
||||
"""
|
||||
items_amount = len(enum_items)
|
||||
# Yes, accessing items through annotations is a bit hacky
|
||||
# but it's the only way to get the dynamic enum items
|
||||
# besides providing them to get_enum_safe explicitly.
|
||||
prop_keywords = props.__annotations__[prop_name].keywords
|
||||
items = prop_keywords.get("items")
|
||||
if items is None:
|
||||
return None
|
||||
if not isinstance(items, (list, tuple)):
|
||||
# items are retrieved through a callback, not a static list / tuple :
|
||||
items = items(props, bpy.context)
|
||||
|
||||
items_amount = len(items)
|
||||
# If enum has no items it seems to always produce a warning.
|
||||
# E.g. if you try to get it's value directly: `BIMModelProperties.relating_type_id`.
|
||||
if items_amount == 0:
|
||||
return False
|
||||
current_value_index = props.get(prop_name, None)
|
||||
# assuming the default value is fine
|
||||
if current_value_index is None:
|
||||
return True
|
||||
return current_value_index < items_amount
|
||||
return None
|
||||
|
||||
index = props.get(prop_name)
|
||||
# If value was never changed (still default), we can just retrieve it from the enum.
|
||||
if index is None:
|
||||
default_value = prop_keywords.get("default")
|
||||
if isinstance(default_value, int):
|
||||
index = default_value
|
||||
else:
|
||||
# If default value is a string then it's a static enum
|
||||
# and we can just return it.
|
||||
return default_value
|
||||
# Ensure index is valid.
|
||||
if items_amount > index >= 0:
|
||||
return items[index][0]
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def append_data_block(cls, filepath: str, data_block_type: str, name: str, link=False, relative=False) -> dict:
|
||||
|
||||
Reference in New Issue
Block a user