I want to be able to toggle the visibility of selected objects with a shortcut (H) the way you can do in Maya and XSI, shown in the GIF. I'm guessing scrippting is needed. I've tried to do it my self but I'm new to Python and Blender and as soon as the objects are hidden they seem to no longer be in a selection state/list. Eg if I manually select the hidden object/s in the Outliner and try to print the selected object to the console, none seem to be selected. Is this possible to do with the current state of Blender 2.8?
3 Answers
iceythe provided a solution over at https://blenderartists.org/t/how-to-get-selection-objects-list-in-outliner/1184175/3?u=joelart
Toggle Hide Addon:
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
import bpy
bl_info = {
"name": "Toggle Hide",
"location": "3D View / Outliner, (Hotkey J)",
"version": (0, 1, 0),
"blender": (2, 81, 0),
"description": "Toggle object visibility of outliner selection",
"author": "kaio",
"category": "Object",
}
class OUTLINER_OT_toggle_hide(bpy.types.Operator):
bl_idname = "outliner.toggle_hide"
bl_label = "Toggle Hide"
bl_options = {'REGISTER', 'UNDO'}
@classmethod
def poll(self, context):
ar = context.screen.areas
__class__.area = next(
(a for a in ar if a.type == 'OUTLINER'), None)
return __class__.area
def execute(self, context):
objs = context.view_layer.objects
sel_objs = {o for o in objs if o.select_get()}
hid_objs = {o for o in objs if o.hide_get()}
# Hide selected
for o in sel_objs:
o.hide_set(True)
# Unhide hidden
for o in hid_objs:
o.hide_set(False)
# Select objects marked in outliner
bpy.ops.outliner.object_operation(
{'area': __class__.area}, type='SELECT')
# Re-hide others
for o in hid_objs:
if not o.select_get():
o.hide_set(True)
return {'FINISHED'}
addon_keymaps = []
def register():
bpy.utils.register_class(OUTLINER_OT_toggle_hide)
wm = bpy.context.window_manager
kc = wm.keyconfigs.addon.keymaps
km = kc.get("Object Mode")
if not km:
km = kc.new("Object Mode")
kmi = km.keymap_items.new("outliner.toggle_hide", "J", "PRESS")
addon_keymaps.append((km, kmi))
km = kc.get("Outliner")
if not km:
km = kc.new("Outliner", space_type="OUTLINER")
kmi = km.keymap_items.new("outliner.toggle_hide", "J", "PRESS")
addon_keymaps.append((km, kmi))
def unregister():
bpy.utils.unregister_class(OUTLINER_OT_toggle_hide)
for km, kmi in addon_keymaps:
km.keymap_items.remove(kmi)
addon_keymaps.clear()
Here's as link to the githup addon/script page: https://github.com/K-410/blender-scripts/blob/master/2.8/toggle_hide.py
In Blender, the way selection works is a bit different. You can't really have something "selected" when it's hidden in the viewport.
You can hide an object with H, but to unhide, you generally either undo or alt-H to unhide all hidden objects. To have the same shortcut key do both an action and its opposite is pretty uncommon in Blender. The only thing I can think of is selecting all (A for select all AA to deselect all, but they are moving away from that by making alt-A deselect all).
-
1$\begingroup$ I think they Maya way is the most intuitive and ergonomic to perform with toggles and think Blender should move towards it instead. That said, is there a way in Scripting to get a list of the objects that I've selected in the Outliner, if so then I can at least make H unhide them. $\endgroup$– JoelArtDec 12, 2019 at 2:00
-
1$\begingroup$ I occasionally wanted an option to toggle show/hide in Blender too. Illustrator & Photoshop use the same hide/show functionality as Blender does now, so it's not uncommon for people to be used to that (the "hide single object", "show all hidden objects" method). I wish I could give you a script, but I'm not too good at that. This guy seems to be wanting to do the same thing as you. And the documentation can help with scripting $\endgroup$ Dec 12, 2019 at 16:39
Here is my solution, you can use this script as an addon , then register a new keymap with H key using object.toggle_visible operator , then disable the default H keymap.
import bpy
bl_info = {
"name": "HideShowToggle",
"blender": (3, 10, 0),
"category": "Object",
"author": "Gumoumoumou",
"doc_url": "https://space.bilibili.com/22223199"
}
def GetAllSelectedObjects():
visibles = bpy.context.visible_objects
bpy.ops.object.hide_view_clear()
selecteds = bpy.context.selected_objects
for o in bpy.data.objects:
if not o in visibles:
o.hide_set(True)
return selecteds
def main(context):
objs = GetAllSelectedObjects()
for o in objs:
o.hide_set(not o.hide_get())
o.select_set(True)
class HideShowToggle(bpy.types.Operator):
"""Tooltip"""
bl_idname = "object.toggle_visible"
bl_label = "Toggle visibility of objects"
def execute(self, context):
main(context)
return {'FINISHED'}
def menu_func(self, context):
self.layout.operator(HideShowToggle.bl_idname, text=HideShowToggle.bl_label)
def register():
bpy.utils.register_class(HideShowToggle)
bpy.types.VIEW3D_MT_object.append(menu_func)
def unregister():
bpy.utils.unregister_class(HideShowToggle)
bpy.types.VIEW3D_MT_object.remove(menu_func)
```