I’ve hit a roadblock in one of my projects, and I think it’s due to a design limitation. It’s not a bug per se because everything’s working as designed but it’s making the python API behave strangely around layer collections.
I’m making use of the collection linking in my scene. It’s the feature where, in the outliner, you drag a collection into another collection while holding CTRL, creating a 1-1 direct reference between the two child collections. It’s an awesome feature that I feel like is really underused in all the projects I’ve seen.
The only way I know to select a Layer Collection using the API is by name, using the underlying collection name. It’s all good and well, since collections are bound to have a unique name by design.
However layer collections don’t. A view layer can have any number of layer collections that link to the same underlying bpy.types.Collection
.
So in the case where every collection is mapped to a single layer collection, this code can be used :
import bpy
collection = bpy.data.collections["Cube"]
def find_collection(layer_collection):
if layer_collection.collection == collection:
return layer_collection
for child_collection in layer_collection.children:
return find_collection(child_collection)
print(find_collection(bpy.context.view_layer.layer_collection))
>> <bpy_struct, LayerCollection("Cube") at 0x0000022909E377E8>
And, it can be adapted to return a list of layer collections instead :
import bpy
collection = bpy.data.collections["Cube"]
def find_collection(layer_collection):
if layer_collection.collection == collection:
yield layer_collection
for child_collection in layer_collection.children:
yield from find_collection(child_collection)
print(list(find_collection(bpy.context.view_layer.layer_collection)))
[bpy.data.scenes['Scene']...LayerCollection, bpy.data.scenes['Scene']...LayerCollection, bpy.data.scenes['Scene']...LayerCollection]
But there is no actual way to diferrentiate between the 3 collections. context.selected_ids returns the same pointer when two linked collections are selected in the outliner.
So one can’t selectively and accurately include or exclude a particular child linked collection from a view layer using the API.
The problem shows when using the Collection Manager addon that’s shipped with Blender. It’s breaking apart when linked collections are used. It doesn’t take into account that a single collection can be used in many layer collections in a single view layer, and from my understanding it’s not possible using the API.
So my question is : Is there a design limitation in the way layer collections are handled by the API and is there a preferred way to circumvent it ? Obviously the C/C++ codebase knows about which exact layer collection is acted upon when the user clicks on the exclusion checkbox so it may just be a matter of exposing it to the API ? Maybe I am missing something ?
Cheers