mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +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):
|
def type_thumbnail(cls):
|
||||||
if not cls.data["relating_type_id"]:
|
if not cls.data["relating_type_id"]:
|
||||||
return 0
|
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
|
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
|
return cls.type_thumbnails.get(element.id(), None) or 0
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -251,10 +252,8 @@ class AuthoringData:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def predefined_type(cls):
|
def predefined_type(cls):
|
||||||
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")
|
||||||
return
|
if relating_type_id is None:
|
||||||
relating_type_id = cls.props.relating_type_id
|
|
||||||
if not relating_type_id:
|
|
||||||
return
|
return
|
||||||
relating_type = tool.Ifc.get().by_id(int(relating_type_id))
|
relating_type = tool.Ifc.get().by_id(int(relating_type_id))
|
||||||
if not hasattr(relating_type, "PredefinedType"):
|
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)
|
bpy.ops.bim.load_type_thumbnails(ifc_class=self.ifc_class)
|
||||||
AuthoringData.data["relating_type_id"] = AuthoringData.relating_type_id()
|
AuthoringData.data["relating_type_id"] = AuthoringData.relating_type_id()
|
||||||
AuthoringData.data["type_thumbnail"] = AuthoringData.type_thumbnail()
|
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
|
self["relating_type_id"] = 0
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -468,20 +468,41 @@ class Blender(blenderbim.core.tool.Blender):
|
|||||||
active_object.select_set(True)
|
active_object.select_set(True)
|
||||||
|
|
||||||
@classmethod
|
@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
|
"""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'`
|
`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.
|
# 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`.
|
# E.g. if you try to get it's value directly: `BIMModelProperties.relating_type_id`.
|
||||||
if items_amount == 0:
|
if items_amount == 0:
|
||||||
return False
|
return None
|
||||||
current_value_index = props.get(prop_name, None)
|
|
||||||
# assuming the default value is fine
|
index = props.get(prop_name)
|
||||||
if current_value_index is None:
|
# If value was never changed (still default), we can just retrieve it from the enum.
|
||||||
return True
|
if index is None:
|
||||||
return current_value_index < items_amount
|
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
|
@classmethod
|
||||||
def append_data_block(cls, filepath: str, data_block_type: str, name: str, link=False, relative=False) -> dict:
|
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