Enhance filter operation modes with new preferences for chaining and default behaviors

This commit is contained in:
falken10vdl
2025-12-18 10:20:28 +01:00
parent 738a068474
commit affaa859ef
4 changed files with 81 additions and 8 deletions
+12 -2
View File
@@ -535,7 +535,12 @@ def draw_filter(
for j, ifc_filter in enumerate(filter_group.filters):
if ifc_filter.type == "entity":
row = box.row(align=True)
if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
preferences = tool.Blender.get_addon_preferences()
if preferences.chain_filter_with_set_operations:
show_mode_toggle = j > 0
else:
show_mode_toggle = preferences.default_filter_with_set_operations_for_globalid_and_class and j > 0 # PR 7315 mode
if show_mode_toggle:
mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
op = row.operator(
"bim.toggle_filter_inclusion",
@@ -749,7 +754,12 @@ def draw_filter(
row.prop(ifc_filter, "value", text="")
elif ifc_filter.type == "instance":
row = box.row(align=True)
if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
preferences = tool.Blender.get_addon_preferences()
if preferences.chain_filter_with_set_operations:
show_mode_toggle = j > 0
else:
show_mode_toggle = preferences.default_filter_with_set_operations_for_globalid_and_class and j > 0 # PR 7315 mode
if show_mode_toggle:
mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
op = row.operator(
"bim.toggle_filter_inclusion",
@@ -760,8 +760,8 @@ class Search(Operator):
else:
assert_never(self.property_group)
if tool.Blender.get_addon_preferences().chain_filter_with_set_operations:
preferences = tool.Blender.get_addon_preferences()
if preferences.chain_filter_with_set_operations or preferences.default_filter_with_set_operations_for_globalid_and_class:
results = tool.Search.execute_filter_groups(props.filter_groups)
else:
results = ifcopenshell.util.selector.filter_elements(
+13 -2
View File
@@ -691,10 +691,15 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences):
)
chain_filter_with_set_operations: BoolProperty(
name="Enable chained filters with set operations",
name="NEW filter mode: Enable chained filters with set operations",
description="Enable chaining search filters with set operations: ADD (union: combine sets), SUBTRACT (difference: remove from set), FILTER (intersection: only elements in both sets), with autocomplete suggestions for filter values",
default=False,
)
default_filter_with_set_operations_for_globalid_and_class: BoolProperty(
name="DEFAULT filter mode: Enable set operations for GlobalId/Class",
description="Enable ADD/SUBTRACT/FILTER toggle buttons on entity (Class) and instance (GlobalId) filters for the DEFAULT filter mode",
default=False,
)
if TYPE_CHECKING:
svg2pdf_command: str
@@ -734,6 +739,7 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences):
container_hide_show_isolate: bool
mass_time_units_in_wizard: bool
chain_filter_with_set_operations: bool
default_filter_with_set_operations_for_globalid_and_class: bool
def draw(self, context: bpy.types.Context) -> None:
layout = self.layout
@@ -916,9 +922,14 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences):
def draw_extras_settings(self, layout: bpy.types.UILayout, context: bpy.types.Context) -> None:
layout.prop(self, "container_hide_show_isolate")
layout.prop(self, "mass_time_units_in_wizard")
row = layout.row(align=True)
layout.label(text="Filtering modes:")
box = layout.box()
row = box.row(align=True)
row.prop(self, "chain_filter_with_set_operations")
row.operator("bim.open_uri", text="", icon="HELP").uri = "https://community.osarch.org/discussion/3270"
row = box.row(align=True)
row.prop(self, "default_filter_with_set_operations_for_globalid_and_class")
row.operator("bim.open_uri", text="", icon="HELP").uri = "https://community.osarch.org/discussion/comment/27030"
# Scene panel groups
+54 -2
View File
@@ -184,23 +184,64 @@ class Search(bonsai.core.tool.Search):
Within a single group chain, all filters chain sequentially with ADD/SUBTRACT/FILTER modes.
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 filter_group in filter_groups:
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
mode = "ADD" if filter_index == 0 else ifc_filter.filter_mode
#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)")
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":
@@ -209,9 +250,11 @@ 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":
@@ -219,11 +262,16 @@ 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)
@@ -231,6 +279,10 @@ 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