 Hello and welcome to another episode of Scripting for Artists. My name is Sibren and this episode is about Blender Collections. These were introduced in Blender 2.80 and replaced the numbered scene layers and groups. I'm not recording this as usual at the Blender Institute but I'm home right now as so many of you and as a result the video will be less scripted and I won't have any slides to show so we'll just dive into Blender and I will show things there. So in the Outliner here you can see that we have a scene collection with Suzanne in it like one object and it has that default collection collection one so given that this thing here is called the scene collection let's look at the scene object and see if we can find a collection property. So here we have Suzanne and as a reminder here we have the convenience variables so capital C stands for bpi.context and capital D stands for bpi.data. You can't use these in your own scripts but you can use them here in the console while you're figuring things out. So let's take a look at scene.call then press tab and you can see it already has a collection property. We can get its name it's called master collection because it's the main scene collection and it has a property called objects and if you convert that to a list just arrow up and then type list with parentheses around the line and there you can see that one object Suzanne that was here. Collection.objects gives you all the objects that are directly linked into that collection. So let's see what happens when we move Suzanne into collection one it's still indirectly inside the scene collection because it's inside collection one and collection one is inside the scene collection but it's no longer in the scene collections dot object. If you want to have really everything then look at all underscore objects this is like a magical view that will give you everything in the collection itself so it contains everything that objects also contains but then it also contains everything that is inside collections in the collection in the collection in the collection in the collection and as you can see we have Suzanne so as many things in blender collections have to have a unique name because they are stored in data so we have dpi.data or in the console capital D dot collections and this gives us the collection one it does not contain the scene's master collection but it contains all the other collections so here we also can get the collections collection one objects and convert it to a list to see what's in there and again of course there is Suzanne in there so this already gives you a way to given the name of a collection iterate over all the objects in that collection so maybe you want to write an exporter that exports everything in one particular collection now you know how to access it and I'm saying iterate over the objects let's just take a look at how that would happen just to refresh your memory so let's say we have a nice little bohemian rap city going on here with four Suzanne's in that one collection if we say list the collection dot objects then we get all four of them of course so let's take a little example of how it would look like in a little bit more complex code you would basically say well collection a call or call or what you want to call it is collections collection one and then I can say for ob in call dot objects print opname is op dot name and this is a format string it's really useful you can just type an f before the opening quotes and then within curly braces you can write any expression like op dot name and what you can see here it lists all the names of all the objects so it loops with the for loop it loops over all the objects in the collection and then does something with it and this could be calling an exporter or this could be setting a material or it could be changing the name or whatever you want to do of course and in our case it just prints the name so let's take a look at creating a collection from python this is also done through the data dot collections collection so d dot collections let's take a look what do we have we have a new function so let's type new tab and you can see that you can type name and now we have a new collection called demo you want to use this collection as it's given to you because of course this is now available at dpi data collections demo this happens to the best of us everybody makes typos don't worry about it we can get given the name demo we can get the collection again and this is a big big pitfall that you could fall into because you may think that that collection that you just created with an m demo will have an m demo well let's take a look at what happens when we do it again exactly the same function call just telling blender to make me a new collection called demo but this time we already have a collection that is called demo and as I said collections have to have a unique name so what happens is that it calls it demo dot 001 as you're used from blender but now the name that we ask blender to give the collection is not the same as the name that the collection was given so if you now access bpi data collections demo you will see that you get demo of course and not demoed at 001 so what I would say is always when you create a new collection assign it to a name like this and then you're sure that you have the right collection afterwards you can change the name like scripting for artists and it will have the new name one thing you may notice in the outliner up here is that the name isn't there like the collection is not there yet so it exists in the blend file it exists in memory but it's not linked to the scenes master collection yet so how do we do that well we go to the master collection and then dot and tab to just get a list of everything that's in there and one thing you'll notice is this property called children and that contains all the child collections so that's all the collections that are linked into this collection so let's take a look there and there you find a function called link at this collection as a child of this collection well it's a bit cryptic two times this collection referring to different things but I think you get the gist we had our collection in the name collection so keep your eyes on the outliner while I press enter there we go and now it is part of the scene collection linking objects into this new collection is pretty much the same thing as linking other collections into it instead of using dot children dot link you use dot objects dot link so let's take a look we have our collection it has an empty empty set of objects nothing is in there and we can use dot objects dot link to link an object to it and like that we can add susanne dot zero zero three to it now let's put this into a bit more of a script so i'm going to subdivide here and change to the text editor create a new script call it move stuff dot pi always start with input b pi and now let's say we want to move everything that is inside one collection and move it into another uh so we have to have a collection from is b pi data collections collection one and we have something similar collection two is b pi data collection sf a so now we have our two collections let's loop over one and then add all the objects that we find into the other so for ob in call from dot objects call to dot objects dot link ob and this will already copy well link all the objects from one collection into the other what's left to move is to unlink from the other collection so we need to unlink from call from but that also means removing that object from call from dot objects so that means that by unlinking we're changing the thing that we're looping over currently and this is not a good idea that you shouldn't do this it did at best it will be unpredictable and at worst it will crash blender and you will lose your data the most simple solution for this of course there's many of them but the simplest is to keep track of the objects that you want to unlink so let's say to unlink is an empty list and in this list we will keep track of whatever we want to unlink later so we can say to unlink dot append ob and once this for loop is done we can and loop over this and unlink everything so for ob in to unlink call from dot objects dot unlink ob and this will work let's give it a try and my script failed of course let's take a look at the console if we look at the terminal from which I started blender you can see that it gives me a runtime error objects is n dot 003 already in collection sfa and okay fair enough it doesn't like us linking an object that is already in there so there's basically two ways in which to avoid your script breaking because of an error like this one is to avoid the error to begin with and the other is to handle the error when it occurs and I think in this case it's easiest to just catch the error and make sure that our script keeps running when that happens so the error says that line number eight is the problem so let's take a look at line number eight so line eight is this line in the code it's the linking itself of course that goes wrong and you can tell python to just give this line a try and see what happens so literally you say try and then a column and like the for loop and the if and the other things that we've seen that and in a column you have to indent the rest so that indicates what it needs to try and then when we look at the terminal we saw the runtime error that is right over here that is the type of the exception and I won't go into detail as to what it all means just know that you have to type it here so that python notes that if an exception occurs in this try block of this type then execute this code over here and in our case this is fine this happens when the object is already in the collection which means that we're happy because we wanted to link it there it already is there so it is all fine so we can let this pass which literally means just type pass there this tells python don't do anything here ignore the error nothing happened really the next line is of course still important because we still want to handle this as though the object moved so the linking went bad because it was already there it still needs to be unlinked from the original collection so we can just keep going and this should fix our code let's give it a try and there we have it all the objects have been moved into sfa have been taken away from collection and of course we can do the opposite we can say well just flip the names around run the script again and there are back again when this started so this is how you can move objects between collections one final thing we could do which maybe is a little bit useless but just to give a demo um we can also remove the collection that we moved everything from so that would be bpi data collection start remove call from so let's flip them around again we move all the objects from collection one to sfa and then once that is done we remove the collection and there we go now collection one is gone all the objects have been moved again and that's how you work with collections from python to end this episode let's take another look at the outliner and there are a few toggles that you can set like the restriction toggles so let's take a look if i want to change the viewport rendering of this collection you can see in the python tooltip which you can enable in the user preferences you can see that bpi data collections sfa dot hide viewport is the thing to go to so let's take a look there we take our data collections sfa dot hide well there you already have hide render hide select hide viewport and you can just set them to true back to false and you can play around with this and it pretty much does what you would expect from clicking on the icons so that's it if you have any questions leave comments and i'll see you in the next episode