From 21137de8a0fa6633a885b9fd0ea200fc1322bcf8 Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Fri, 5 Sep 2025 18:25:39 +0500 Subject: [PATCH] Fix error reapplying selection during assign_class #7082 It appeared in case if user had IfcTypeProduct collection disabled. --- src/bonsai/bonsai/bim/module/root/operator.py | 9 ++------ src/bonsai/bonsai/tool/blender.py | 23 +++++++++++++++++++ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/bonsai/bonsai/bim/module/root/operator.py b/src/bonsai/bonsai/bim/module/root/operator.py index 37bee7b25b..e9ace873e2 100644 --- a/src/bonsai/bonsai/bim/module/root/operator.py +++ b/src/bonsai/bonsai/bim/module/root/operator.py @@ -385,13 +385,8 @@ class AssignClass(bpy.types.Operator, tool.Ifc.Operator): # TODO: reload representation might lead to the object being replaced by object of the other type. # We probably should track it somehow and keep the original selection. - # Validation selection. - new_selected_objects = list(filter(tool.Blender.is_valid_data_block, current_selection[2])) - active_object = current_selection[1] - if active_object and not tool.Blender.is_valid_data_block(active_object): - active_object = None - current_selection = (current_selection[0], active_object, new_selected_objects) - + # Validate selection and reapply it. + current_selection = tool.Blender.validate_object_selection(*current_selection) tool.Blender.set_objects_selection(*current_selection) diff --git a/src/bonsai/bonsai/tool/blender.py b/src/bonsai/bonsai/tool/blender.py index 44ceaad680..c225d00d9b 100644 --- a/src/bonsai/bonsai/tool/blender.py +++ b/src/bonsai/bonsai/tool/blender.py @@ -690,6 +690,29 @@ class Blender(bonsai.core.tool.Blender): if active_object: active_object.select_set(True) + @classmethod + def validate_object_selection( + cls, + context: bpy.types.Context, + active_object: Union[bpy.types.Object, None] = None, + selected_objects: Sequence[bpy.types.Object] = (), + ) -> tuple[bpy.types.Context, Union[bpy.types.Object, None], list[bpy.types.Object]]: + """Validate object selection and return only valid objects. + + Can be used before ``set_objects_selection`` to avoid errors + trying to select or set as active already removed objects + or objects that are not in the current view layer (their collection is unchecked). + """ + assert context.view_layer + view_layer_objects = set(context.view_layer.objects) + + new_selected_objects = [o for o in selected_objects if cls.is_valid_data_block(o) and o in view_layer_objects] + + if active_object and (not cls.is_valid_data_block(active_object) or active_object not in view_layer_objects): + active_object = None + + return context, active_object, new_selected_objects + @classmethod def clear_objects_selection(cls) -> None: """Clear objects selection and active object."""