diff --git a/src/bonsai/bonsai/bim/helper.py b/src/bonsai/bonsai/bim/helper.py index c9aab88589..bda029cd20 100644 --- a/src/bonsai/bonsai/bim/helper.py +++ b/src/bonsai/bonsai/bim/helper.py @@ -360,6 +360,8 @@ def prop_with_search( prop_name: str, should_click_ok: bool = False, original_operator_path: Optional[str] = None, + enable_relating_type_suggestions: bool = True, + search_threshold: int = 10, *, button_kwargs: Union[dict[str, Any], None] = None, **kwargs: Any, @@ -367,23 +369,26 @@ def prop_with_search( """ Draw a row with enum prop and enum search operator. - Search operator appears only in case if there's more than 10 item in enum. + Search operator appears only in case if there's more than `search_threshold` items in enum. :arg button_kwargs: kwargs to pass to ``UILayout.operator()``. :arg kwargs: kwargs to pass to ``UILayout.prop()``. + :arg enable_relating_type_suggestions: Enable additional suggestions for relating type properties. + :arg search_threshold: Minimum number of enum items required to show search button. Default is 10. :return: Added row. """ # kwargs are layout.prop arguments (text, icon, etc.) row = layout.row(align=True) row.prop(data, prop_name, **kwargs) try: - if len(get_enum_items(data, prop_name, original_operator_path=original_operator_path)) > 10: + if len(get_enum_items(data, prop_name, original_operator_path=original_operator_path)) > search_threshold: # Magick courtesy of https://blender.stackexchange.com/a/203443/86891 row.context_pointer_set(name="data", data=data) op = row.operator("bim.enum_property_search", text="", icon="VIEWZOOM", **(button_kwargs or {})) op.prop_name = prop_name op.should_click_ok = should_click_ok op.original_operator_path = original_operator_path or "" + op.enable_relating_type_suggestions = enable_relating_type_suggestions except TypeError: # Prop is not iterable pass return row diff --git a/src/bonsai/bonsai/bim/operator.py b/src/bonsai/bonsai/bim/operator.py index e7fe1432b4..bec3619e98 100644 --- a/src/bonsai/bonsai/bim/operator.py +++ b/src/bonsai/bonsai/bim/operator.py @@ -1030,6 +1030,7 @@ class BIM_OT_enum_property_search(bpy.types.Operator): prop_name: bpy.props.StringProperty() should_click_ok: bpy.props.BoolProperty(default=False) original_operator_path: bpy.props.StringProperty(name="Original Operator Path", default="", options={"SKIP_SAVE"}) + enable_relating_type_suggestions: bpy.props.BoolProperty(default=True) identifiers: list[str] @@ -1100,6 +1101,38 @@ class BIM_OT_enum_property_search(bpy.types.Operator): predefined_type=predefined_type, ) + if self.enable_relating_type_suggestions: + self.add_relating_type_suggestions() + + def add_relating_type_suggestions(self) -> None: + ifc_file = tool.Ifc.get() + if not ifc_file: + return + + type_elements = [] + for identifier in self.identifiers: + element = ifc_file.by_id(int(identifier)) + if element and element.is_a().endswith("Type"): + type_elements.append(element) + + for element in type_elements: + base_name = element.Name or "Unnamed" + element_step_id = str(element.id()) + + attributes = [] + for attr_name in ["Description", "PredefinedType", "ElementType", "ObjectType"]: + value = getattr(element, attr_name, None) + if value: + attributes.append(value) + + if attributes: + concatenated_name = f"{base_name} > {' > '.join(attributes)}" + self.add_item( + identifier=element_step_id, + name=concatenated_name, + predefined_type=element.PredefinedType or "", + ) + class BIM_OT_select_entity(bpy.types.Operator): bl_idname = "bim.select_entity"