From 59c9b162761b2f3c62d3a08f79e1bccf13591fd8 Mon Sep 17 00:00:00 2001 From: falken10vdl Date: Thu, 18 Dec 2025 10:56:18 +0100 Subject: [PATCH] Migrate old filter prefixes to new filter_mode system and enhance filter handling based on user preferences --- .../bonsai/bim/module/search/operator.py | 10 ++++ src/bonsai/bonsai/tool/search.py | 59 +++++-------------- 2 files changed, 24 insertions(+), 45 deletions(-) diff --git a/src/bonsai/bonsai/bim/module/search/operator.py b/src/bonsai/bonsai/bim/module/search/operator.py index f9e7885ebe..58c773af17 100644 --- a/src/bonsai/bonsai/bim/module/search/operator.py +++ b/src/bonsai/bonsai/bim/module/search/operator.py @@ -761,7 +761,17 @@ class Search(Operator): assert_never(self.property_group) preferences = tool.Blender.get_addon_preferences() + + # Migrate old ! prefix filters to new filter_mode system when preferences are enabled if preferences.chain_filter_with_set_operations or preferences.default_filter_with_set_operations_for_globalid_and_class: + for filter_group in props.filter_groups: + for ifc_filter in filter_group.filters: + if ifc_filter.type not in ["entity", "instance"]: + continue + if ifc_filter.value.startswith("!"): + ifc_filter.value = ifc_filter.value[1:] + ifc_filter.filter_mode = "SUBTRACT" + results = tool.Search.execute_filter_groups(props.filter_groups) else: results = ifcopenshell.util.selector.filter_elements( diff --git a/src/bonsai/bonsai/tool/search.py b/src/bonsai/bonsai/tool/search.py index 20c4b75387..36536f5a1a 100644 --- a/src/bonsai/bonsai/tool/search.py +++ b/src/bonsai/bonsai/tool/search.py @@ -123,21 +123,28 @@ class Search(bonsai.core.tool.Search): @classmethod def _export_single_filter(cls, ifc_filter: BIMFacet) -> str: + preferences = tool.Blender.get_addon_preferences() + if ifc_filter.type == "instance": if "bpy.data.texts" in ifc_filter.value: data_name = ifc_filter.value.split("bpy.data.texts")[1][2:-2] value = bpy.data.texts[data_name].as_string() else: value = ifc_filter.value - value = value.lstrip("!") - if ifc_filter.filter_mode == "SUBTRACT": - value = f"!{value}" + + if preferences.chain_filter_with_set_operations or preferences.default_filter_with_set_operations_for_globalid_and_class: + value = value.lstrip("!") + if ifc_filter.filter_mode == "SUBTRACT": + value = f"!{value}" return value + elif ifc_filter.type == "entity": value = ifc_filter.value - value = value.lstrip("!") - if ifc_filter.filter_mode == "SUBTRACT": - value = f"!{value}" + + if preferences.chain_filter_with_set_operations or preferences.default_filter_with_set_operations_for_globalid_and_class: + value = value.lstrip("!") + if ifc_filter.filter_mode == "SUBTRACT": + value = f"!{value}" return value elif ifc_filter.type == "attribute": if not ifc_filter.name: @@ -185,63 +192,36 @@ class Search(bonsai.core.tool.Search): Groups are combined with union (same as original " + " behavior). """ preferences = tool.Blender.get_addon_preferences() - #print(f"\n{'='*80}") - #print(f"DEBUG: execute_filter_groups - Starting execution") - #print(f"DEBUG: Preferences - chain_filter_with_set_operations: {preferences.chain_filter_with_set_operations}") - #print(f"DEBUG: Preferences - default_filter_with_set_operations_for_globalid_and_class: {preferences.default_filter_with_set_operations_for_globalid_and_class}") - #print(f"DEBUG: Total filter groups: {len(filter_groups)}") all_group_results = [] for group_idx, filter_group in enumerate(filter_groups): - #print(f"\n--- Group {group_idx} ---") group_results = set() for filter_index, ifc_filter in enumerate(filter_group.filters): - #print(f"\n Filter {filter_index}:") - #print(f" Type: {ifc_filter.type}") - #print(f" Value: {ifc_filter.value}") - #print(f" filter_mode property: {ifc_filter.filter_mode}") - if not ifc_filter.value: - #print(f" SKIPPED: No value") continue query = cls._export_single_filter(ifc_filter) if not query: - #print(f" SKIPPED: No query generated") continue - #print(f" Generated query: {query}") - #print(f" Current group_results size before this filter: {len(group_results)}") - - # Determine the mode for this filter if filter_index == 0: - mode = "ADD" # First filter is always ADD - #print(f" Mode decision: ADD (first filter)") + mode = "ADD" else: - # For entity and instance filters, check if set operations are enabled if ifc_filter.type in ["entity", "instance"]: - # Use filter_mode only if chain mode OR default mode preference is enabled if preferences.chain_filter_with_set_operations or preferences.default_filter_with_set_operations_for_globalid_and_class: mode = ifc_filter.filter_mode - #print(f" Mode decision: {mode} (entity/instance with preference enabled)") else: - # Default behavior: sequential filtering (FILTER mode) mode = "FILTER" if group_results else "ADD" - #print(f" Mode decision: {mode} (entity/instance default behavior)") else: - # For other filter types, use chain mode if enabled, otherwise FILTER if preferences.chain_filter_with_set_operations: mode = ifc_filter.filter_mode - #print(f" Mode decision: {mode} (other type with chain mode)") else: mode = "FILTER" if group_results else "ADD" - #print(f" Mode decision: {mode} (other type default behavior)") if mode == "ADD": results = ifcopenshell.util.selector.filter_elements(tool.Ifc.get(), query) - #print(f" ADD: Found {len(results)} elements, adding to group_results") group_results.update(results) elif mode == "SUBTRACT": @@ -250,11 +230,9 @@ class Search(bonsai.core.tool.Search): elements_to_remove = ifcopenshell.util.selector.filter_elements( tool.Ifc.get(), query_without_prefix, elements=group_results ) - #print(f" SUBTRACT: Removing {len(elements_to_remove)} elements from group_results") group_results -= elements_to_remove else: results = ifcopenshell.util.selector.filter_elements(tool.Ifc.get(), query) - #print(f" SUBTRACT: group_results empty, adding {len(results)} elements (fallback to ADD)") group_results.update(results) elif mode == "FILTER": @@ -262,16 +240,11 @@ class Search(bonsai.core.tool.Search): results = ifcopenshell.util.selector.filter_elements( tool.Ifc.get(), query, elements=group_results ) - #print(f" FILTER: Filtering group_results, result: {len(results)} elements") group_results = results else: results = ifcopenshell.util.selector.filter_elements(tool.Ifc.get(), query) - #print(f" FILTER: group_results empty, found {len(results)} elements (fallback to ADD)") group_results.update(results) - - #print(f" Group results size after this filter: {len(group_results)}") - #print(f"\n Group {group_idx} final size: {len(group_results)}") if group_results: all_group_results.append(group_results) @@ -279,10 +252,6 @@ class Search(bonsai.core.tool.Search): for group_results in all_group_results: final_results.update(group_results) - #print(f"\n{'='*80}") - #print(f"DEBUG: Final combined results: {len(final_results)} elements") - #print(f"{'='*80}\n") - return final_results @classmethod