 So, welcome everybody to my talk. I called it Animating Container Terminals for Lazy People. So, first, some things about me. My name is Jonathan Bell. I've been doing 3D for quite a long time using various programs. I studied computer science at Delft University. I specialized there in computer graphics, and you might have seen some of my posts on the Blender Artist Forum under the name of John Amater. Also a bit about my work. All of the things that the company where I work, TBA, is doing, it's already related to container terminals. We do logistic optimization of container terminals. We develop container terminal software. We train the planners for container terminals. And in one very small subsection of the company, we create animations for container terminals. And these animations can have different purposes. So, sometimes it is to explain one of the procedures in a container terminal. Or sometimes it is more to show plans for the terminal to possible investors. So, for that kind of purposes, we make these animations. Here I'll show just a few shots to show what kind of animations we make. This is all made in Blender. As you see, container terminals can be quite big. We have all kinds of equipment in container terminals. There are these cranes, a lot of movements with the containers, a lot of things driving around. And so this is just a short view of what kind of stuff we do. And there's also a lot of container interactions. So, where containers are going from one equipment to another. So, what am I going to talk about? I'll first talk a bit about how we organize the files in our projects. I'll talk something about the virtue of laziness. Show some tips and tricks that we have. Tell a bit about how we write plugins. And a bit about our render farm. So, first our project structure. We have a library folder structure. We check that whole folder structure into Git. Git is not ideal because it has trouble with binary files. But it's good enough. And we've been using it this way for several years already. We have the library files of all the equipment and the containers and all the different kinds of buildings and fences you might find on a container terminal. And we also have project files which are specific for each project. And we actually have them in one folder structure. We use a lot of linking, especially we link using the Duplic groups. And we always use relative paths so that if you want to render or work on a project on a different computer, you just need to make sure you have the whole directory tree cloned from Git or just copied from the other drive and then everything works. Until now, we have not really figured out what a suitable place would be to store the renders because you don't want to have them in Git or the montage files because you might want to have them in Git for the version controls but they need the renders to actually do something useful with it. So, we're still thinking a bit about that. So, in our library folder, we have an objects folder with all the meshes, textures, materials, that kind of things. We have an effects folder with reusable material node groups. We don't have a lot of them but we have some. We have a folder with animated objects. That's where we store our rigs. I'll tell more about our rigs later on. We have a projects folder and that is where we have the projects for the specific terminals and customers. In a project folder, we have the scene which is basically the background and then we have one or more animation files with actually all the moving parts in it. We have a fonts folder. It's very important to not use system fonts because if you then open the file on a different computer, suddenly the fonts look weird. Some backgrounds. And very important for us is scripts folder with inside add-ons, misc and modules. The add-ons folder contains custom add-ons that we developed ourselves or sometimes customized version of the add-ons that we can find online. The misc folder just contains scripts that are useful but you have to load them in the text editor and then click run script. And the modules, that's basically Python libraries. One of my plug-ins uses MySQL, for example, so then the MySQL Python bindings are in this folder. And from Blender, you can refer to a scripts folder and if you refer to it correctly, that means that it will automatically also find these add-ons. So that's how we have Blender configured on our systems. So the important part of my talk, laziness. Larry Wall said there were three virtues of a programmer and one of them was laziness. And why is laziness important? Well, the idea is you do the smart work and let the computer do all the dumb work for you. And if you find you're doing the same series of steps over and over again, automate it. So I will just give some examples of how we work effectively and in the same time in a lazy way in our work. First of disclaimer, some of the solutions I'm going to show are solutions I found out during the past few years. And once you have a working solution, you don't really look into different solutions. So maybe there are some new features in Blender that make my solutions obsolete. I don't know. I don't really care actually. I just use my solutions that work. And also my solutions might not apply to your specific situation, but you can be the judge of that. So in a typical container terminal project, we have something like 30 cranes, 50 trucks. We want to have 10 minutes of container terminal operation in which a lot of containers are actually switching parents, so from trucks to cranes to the stacks. We also have a lot of different shots or angles of the same terminal, so we also have multiple cameras. Luckily, we work at a company that also does simulations for container terminals. So if we have a simulation, we can have it store the x, y, and z position and rotation of everything that moves. Then with a plugin that I created, we can load it into Blender that gives a huge file because for every second, for every moving equipment, it stores a keyframe. And if you have 10 minutes of simulation data, that's really a lot. And we cannot always use this easy trick because sometimes the customer wants to show a very specific story and, well, the simulation just shows some general how the terminal works. Sometimes they want to show processes that we don't actually simulate, for example, when it concerns humans. Then in simulation model, we just say, this process takes two minutes, but we don't actually show the person walking around the truck or things like that. So that's where manual animation would also come in. So if we are not in the fortunate situation that we can just import the simulation data and, ta-da, everything is there, we need to do something with rigs and manual animation. And this is a quote from the Blender development blog that made me very happy because already for years I've been hoping for the possibility of just linking in a rig and using multiple instances of that rig and in the future that is actually going to be possible. But as long as Blender 2.8 is not yet here and feasible for work production work, I do something different. We use actually rigs, which are structure of empties and dupli groups and constraints and we append that to the scene and then we use that. So when you're making a rig, you have to think what do you animate most often and you have to think about how do you want to animate it, move it along a path or give it free movement or constraint movement. You have to think about anchor points and maybe other reference points that are important for you. So I'll give a few examples. The first one has to do with the question forward or inverse kinematics and what do you want to animate and how does the rest of it relate to that. And so I will show this in a blend file. So here I have a stack crane and this is a crane that drives along the stack and on the crane at the top you have a trolley which goes from the left to the right and on the trolley there is a spreader which is a sort of grabbing thing to grab the containers. Basically when animating this kind of crane, the only thing that's really important to us is the movement of the spreader because the spreader goes to the container, grabs the container, et cetera. So how we would animate that, first of all, insert a location key frame for the spreader. And actually what's important to note the spreader, this is not really the spreader, but this is an anchor point or an empty that I added below the spreader, exactly one container height below the spreader. And the idea why I do that is I can also select the container and then with shift S, selection to active and then suddenly the spreader is directly on top of the container which is fun, which is easy. So then for the spreader I insert another key frame. Then I wanted to actually grab the container, so I select the container and this anchor point and then I have this plug-in that I wrote to make things easier for myself and it's called switch parents. Basically it is similar to normal parenting operation except that it uses constraints so for the container it now added a child of constraint. Now we can decide where we want to move this container to. So we select, for example, we want to put it on top of that container, so shift S, selection to active, but then we need to move it up to point 38 meters. Oh, I forgot to move to the next key frame. Go again, sorry, select to active and then here we can insert another key frame again. So in this way it's very easy to make the crane move, but of course you see that the movement now it's going straight through the stack. You don't want to have that. So basically what you do then is you go to this nice curve editor and then you can say that the spreader stays up. Let me just move this one out. So you can say that the spreader stays up till the end and then it goes down and then after that it should go immediately up again. So I duplicate it along the x-axis and again and in that way it is making a nice movement. So this is just a quick example of how setting up a rig correctly saves you lots of time. I showed you the selected to active trick and the switch parent operator. What we do a lot for driving vehicles is we animate them along the path and then it's very important to choose what is actually the anchor point or the center or the, how do you call it, of the vehicle because you could put it here on the axis that is not steering. You could say put it here because that's the center of the vehicle or put it here, the front axis. I don't know why you would do that. But in our rigs we chose to put it on the axis that is not steering and in container terminals we have a lot of trucks and the issue with trucks is you want to have the trailer following the truck in a realistic way. You cannot just say that the trailer has to drive over the same path as the truck because basically the trailer doesn't exactly follow the same path. And we also want the wheels of the truck to turn and I've seen some workarounds that have to do with putting a car on a path and making the wheels turn but I haven't actually seen something that works perfectly. So the solution we came up with is baking it into key frames. So let me switch to the truck example. So here we have a scene and here we have a truck and as you see the center of the truck is actually the rear axis, the axis that is not steering. And in this rig we also have a target here and the trailer is always pointing towards the target. And now this truck it will move along the path. It's all very nice. So we go to the big animations dialog and then I say, well, every four frames I want to have a key frame, do it and then you see the timeline filling with key frames. That's also very nice for the file size. You get huge files this way. So you always try to keep that to the last point in your before rendering. But what you see is that the trailer is now nicely in the trailer. So the trailer is following the truck and also here you can see that it's just realistically following the truck. And something that you might even see, yeah, the wheels are also turning. And that's all what the script has calculated based on some settings that the objects have. So for example the wheels here, they have a custom property wheel radius. So this is another way of saving yourself a lot of time. We also, let me see how much time I have. I'll just skip this example and go to writing plugins because this is actually the tool for being lazy. This is a very important comic that XKCD made because it actually tells you how much time you're allowed to spend on automating a task. If you do a task five times a day and it takes you 30 seconds each time, that means that you have three days to work on automating it, creating a script for it. And that will earn itself back in the coming five years. So keep this in mind when you think about is it worth to automate or not. When you're writing plugins, we have MISC scripts that you load into Blender and then click Run Script. Or you can have plugins and you enable them and then you can use them. But it is a lot of extra work to write a plugin. And so I created Operator Script. You click it in the text menu. Then you have these fields you can fill out with how do you want to call it, what the tooltip should be. And then ta-da, you have your script. The only thing you need to do is replace the print hello world with something useful that your operator is going to do. Finally, I'd like to share a bit about our render farm. We started out with what is called the poor man's render farm. You have one PC with a shared directory which contains the file or the files in our case. And the output directory. And then all the other PCs that are going to help rendering, they have this placeholders checkbox checked and the override is not checked. And what happens is it stores an empty JPEG file and when it starts rendering a frame and when rendering the frame is finished, it replaces it with a real JPEG file. It has some down sides. It is quite annoying to start a render because you have to walk to each PC, open the file, wait for it to load, take some time, then click render animation. And then if you figure out you forgot something, you need to stop all these renderings and then start it all over again. It is impossible to queue renders. And if on one PC you forgot to update the Blender version, you have one PC producing frames that are slightly different and then after that you need to go through the folder and delete every so many frames, which is annoying. So we have version two of the poor man's render farm. I put Blender also on the main render PC just in a folder so you can just load it from there. You don't need to install it on any other PC. And I added a script in that folder and what it does is it checks in a render tasks folder if there is a new Blender file, if so, render it. And in that way you have a simple render farm. All the other PCs, you just start them up, start a script and that does the rest for you. Still, it was not ideal because for our projects you often have one animation file with multiple shots and each shot has a different start and frame, different camera, different frame step. Still quite annoying to fill that out every time. So now you can also add a file in your animation blend file. You add a text file called render plan and it's a tab separated file with this information and if that file is present then one folder will be created for each shot and inside that folder with that camera those frames will be rendered automatically. And so that is how currently our render farm works and the nice thing is it works with one PC, two PCs. Or if you're really, really in a hurry you can walk through the office and claim everybody's PC when they go home and set them to work. Although there is one limit, I figured out at a certain point something like 20 or 25 PCs and then Windows says you're not allowed to share the folder with more than so many users. There was something related to that. At least that's how our render farm works. So to summarize, how can you be lazy and effective? If you have smart findings you can save work. Custom plugins can be very smart findings and automate your rendering. Thank you.