8

Is there a way to change the "active" collection? I can check witch collection is currently selected with this code:

>>> bpy.context.collection
bpy.data.collections['My Collection']

But I can't change it using this property because is read-only. Is there a way to do that?


EDIT

After some research I found out part of the solution. I can use this code to get and set the active layer collection.

# Get the current active layer collection and store it in x
x = bpy.context.view_layer.active_layer_collection
# Select another layer collection from the outliner,
# then use this code to restore x as active
bpy.context.view_layer.active_layer_collection = x

the new problem is that x is not a Collection object, is a LayerCollection and we can't pass any collection created with the method:

myColl = bpy.data.collections.new('My Collection')
bpy.context.scene.collection.children.link(myColl)

So the refined question is: How to obtain a LayerCollection for a particular Collection to change the Active Collection?

johnzero7
  • 359
  • 1
  • 3
  • 10

2 Answers2

11

In Blender 2.80, I've had some success with something simpler that previous @johnzero7's solution :

collection = bpy.data.collections.new('My Collection')
bpy.context.scene.collection.children.link(collection)

# NOTE the use of 'collection.name' to account for potential automatic renaming
layer_collection = bpy.context.view_layer.layer_collection.children[collection.name]
bpy.context.view_layer.active_layer_collection = layer_collection
rotoglup
  • 353
  • 2
  • 10
7

The only way I could find to obtain the LayerCollection for a particular Collection is to transverse bpy.context.layer_collection looking for the name I want

#Recursivly transverse layer_collection for a particular name
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

#Create one collection
myColl = bpy.data.collections.new('My Collection')
bpy.context.scene.collection.children.link(myColl)

#Create another collection
myColl = bpy.data.collections.new('Another Collection')
bpy.context.scene.collection.children.link(myColl)

#Change the Active LayerCollection to 'My Collection'
layer_collection = bpy.context.view_layer.layer_collection
layerColl = recurLayerCollection(layer_collection, 'My Collection')
bpy.context.view_layer.active_layer_collection = layerColl

#Change the Active LayerCollection to 'Another Collection'
layer_collection = bpy.context.view_layer.layer_collection
layerColl = recurLayerCollection(layer_collection, 'Another Collection')
bpy.context.view_layer.active_layer_collection = layerColl
johnzero7
  • 359
  • 1
  • 3
  • 10
  • 2
    It's weird to have to iterate over all collections to get or set the exclusion state of a particular one... – Gorgious May 05 '21 at 07:02
  • @Gorgious but that is the only way currently to also capture nested collections? but it does not solve this problem https://blender.stackexchange.com/questions/302094/how-can-i-fully-select-a-collection-using-python-with-blue-highlight – Harry McKenzie Oct 03 '23 at 01:28
  • 1
    @HarryMcKenzie yes, it also doesn't take into account that a collection can be linked in several layer collections in a single view layer. This solution only selects the first one it found. You might be interested in my discussion over on devtalk – Gorgious Oct 03 '23 at 08:29