From 4d38c8ad18b9ce2c1a798d268138b6fb8b32db92 Mon Sep 17 00:00:00 2001 From: Petru Conduraru Date: Sun, 12 Jul 2026 09:14:04 +0300 Subject: [PATCH] Bonsai: skip out-of-view-layer spaces in toggle_hide_spaces (#5309) Toggling space visibility crashed with `RuntimeError: Object 'IfcSpace/...' cannot be hidden because it is not in View Layer 'ViewLayer'!` when a space object lived in a collection excluded from the active view layer. tool.Spatial.toggle_hide_spaces called hide_get/hide_set unconditionally; Blender raises for any object not in the active view layer. The rest of spatial.py already guards these calls via view_layer.objects.get(obj.name); this method was the outlier. Filter the spaces to objects present in the active view layer, derive the toggle direction from the first surviving object, and apply hide_set only to those. Objects not in the view layer are skipped (they cannot be hidden anyway). Also returns cleanly when nothing is toggleable. Verified live in headless Blender: with one space in an excluded collection, the old code raised the reported RuntimeError; the fix completes, hides the in-view-layer space, and skips the excluded one. Core test_spatial.py: 12 passed. Generated with the assistance of an AI coding tool. Co-Authored-By: Claude Opus 4.8 --- src/bonsai/bonsai/tool/spatial.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/bonsai/bonsai/tool/spatial.py b/src/bonsai/bonsai/tool/spatial.py index df87d493c7..2a2c83b4b8 100644 --- a/src/bonsai/bonsai/tool/spatial.py +++ b/src/bonsai/bonsai/tool/spatial.py @@ -1258,19 +1258,20 @@ class Spatial(bonsai.core.tool.Spatial): @classmethod def toggle_hide_spaces(cls, spaces: list[ifcopenshell.entity_instance]) -> None: - first_obj = tool.Ifc.get_object(spaces[0]) - assert isinstance(first_obj, bpy.types.Object) - obj: bpy.types.Object - if first_obj.hide_get() == False: - for space in spaces: - obj = tool.Ifc.get_object(space) - obj.hide_set(True) + # `hide_get`/`hide_set` raise for objects that are not in the active view + # layer (e.g. spaces living in an excluded collection), so skip those. + view_layer = bpy.context.view_layer + objs = [ + obj + for space in spaces + if isinstance(obj := tool.Ifc.get_object(space), bpy.types.Object) and view_layer.objects.get(obj.name) + ] + if not objs: return - elif first_obj.hide_get() == True: - for space in spaces: - obj = tool.Ifc.get_object(space) - obj.hide_set(False) + should_hide = objs[0].hide_get() == False + for obj in objs: + obj.hide_set(should_hide) @classmethod def set_default_container(cls, container: ifcopenshell.entity_instance) -> None: