Changing visibility of multiple collections at once

Hello, I am having -probably a very basic- an issue with changing visibility of multiple collections/subcollections at once. I might be having a slow brain moment, can you please tell me how I can go about doing this? All I want to do is, changing the layer visibility of all -selected- (sub)collections at the same time.

subcollection

Select the parent collection and hold shift while clicking left.
It will change it for all sub-collections.

1 Like

I tried all the combinations, shift+Click, ctrl+Click, alt+click, shift+ctrl+Click… But it didn’t work

I see, it is caused by unchecking the “Exclude from view layer”. It works if they are checked.
So you have to check them first. But shift is not working for “Exclude from view layer”.

Did you create via script? They are all empty.

I created this screenshot as an example. In the real file I am working on, I have over 300 collections and 5-10 subcollections each. Thus, checking them first would take quite some time, that’s why I am looking for maybe a script that turns on all the selected collections.

That should do it, make a backup before try:

import bpy


for s in bpy.data.scenes.items():
    print(s[0])
    for vlay in bpy.data.scenes[s[0]].view_layers:
        print(vlay.name)
        for item in vlay.layer_collection.children:
            print(item.name)
            item.exclude = False
1 Like

Thanks a lot for your reply. As far as I understand, this turns on every collection in the file, right? What would you change in the script to make it affect only the selected collections/subcollections?

That is not so easy, i can only see outliner access to active layers, but no for all or inactive.
Maybe someone in the scripting area know a solution. I move the topic.

1 Like

Thanks a lot for your time and thank you for moving the topic :slight_smile:

I’ve been looking for a script to do it, but still, I couldn’t find any solution yet.

import bpy
        
for w in bpy.context.window_manager.windows:
    s = w.screen
    for a in s.areas:
        if a.type == "OUTLINER":
            with bpy.context.temp_override(window=w, area=a):
                cols = [s for s in bpy.context.selected_ids if s.rna_type.name == "Collection"]
                for c in cols:
                    # Outliner Icon - Checkbox
                    bpy.context.scene.view_layers[0].layer_collection.children[c.name].exclude = True
                    # Outliner Icon - Cursor
                    c.hide_select = True
                    # Outliner Icon - Eye
                    bpy.context.scene.view_layers[0].layer_collection.children[c.name].hide_viewport = True
                    # Outliner Icon - Camera
                    c.hide_render = True
            break
1 Like

Paladin comes to save the day! :slight_smile:

I am not sure if I am doing something wrong, but after running the script, some random collections are not turning on as follows:

script

How should I use the script? Should I only select the main collection to turn on the subcollections underneath, or should I choose everything I want to turn on?

Two reasons why I didn’t implement detection for sub-collections:

  • If the parent collection is hidden, View Layer, 3D Viewport or Render wise, its sub collections are automatically hidden. So there’s no need to hide them.
  • To get sub-collections, you need to implement a rather complex loop cycle to continuously check for sub-collections and their sub-collections (etc) until no more are detected.
    • I made examples of the scale complexity here & here.

What you want can be done. But not only is it overly complex (to my knowledge), it’s also not good for performance (the continuous loop).

1 Like

Aha, I understand. Thanks a lot for your reply and for your time!

I can still make the script that you’re going for, if you’d like. I just want you to be aware that it might be slower then manually Outliner toggling, especially if you have a lot of collections/sub-collections.

I have ~200 collections and around 5 sub-collections each. I am using a batch render add-on that turns of every collection after rendering, so I am turning them on by manual toggling which takes around 10 minutes (Maybe I am slow…)

I was wondering how hard it would be implement into blender to use alt+Left click to turn on/off selected collections altogether.

If it is not going to take too much of your time and if it will help me turn on selected sub-collections, I would really appreciate the script

Video Demostration

Code Snippet

import bpy

for w in bpy.context.window_manager.windows:
    for a in w.screen.areas:
        if a.type == "OUTLINER":
            with bpy.context.temp_override(window=w, area=a):
                # Icon - Checkbox / Collapse
                bpy.ops.outliner.collection_exclude_set()
                # Icon - Eye / Viewport
                bpy.ops.outliner.collection_hide()
                # Icon - Camera / Render
                bpy.ops.outliner.collection_disable_render()
                cols = [s for s in bpy.context.selected_ids if s.rna_type.name == "Collection"]
                for c in cols:
                    # Icon - Cursor / Selectable
                    c.hide_select = True

Summary

After experimenting with some stuff, Blender apparently already offers what you were looking for as operators. So I used some of those. Note: I couldn’t find the operator to toggle the selectable icon, so I made it with other collection functions.

Note: The operators are also available as standard UI buttons (minus the selectable icon which I can’t find as I mentioned already above) by right-clicking while selecting a Outliner element.

1 Like

Thank you and I am sorry for taking your time :slight_smile:

It is giving me the following error when I run the script

Python: Traceback (most recent call last):
  File "....blend\Open Collections", line 8, in <module>
  File "...3.2\scripts\modules\bpy\ops.py", line 115, in __call__
    ret = _op_call(self.idname_py(), None, kw)
RuntimeError: Operator bpy.ops.outliner.collection_exclude_set.poll() failed, context is incorrect

And for standard UI buttons -E to disable and Alt E to enable in View Layer-, it sometimes works and sometimes randomly doesn’t. I think I am giving up on this and I will do the rest manually. Thanks a lot again for your time!

If you don’t mind changing the attributes of all scene LayerCollections + Collections by global assignment, rather then manual selection assignment, we can do without the operators.

import bpy

# Variable
LIST = []

# Get LayerCollections - Recursive
def get_layer_children_recursive(p):
    LIST.append(p)
    for c in p.children:
        LIST.append(c)
        get_layer_children_recursive(c) 

# Get LayerCollections - Init
get_layer_children_recursive(bpy.context.scene.view_layers[0].layer_collection)

# Assign Attributes - LayerCollections + Collections
for c in [*set(LIST)]:
    if c.name != "Scene Collection":
        # Icon - Checkbox / Collapse
        c.exclude = True
        # Icon - Cursor / Selectable
        bpy.data.collections[str(c.name)].hide_select = True
        # Icon - Eye / Viewport
        c.hide_viewport = True
        # Icon - Camera / Render
        bpy.data.collections[str(c.name)].hide_render = True

@simsek Do you know why this may happened? I’ve the same problem. Subcollections can’t be unhidden at once and must be unhidden one by one.