From d24dabbdc2c5822105bd8b16f1db4fb3a32f752c Mon Sep 17 00:00:00 2001 From: tetektoza Date: Sun, 27 Apr 2025 00:55:34 +0200 Subject: [PATCH] BIM: Hide all objects that aren't selected during Isolate Currently if user selects an item and does `Isolate` operation on it in BIM, everything is being hidden if the item was inside another container (like Building). This is because we are prioritizing on hiding parents of current object if they are not the selected ones, which is causing the child of the parent to be hidden as well (duh). So, this patch fixes isolate method to hide all other parents and their childs. If they are not a parent of our child under selection -> hide them and proceed further. If we are processing parent of our selection, just hide anything on current level that is not our selection while leaving parent intact. --- src/Mod/BIM/bimcommands/BimViews.py | 41 ++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/Mod/BIM/bimcommands/BimViews.py b/src/Mod/BIM/bimcommands/BimViews.py index b7d245fd9e..8a10ae8ed8 100644 --- a/src/Mod/BIM/bimcommands/BimViews.py +++ b/src/Mod/BIM/bimcommands/BimViews.py @@ -448,17 +448,46 @@ class BIM_Views: FreeCAD.ActiveDocument.recompute() def isolate(self): - "turns all items off except the selected ones" + """ + Traverse the tree and hide all items (and their ancestors) that are not the currently + selected item or a descendant of the currently selected item. + + This ensures that only the selected item and its ancestors remain visible, while + all other items are hidden. + """ vm = findWidget() if vm: - onnames = [item.toolTip(0) for item in vm.tree.selectedItems()] - for i in range(vm.tree.topLevelItemCount()): - item = vm.tree.topLevelItem(i) - if item.toolTip(0) not in onnames: - obj = FreeCAD.ActiveDocument.getObject(item.toolTip(0)) + onnames = vm.tree.selectedItems() + selectedItsTooltips = [item.toolTip(0) for item in vm.tree.selectedItems()] + def is_ancestor_of_any(potential_parent, selected_items): + """Check if potential_parent is an ancestor of ANY selected item.""" + for item in selected_items: + current = item.parent() + while current: + if current.toolTip(0) == potential_parent: + return True + current = current.parent() + return False + + def traverse_and_hide(item): + """Recursively traverse the tree and hide/show parents accordingly.""" + toolTip = item.toolTip(0) + obj = FreeCAD.ActiveDocument.getObject(toolTip) + if toolTip not in selectedItsTooltips and not is_ancestor_of_any(toolTip, onnames): if obj: obj.ViewObject.Visibility = False + + # Traverse on lower levels of this tree only if we didn't hide current level + if obj and obj.ViewObject.Visibility != False: + for i in range(item.childCount()): + traverse_and_hide(item.child(i)) + + # Start from top-level items + for i in range(vm.tree.topLevelItemCount()): + top_item = vm.tree.topLevelItem(i) + traverse_and_hide(top_item) + FreeCAD.ActiveDocument.recompute() def saveView(self):