Each collection has a
children (collection) property. Easy to figure out using the python console:
>>> C.scene.collection. all_objects animation_data_clear( animation_data_create( as_pointer( bl_rna bl_rna_get_subclass( bl_rna_get_subclass_py( children ...
To get the first level of all sub-collections, you can just iterate through the list:
>>> for coll in C.scene.collection.children: ... print (coll.name) ... Collection Collection 2 Collection 3 ...
To add a new collection, create a new data-block and then use
.link(collection) method to add it to whatever your main collection is:
>>> C.scene.collection.children.link( link() CollectionChildren.link(child) Add this collection as child of this collection >>> my_sub_coll = bpy.data.collections.new("My Sub Collection") >>> C.scene.collection.children.link(my_sub_coll)
The same principle applies to all collections, no matter the collection is on the first or any other level. Example on how to add a new (sub) collection to the active collection:
>>> active_coll = C.view_layer.active_layer_collection.collection >>> active_coll.children.link(my_sub_coll)
You can also specify the each collection by its name
C.scene.collection.children["Collection"] or you can even use the index operator
C.scene.collection.children but that's error prone. In case the name of the collection or the scene hierarchy changes you're lost. Better practice is using pythons
get() method to basically perform a search for the collection in the first place:
>>> C.scene.collection.children.get("Collection") bpy.data.collections['Collection']
Basic example using
import bpy C = bpy.context main_coll = C.scene.collection.children.get("Collection") if main_coll: # Create the new collection my_sub_coll = bpy.data.collections.new("My Sub Collection") # Add it to the found collection main_coll.children.link(my_sub_coll)
Advanced example on how to add a new collection to an arbitrary collection in the scene using a recursive loop based on https://blender.stackexchange.com/a/137866:
import bpy def traverse_tree(t): yield t for child in t.children: yield from traverse_tree(child) coll = bpy.context.scene.collection for c in traverse_tree(coll): if c.name == "MyCollection": # Specify the name of you main collection here my_sub_coll = bpy.data.collections.new("My Sub Collection") # Add it to the main collection c.children.link(my_sub_coll)
Notice that you add objects to the collection(s) the same way by just passing an object when calling the
.link(object) method on the actual object (collection) property, which is actually pretty nice and convenient:
posting how I do this in blender 2.90 for others in case it's useful.
doing it like this doesn't require context or ui polling.
import bpy #create scene collection shared_assets_collection_name = "Shared Assets" shared_assets_collection = bpy.data.collections.new(shared_assets_collection_name) bpy.context.scene.collection.children.link(shared_assets_collection) #create subcollection cname = "Actors" c = bpy.data.collections.new(cname) bpy.data.collections.get(shared_assets_collection_name).children.link(c)