How to get selection objects list in outliner?

I’m making simple script which can toggle hide or unhide.
But I can’t get selection objects lists in outliner.

Getting object selection list which selected in viewport is easy.
(using bpy.context.selected_objects)

I can select hide objects in outliner only.
But,Getting object selection list which selected in outliner is difficult.

I can get last selected object in outliner, (using bpy.context.selected_objects)
But I can’t get all selected objects list in outliner.

Please help me.
q01

I’m in the same situation, if someone has some knowledge to share I/we would be delighted.

Here’s my questions on Stack exchange: https://blender.stackexchange.com/questions/160694/how-to-toggle-selected-objects-visibility-with-h-shortcut-as-in-maya

In 2.7 this was easily accessible through so-called object bases, which there no longer are no entry points to from python afaik. However, one way to determine the objects is by temporarily unhiding things and cross reference the selections.

Made a quick addon out of it. The hotkey is set to J to avoid colliding with the vanilla operator, but can easily be changed.

Updated 7/19/21:

toggle_hide.py
Right-click > Save As

2 Likes

I tried to install the .py file in 2.81 but it doesn’t seem to show up in the addon list, it’s added to the addon folder (…2.81\scripts\addons) though and pressing J doesn’t work of course. Any ideas how to make it install and work?

Sounds like you downloaded the web page instead. Visit the link, right-click “Raw”, then save link as file.

Ah thanks, that was it, took a look in the installed .py file in indeed it was an html file and…

Wow thank you so much for the script, it’s working great.

1 Like

Hello,
I was looking for a similar solution
but doesn’t seem to work in 2.83+
it switches once and then hides everything and stops working …
@iceythe can you look at code to make it work in 2.83+ or in 2.9. Thanks!

Please I have the same problem like other users, can you please updat ethe code for Blender 2.9 + ?

Here is workaround script.
Toggle-hide between two objects.
Code can be saved in .py file and installed as usual addon
and then add keymap for outliner.toggle_hide operator

Summary
import bpy
from bpy.types import Operator

bl_info = {
    "name": "Toggle Hide",
    "description": "Toggle Hide",
    "author": "APEC, Oskar",
    "blender": (2, 90, 0)
    }

class OUTLINER_OT_toggle_hide(Operator):
    """Toggle the viewport visibility between two initially visible and selected objects in the viewport"""
    bl_idname = "outliner.toggle_hide"
    bl_label = "Toggle Hide"
    #bl_options = {'REGISTER', 'UNDO'}

    @classmethod
    def poll(cls, context):
        
        if (bpy.context.area.type == "VIEW_3D" or bpy.context.area.type == "OUTLINER"):
            return True
    
    def execute(self, context):
        # Get the current scene so we can store our selected objects in it.
        scene = bpy.context.scene
        selected_objects = context.selected_objects
        
        # This is our custom property where we will store the object names in.
        # Returns None if the property doesn't exists. To avoid try/except.
        prop = scene.get("hide_toggle_objs", None)
        
        if prop is not None and len(prop)>0 and len(selected_objects)==0:
            # Get the stored objects
            toggle_objs_list = scene["hide_toggle_objs"]
            
            # Reverse their visibility
            toggle_objs_list[0].hide_viewport = not toggle_objs_list[0].hide_viewport
            toggle_objs_list[1].hide_viewport = not toggle_objs_list[0].hide_viewport
            
        elif len(selected_objects)>0:
            # If we selected new objects, then store them in the scene
            bpy.context.scene["hide_toggle_objs"] = selected_objects
            # Hide the first selected and deselect the second
            selected_objects[0].hide_viewport = True
            selected_objects[1].select_set(False)
        
        return {'FINISHED'}
    
classes = (
    OUTLINER_OT_toggle_hide,

)
register, unregister = bpy.utils.register_classes_factory(classes)


if __name__ == "__main__":
    register()

Thank you APEC, but this script Toggle the viewport visibility between two initially visible and selected objects in the viewport. It works, but I am looking for simple visibility toogle of anything selected in viewport or outliner - on and off, not switching between two objects… please don’t you have this kind of script as well?

Can you explain what exactly you need?
Select objects in Outliner and hide them? Like default “H” key?

Or hide also for rendering?

Simple toggling selected objects by default in Blender is “H” - hide and “Alt+H” - unhide. “Shift+H” - hide unselected.
Also here is “Local View Mode” that isolate selected object/s (key “Numpud /”) - very helpful in complex scenes.

I just need nothing more simple than this

Just toggle between visibility. Yes, also for rendering, everywhere.
Just get the list of the selected objects in outliner - go through it - if it’s hidden (disabled in viewport) make it unhidden, if it’s not hidden make it hidden. I am trying to solve such a simple thing all day long - please help me to go to sleep finally with peace… I know I am new to Blender and conding there - sorry fo that.

Got it,
default hotkeys won’t help in such task.
Yes, indeed, it need to write a script for this, will try to help you tomorrow, there was no need for such a task before.

Thank you very much - I truly appreciate you trying to help me. Looking forward for tomorrow
But keeping keeping watching tutorials anyway :slight_smile:

Hi, did you have time to make a script?

Hello,
With my basic skills I tried here

But you cannot run the script in 3DView, until the developers make changes to the main code

Hi there,
After looking through basically every forum thread for a solution for accessing hidden selected objects from the outliner outside the outliner, I figured that it is not supported by the python API.
The bpy.context.selected_ids works great, but for now at least only in the context of the Outliner, which is for most of the intended use cases not a good/feasible solution.

Long story short, I updated the awesome script of @iceythe to work with blender 2.93LTS.
This said, it is by nature a very “hacky” and I just did a quick rework and could not really test it, but here you go:

The internal struct have changed slightly, such that a few classes of the original script must be adjusted.

#unchanged

class SpaceOutliner(ctypes.Structure):
    _fields_ = (
        ("next", ctypes.c_void_p),
        ("prev", ctypes.c_void_p),
        ("regionbase", ctypes.c_void_p * 2),
        ("spacetype", ctypes.c_char),
        ("link_flag", ctypes.c_char),
        ("pad0", ctypes.c_char * 6),
        ("v2d", ctypes.c_char * 160),       #changed in 2.93 -> 160 (unsure if it's actually 160 xD)
        ("tree", listbase(TreeElement29)))

TreeElement._fields_ = (
    ("next", ctypes.POINTER(TreeElement)),
    ("prev", ctypes.POINTER(TreeElement)),
    ("_parent", ctypes.POINTER(TreeElement)),
    ("type", ctypes.c_void_p),              #new field in 2.93
    ("subtree", listbase(TreeElement)),
    ("xys", ctypes.c_int * 2),
    ("_store_elem",  ctypes.POINTER(TreeStoreElem)),
    ("flag", ctypes.c_short),
    ("index", ctypes.c_short),
    ("idcode", ctypes.c_short),
    ("xend", ctypes.c_short),
    ("_name", ctypes.c_char_p),
    ("directdata", ctypes.c_void_p),
    ("rnaptr", ctypes.c_void_p * 3))            #unchanged

I’ve rewritten the toggle script and tried to make sure it works on all recent Blender versions. This includes the LTS (2.83.x), 2.93.x and 3.0 alpha.

If (when) a newer version breaks the script, it usually means the DNA side of Blender has changed (struct members added/removed). When that happens, let me know of the specific version.

(Same link as my other post)
toggle_hide.py
Right-click > Save As.

6 Likes

Thank you a lot for the clean update!

2 Likes

This is so useful to me. Thank you thank you thank you!