Script – duplicate all selected "View layers"

Hi, can someone help me convert this script so that it duplicates not only the active “View Layer” but all selected ones?

import bpy
context = bpy.context
old_layer = context.window.view_layer
new_layer = context.scene.view_layers.new(old_layer.name)
collection = old_layer.layer_collection
new_collection = new_layer.layer_collection

for prop in dir(new_layer):
    try:
        attr = getattr(old_layer,prop)
        setattr(new_layer, prop, attr)
    except:
        pass

cycles = old_layer.cycles
new_cycles = new_layer.cycles
for prop in dir(new_cycles):
    try:
        attr = getattr(cycles,prop)
        setattr(new_cycles, prop, attr)
    except:
        pass


def recursive_attributes(collection, new_collection):
    new_collection.exclude = collection.exclude
    new_collection.holdout = collection.holdout
    new_collection.indirect_only = collection.indirect_only
    new_collection.hide_viewport = collection.hide_viewport

    for i, _ in enumerate(new_collection.children):
        old_child = collection.children[i]
        new_child = new_collection.children[i]
        recursive_attributes(old_child, new_child)

    for i, _ in enumerate(new_collection.collection.objects):
        tmp = collection.collection.objects[i].hide_get()
        new_collection.collection.objects[i].hide_set(tmp)

    return 0

recursive_attributes(collection, new_collection)
context.window.view_layer = new_layer

If I understand your intention correctly I don’t believe the ability to identify which collections are selected in the outliner is exposed to the API but instead are part of the source code.

My interpretation of your intention is to identify:

outliner_selection

Both the collection named ‘Objects’ and ‘Reference Images’ are to be affected and no other collection within the “Scene Collection” viewlayer.

As a hacky work around to an issue like this one possibility would be to perform a specific operation from the outliner context like bpy.ops.outliner.collection_color_tag_set(color='COLOR_01')

outliner color tag

Then you could make a list of the collections within the viewlayer that specifically have that property set to iterate over. Similar to:

import bpy
C = bpy.context
D = bpy.data


def recurLayerCollection(layerColl, collName):
    found = None
    if (layerColl.name == collName):
        return layerColl
    for layer in layerColl.children:
        found = recurLayerCollection(layer, collName)
        if found:
            return found

layer_collection = C.view_layer.layer_collection

coll_names = []

for coll in layer_collection.collection.children_recursive:
    if not coll.color_tag == 'COLOR_01':
        continue
    coll_names.append(coll.name)

print(coll_names)

At which point you could create a for loop to perform all your operations based on the names in the list coll_names and finally set the color tag property back.

Thx @nezumi.blend for answer :slight_smile: I think I explained it unclearly, so I’ll post a screenshot to illustrate the problem :slight_smile: