 Wake up. Hello. Welcome to Tips and Tricks for new add-on creators. Has anybody in here actually already made an add-on? Okay, thank goodness, because this is for you. This is not like a beginner, beginner, beginner. We're going to go through anything like that. Can I make that big? We're going to go with that. All right. Well, cool. So who am I? My name is Zachy said I'm here. This is my first time at Blender Conference, having a great time. What have I done? I started in Blender in 2008 and Blender 2.47 with Big Buck Bunny back in high school. It was a great time and I used it throughout high school. I used it throughout college and then professionally for seven years now and run in my own business here with my fellow, fellow comrade Richard trainer and we have started Truby FX and we're adding developers. Like I said, Truby FX, we do stuff like true terrain, node scapes, true sky, true VDB, true space. Plenty of beautiful add-ons. That's who I am. Who is this for? This is for add-on creators who have already made maybe one, maybe two small or just like automation scripts or add-ons and are looking to ramp up their skills. If you're an advanced coder in here, great. I hope you'll learn something, but it might not be the greatest. But things we're not going to discuss in here. We're not going to discuss exactly setting up a new add-on and we're not going to be going through the actual API itself. There can be a little bit of script talk. We're going to have a couple verbal tutorials later on and we'll go through, I guess technically we'll go through the API there, but we're not going to go line by line, how do you find stuff? I'd love to go through these things, come up and talk to me if you think that would be really beneficial trying to go through some of these things in the future. But there's a lot of already beginning developer ones and so this is really when I started coding in Blender it's kind of like my letter back to myself about what would I have loved right after that first add-on. Now I want to make it pretty. I want to make it more usable. I want to make it faster or something like that. This is my letter back to myself on advice on how to just make that better. I hope you want to go. Group one, helping coders, how to find help for the Blender API. The first thing first, the best thing a developer has is somebody else. That's your best friend is somebody else, right? And so in the number one thing is always Google. So how do you Google a Blender Python related question? Because sometimes a lot of the terminology is similar to JavaScript, it's similar to Python, just Python in general, other C, C++. How do you find an actual Blender thing? And right there, start every search with BPY. It changes the game. It really does. You'll get specifically to Blender Python things. So first and foremost, always Google your question and always start it with BPY. If you start with Blender, you're going to most likely get, even if you get the documentation from Blender itself, it'll be the user manual from the UI and as an actual animator side of things. But if you do BPY, more often than not, you're going to get the actual API documentation. Number two, I assume if you've done any sort of Googling search, you're going to find these two places. There is two fantastic places to go for questions. If you want to ask a question, but more often than not, the question's already been answered. And that is Blender Artists and Blender Stack Exchange. These are the two number one places you're going to find. Honestly, when Googling, they're going to come up anyways. You don't always have to go to it directly to find your stuff. You're going to find it just by Googling. Third one is the Blender API Tutorials. And there's multiple things. This is kind of a heading. And so some of the things inside the Blender API Tutorials are things like the Blender Release Notes. When Blender releases a new version, there's an actual category for Python and text editor. And inside that, they will release all the Python changes that they do. And sometimes even within that, they will actually show you how to use the new feature. I think the most recent one that I found was they added search to string properties, which I was like, oh, that's a fantastic use. I have plenty of things I could do that with. And so just reading the release notes in that way will keep you up to date, and sometimes will help you find how to use the new stuff. Second one there is the actual docs.blender.org plus API current. Surprised the docs are very good. And inside those docs, well, most of the time, they're really good. There's a lot of really great stuff in there. And one of the things in there is the actual how to use many of the things. Like if you go to the operator section, you can do a template or example after example after example how to do multiple different things. Text editor templates. Inside the text editor, there's a template section, and there's lots of actual templates inside there for very common, how to do a simple operate, how to do a simple panel, how to do a new node tree, how to do a new node, like very, very cool stuff. And then, so that's all kind of blender stuff. But then there's a couple other places. These are the two that I have gone to the most. Sinesthesia.co. That is the creator of Mirage. And there's another one, I forget what it is. Oh, Render Plus. That's what it is, the creator of that. And he has very good detailed templates or articles explaining how to do, how to get really deep into stuff like UI lists and a bunch of other stuff like that. I will note that if it's not posted in the description of this YouTube video, I will post the link to the slides, I think. So if you're trying to take notes, you're like, holy cow, he's going so fast. I apologize. Oh, and the last one right there is JNM. I think it's how you pronounce it. Fantastic YouTuber. He has just blender tutorials in general. But he also does a lot of coding ones, specifically OpenGL. And that one, that's really nice if you're trying to do custom UI or you want to do your own custom gizmo that doesn't involve a blender's gizmo or stuff like that. Oh, and I've put QR codes, hopefully relatively to what we're talking about. So if you're finding this online afterwards or you're doing it right now, you can easily get that QR code later on and go to their site. So after another great place to find someone else who's your best friend or is in real chats, IRL, we have, so Iyadabed. That's not how you pronounce it, I apologize. He has a discord called Bpy. Fantastic, very active. He himself is very active, but there's also plenty of other people on there that are very active. You get on there, you ask a question, you go to the relevant channel and you ask a question. Very good. I've used it multiple times. It's fantastic. Then there's also, of course, the official Blender chat. And I've put two on here. There's the specific one to Python, but then I have a general link that lists all the chats because there's a bunch of different chats on there. And that's another one in real time. You can communicate with other people. Sometimes developers get on there and that can help out and stuff like that. In real chat, you can ask your questions. You don't have to go to a forum and wait three days and hope somebody clicks on your stuff and goes through that. And then, of course, the relevant QR codes. These are some GitHub repositories. The first two I actually haven't used, but I looked through there real quickly and they have very good examples of how to do some pretty common stuff inside the Blender Python API. Iyadmed, that's the guy who did the Bpy Discord. He has a repository again of very great templates and great examples of how to do some complicated stuff like ray casting and stuff like that. Easy Bpy by Curtis Holt. I don't know how many of you guys know Curtis Holt or watch this stuff, but he has this, it's almost like a Python library, effectively, that you download and you can use in your stuff. And what he does, this is more about if you're learning the Blender API in general. And you can call these very easy things like get object. And it'll just get the object real quick. So there's some really nice, easy ways to get into coding or to find a way of doing it because you can even just explore Curtis Holt's operators and functions and stuff like that to see actually how he's doing what he's doing. Next section, Coding Helper. So actually while you're coding, some helpers for this. First thing is things inside Blender. If you're going to do any sort of work inside Blender, the best thing, of course, is to in your user preferences go to the interface and enable developer extras and Python tooltips. This will allow you to see kind of the guts of Blender. It will also allow you to, it will also bring up new menu options in the right-click menu, such as Copy Python Command, Copy Python Data, Data RNA, I don't know, there's a couple of things and you can actually get whether it's the button operator that it's using or the actual property, that's where I was looking for either, the property that they use on there. Oh, also you can right-click on many things and there's an online Python tooltips that will take you to the website, the documentation for the exact property. Really nice. Python tooltips, that will actually show you what the property or operator is since you can copy and see all that sort of stuff. The next one is going to Prefs editing text editor. If you're going to do any just scripting in the text editor, you know, if you like the autoclose pair, so brackets, parentheses, curly brackets, it'll automatically close it for you, you don't have to do it. If you're used to closing it, I've recently turned this on since 3.3, which is when it was introduced, I believe, 3.1, apologies, and I still add my extra one, and so then I have errors because I always have too many parentheses and that sort of stuff, so be careful. Fake BPY module, I think this is one of the most important ones, if you have an IDE or something like that, I use VS Code and I'm going to, the next slide I believe is going to do some specific things to VS Code, but this, the fake BPY module which you install almost like it's an actual Python library, but this actually will enable your IDE or IntelliSense to fill in the actual stuff. You type BPY, and period, it'll let's out data, context, it'll give you all those options, like in the Blender Python editor, their console, and there's a lot of stuff like that which is really nice, and so that's how you install it in the command line or anything like that, you can just Google Python. Where it says version, normal way you do it is fake BPY module, latest, and that just does the latest Blender version that they have available, they're very fast, they usually have it immediately, or if you want a specific version instead of latest, you actually put 4.3, no brackets or anything like that, 4.3 is not a Blender version, so you shouldn't probably do that. All right, so VS Code, like I said, there's some VS Code extensions I would highly recommend, and if you're doing multi file Blender add-ons, I would incredibly advise you use VS Code for one extension and one extension alone, and that is the Blender development extension, and it has a bunch of functions, a bunch of snippets, and stuff like that for developing add-ons and scripts, so it was created by actually Jacques Luc, who's now the developer for Geometry Nodes, he's no longer maintaining it, so if anybody knows anybody who's really good at Blender and JavaScript, because most of it inside it's JavaScript and it's VS Code a lot of times, you should definitely get on that because there's some updates that could be really nice. So it's developed by it, but he's not developing any more, so the best one is a sorry, there's a, you can do a new add-on right from the visual code, like keymap stuff like that, so it automatically create a new add-on, create a new file, you can name it, it'll set up all your appropriate file structure, it'll put in the right way, and then this is my favorite feature, it'll reload your multi-file add-on every time you save it, so you don't have to press F8, especially if you're using a multi-file add-on, you actually usually have to close Blender and open it after every change, just because it doesn't register. There's some, Sebran has a talk like this from I think 2019, where he actually goes through how you do that, like in Python and I could never get to work, and so VS Code does it for me, and it's fantastic, and you just save it, and it will, it automatically reloads Blender, it doesn't close anything, that just reloads it, and also it implements debugging inside VS Code, which is a live sync, because you can do logpoints and breakpoints, and also you can pause your functions and actually see it line by line, a lot of really nice stuff inside that. You also keep your add-on outside of the add-ons folder, and it will automatically create a symbolic link folder into the add-ons thing, and so what I like about that is that TrueTrain has gigabytes and gigabytes and gigabytes of assets and stuff like that, and so every time I run it through VS Code, I'm not copying an entire add-on, you know, like 100 gigabytes over to the next version of Blender, it just does a symbolic link, so that's just really nice, but then that's what actually allows you to keep it outside of Blender, and so you don't accidentally delete it when you delete Blender, or uninstall Blender and things like that. And then you can also actually do script updates, like script updates as you were inside the text editor and hitting the play button, you can actually do that inside VS Code, and you have all VS Code's nice things, like the text editor doesn't tell us, it doesn't give you what's next when you hit period and things like that, but VS Code does, so you can actually do that inside of VS Code as well. Next one, that's really nice, Blender Python Code is this one, by just typing like operator, it'll give you basically the exact same thing if you went into Blender text editor, did a templates operator, a simple operator, and you can copy that and paste that into your code. So it's a lot of nice snippets for creating menus, operators, it even has I think for the register function, so it just automatically put def-redge and all that sort of stuff, it's really nice. Because I don't remember how to do all this stuff, especially those things you have to do to actually register the BLID name I never remember. And so I just don't have to. I just type operator and it does it all for me. Oh, sorry. Oh no, that's right. Sorcery. So this one's a little, it does cost money, though if you are doing this professionally, I would highly recommend it. There is a free version and it has limited capability, but basically what Sorcery does is it says, you know, this is not the most optimized way of doing this on Python. As you can see here inside the GIF, it has a for loop, then an if, and then you basically append it to this list and it will say why don't you just turn this to a list comprehension and it'll do it all for you. It's incredibly nice and it's nothing else, it's taught me to be a better Python user. Now the only problem, of course, with Sorcery is that their assumptions, these are better practices that maybe you don't agree with or your business doesn't agree with, that's the only difficulty with Sorcery, but as the owner of my own thing, it doesn't matter, so I can use it and it's really great and it just helps me do, because list comprehensions and a lot of those sort of things, comprehensions in general or generators in general are going to be much faster than if you just actually write out each thing inside Python. The next one is auto doxtring, this is just really good for making sure you keep your information straight and you actually know what your own functions do in the future. Those have been some of my biggest problems as I write these giant ones, I've never do a doxtring because it's too complicated and what's nice about doxtring too is you actually state which, what format type, do you want to use NumPy, do you want to, I forget the other ones, I use NumPy's version of doxtring formatting and it just keeps it consistent and it automatically does some fancy formatting thing and I think it's marked down and what not inside that and it's very nice, very, very nice. The last one that I would recommend is because I just, I figured out I'm a bad speller and I got tired of people telling me that I misspelled something, is code speller checker. And so this one is actually a spell checker for VS code and it will even do programming words. Now I'm going to give you a quick thing to actually get, so it doesn't actually try to spell check your variables and stuff like that. So in VS code if you take control shift B and then you hit, you type in user json, it should pop up immediately and then inside user json you're going to find the other C spell settings and then type basically this over to the right here or my, yep you're right and you type that and I've, in comments I've said which one it this way. So this one will, by including this in your VS code settings you will, it won't spell check all your random lettered variables and other things like that. It will only do comments, doc strings and strings. That's what I have in mind for because those are usually the most visible to other people. And so really nice make sure I have, I found a lot of misspellings because of this. Ones I didn't, no one even told me about. Alright next version. We're going fast. I hope it's okay. So this is, the next session is something that I didn't, I mean I think as soon as you're a developer of any kind, you're going to start realizing that the bpy.ops section is super useful until you need something from it. You need it to return something or until you butt up against the whole like, oh the poll function fail and like, okay but why? What is going on here? And so I'm titled this high versus low API. And so high API I'm defining as the bpy.ops operators and the low level is the stuff like bpy.context.object, stuff like that. So many Blender development add-ons tell you actually to do this. They tell you it's fantastic. The best way to get into Blender coding is to right click on an operator that you want to do and then paste it into your Python file. You want to create 10 cubes, write a for loop with a range of nine and then do the bpy.ops.mesh.create primitive cube or something, whatever it is and it'll create 10 of them. Like it's super fast, super great for automation but once you actually need those cubes and need to do something with it, it's incredibly difficult and you have to do a lot of work arounds and sometimes it's necessary but let's talk real quick because this is one of the things I had the hardest problem of trying to figure out to do is when do you use the high level versus when's the best way to use the low level? Oh, sorry, I'm going to have myself to some degree. This is right, these are the vanages of both, right? So the vanages of the bpy, the high level is that you write one line of code and that's it. And maybe some other lines to make it look nice and whatnot for the operators but if you needed to do anything with that, it's not you can't, you don't have to find the plane afterwards and sometimes that's difficult. Create plane low level at the low level code, right? This is actually how you create a plane in the low level and it's a lot more it's a lot more verbose, it takes a lot more lines of code but you notice here we already have the mesh data, we have the object data, we've actually already named it, now of course Blender does a unique thing where they'll put .001 or whatever, but you don't even if you have to name it, even if they do make it unique, you have it already in a variable, you don't have to go finding for it. You can tell what context it's in, you can actually do a lot of stuff with B mesh, it's a little more complicated because usually you need B mesh unfortunately to do some of the stuff anymore inside to create a plane or something like that. So, so, the vanages of high level, it's it's done, you don't have to really worry about it, it's one line of code, low level vanages, you have it all at your hands, you don't have to go try to find they don't have to do any work around to go and find it. Alright, now, when do you use both, right? So, when do you use high level API? So, when it's too complicated to do on your own, so some examples of this are to get the object or note under the mouse, under UV and wrapping, oh, I went too far, okay, my little preview is very small, I can't actually tell what's next. So, like, if you're wanting to get an object, you could cast a ray and then try to figure out if that ray intersects the object, any objects and, you know, there's a lot of complicated stuff there to just select an object, when you could just do BP wide ops, that select or something like that and then figure out by BP wide dot context, that object, you get it, right? Easy peasy. Or nodes, you can't even do it, there's not a ray cast in nodes, I even confirmed this with Jacques, is that it loops through every node in your node editor, calculates the bounding box and figures out if your mouse coordinates are inside that. So, those things like that, you wouldn't want to use that for, that's complicated, it's not necessary, the workarounds are useful in that in that area. And so, if you don't need anything returned, that's also a really beneficial way of, you know, an example of that is deleting the selected object, I don't know why you would do this, but you could use this inside your thing, you don't need that object afterward because it's non-existent or adding a primitive and not eating it afterwards, or once again, UV unwrapping, UV unwrapping is a big one, I used to do that, I try to do that once and it's just best to let the Blender operator try to do that on its own. It's just not when you don't need it afterward, you don't need the UV unwrap information afterwards, you're going to get it anyway just because that's the only way you can get it, is going and getting it afterwards in like BMesh or something like that. If you can't find a low level API, the thing has a lower level API, rendering, baking, I mean all these things don't have an actual lower level equivalent, or at least not that I know of, so sometimes you just have to, you just have to work around the pull functions and whatnot in order to get it. Yeah, open a new Blender window slash area, or if you're another add-ons function, if you want to include for some reason your own add-on function potentially, you're going to have to call the operator, because you should know the pull function if you're going to do that one. And the last one is too slow, right? Python is relatively speaking a slower language, incredibly fast, faster than you or I can do anything, but it's relatively fast, so but if you're iterating over a bunch of data, Python will always be slower than doing it in C or C++, so again, do I have, I don't have it on there, but again UV unwrapping would be another example of this, you're not going to want to, especially if you have a high resolution mesh or something like that, if you don't want to loop over that mesh and try to UV unwrap it and develop it, unless you're doing something completely different. If you're just trying to automate something, usually it's best to let it do it if it's going to be an iterator in that way. All right, so when do you use the low-level API? So 98, 90, what did I say, 95% of the rest of your code should be really the low-level API. It's a lot easier to work with, I find, and it's more predictable. So if you're using an operator in an area that it wasn't intended to be, like if you're trying to delete an object from the node editor, there's going to be a pull problem because it's not going to be able to get the context of that object, because the context is very different. There's no context of that object, there's only context of that node. So stuff like that getting around, that's going to have a problem where you have to actually find the right context and stuff like that and deleting the object, I don't think would work. Right. If speed is your key, and now we're talking relatively speaking, but if speed is your key in did I give an example of this? Yeah, so, okay, yeah, yeah, sorry, it's been a little bit. So a lot of, like we talked about operators have a lot of extra code, i.e. pull functions, but I mean just pull functions, like the create a cube thing has the ability to do transform data, has the ability to do UV unwrapping, all included in that. You may not need that, but the operator is doing it anyways, and so if you're creating a thousand cubes you're doing all these all these things that you don't need automatically, and every time you call the operator, it's also doing that pull check, so you may have fixed the pull check, but every time you call that operator, it's going to recall that if statement, which I mean if statements are relatively speaking, but if we're creating thousands of cubes it's going to be a problem. Is there anything else I list on here? Yeah, that's exactly what I said. So all right, let's actually go into some code examples. I'm doing good on time. I have one very short one, it's one slide, and I have one very long one, it's multiple slides. So we're going to go through two things. We're going to go through installing an external Python library, and then we're also going to go through a nice visual way of doing what is it called? Progress bars, that's what it is. So first one, how do you actually install external modules that are not included with Blender? Import sys, import subprocess, sys.executable, that's the Blender file, that's the Python file that your current Blender file is using, and then you call subpressus.call, and you put those arguments, first here what we're doing, we're making sure that pip is installed, because most of your users probably haven't done anything with Python, and so sure pip is something that's included with Blender just in case pip is not installed. User means it's going to do it for the actual user, sometimes that's also needed for some permission issues. Upgrade, make sure that pip is going to be upgraded sometimes, and then default pip, it's kind of something that's necessary. And then we do if process.call, args equals arguments, and this if statement, make sure that if sure pip does not actually install pip, it does not try to then install anything else. So if pip is not installed, then it returns. This is not a function, so it would actually throw an error. And then we go move on to effectively the same thing for the actual Python library you want, and then at the end there is the library name, that's what you would actually want to do. If you wanted to install it, so adding dash dash user will also place it inside your user's Python site packages folder, which is in the, it's similar to, it's the Python library just for the user. And when it does that, it allows other blender versions to use the same Python library, or sometimes it might be already installed because something else that uses Python is wanting to use it, or another add-on or something like that. And so that's very useful. However, if you don't want to, for whatever reason, install it in the user, you feel a bit iffy about that or whatnot, you can also, down here, instead of user, you would do dash t equals and then your target directory where you want to. One of the good ways to put it is in a folder called module, or module, so that would be next to add-on. Sometimes you have to actually add it in the blender folder structure. But that's a good way to do it because Blender will also automatically check in a folder if it's there for those modules and include it in it. If you do it anywhere else, you're going to have to actually include it in a path and it's very complicated. I would not recommend using that. All right, so that is installing modules that are external to, or Python libraries that are not included with Blender or the normal Python library set. So progress bars. So the way I found to do best progress bars, Blender has a window manager thing for progress bars. It's a little countdown. It's very small numbers. Is it great? Yes. Is it wonderful they've given us something? Yes, it's fantastic. But we all want the render or baking little slider button, right? And how the heck do we do that? I try to do this forever and because once you start an operator, it's going to pause, right? It's going to freeze all of Blender. And so what we're going to do, I'm going to show, we're going to go through. We got 13 minutes. I think we got some time. No, sorry, we have 23 minutes. Is that we're going to actually do a modal with a timer inside Blender. And so we're going to have two threads. One thread is actually what Blender and its UI is rendering or is using. The other thread is what actually runs what we want to do. And then this thread reports progress back to this and then in the side the actual modal thing, as you'll see, it actually updates the UI and stuff like that. Oh, and there's the worker thread. It actually does all the work and reports back. So we're going to start. I have a gift here just to, I know this is the templates. If you don't, if you work to the templates and the text editor, fantastic. It's fantastic. So we're going to start with the modal operator timer template. And we're going to go based off of that. So we don't have to start from scratch. And we do want the timer version of the modal operator template because without the timer, the UI will only update generally when the mouse is moved or when an event actually is triggered. So if you hit a keyboard press or a mouse movement or mouse press, that's the only time your modal will actually run. And so we definitely want the timer one because the timer will actually, it will fire this modal operator every, we're going to do 10th of a second, but however long you put it in. All right. This is where, hopefully it doesn't get too dense. And hopefully I don't speak too fast because I just want to make sure we have enough time for questions. So we're going to start with the register function. We're going to register in the text editor just because, I don't know, when I was making this, I thought that was easier to do, but we're going to see it actually in the text editor. So we're going to register two properties in the text editor. The actual progress bar, which is just an int property that we're going to advance, set to percentage, so it shows a percent sign. And then show progress bar, which is just a boolean that shows, or we'll do a menu function that actually shows or hides the actual progress bar itself. We're going to register our modal class, which we haven't built yet, but we will. And then we're going to actually append to the header where it says our actual menu function that we'll show or hide the progress bar. And then we unregister all that. So just make sure you see that. We're going to first then talk about where you have some variables inside the modal operator, how many cubes we're going to actually end up creating, how many cubes we've actually created, which was the one we'll actually update. Updated, this is good for our modal function. It's not really useful for the one I've built, but it's a good practice so that way your modal function only does math if it needs to. Again, you'll see. End early, which will cancel the other thread. And then this is our thread so we can do some checks while we're in the modal operator. Then we actually are going to do, this is the worker function. This is the function that we're going to pass to a separate thread and we're exactly doing all our work. You see we're doing, we're basically, we're doing a while loop. We're making sure that the cubes created doesn't equal the total cubes or it's still lesser than. And then we have effectively the same mesh creation script. This time it's a cube instead of a grid or a plane that we did have before. And then down below we have the, we're actually updating all of these. So it's self.cubes created, plus equals one, self.updated equals true and then we're checking if anything has set this to end early and if so, return it and it will kill the thread if it actually ends early. Good, we're busting through this. Alright, this is the execute function. This is what will most likely, unless you have an execution function, it's what will actually be called first. You can also do this invoke, it doesn't have to be execute. So again, the window manager, we're setting up our timer. 0.1 is a tenth of a second telling it where to go, what actually window to do. And then we're adding this operator to the modal operator. Modal handler, sorry. And then here is threading.thread target equals self.cubes, which is that function we just talked about. And we notice that we're passing it without the parentheses. And then as a callback. And then for this one, we don't have any arguments, but inside the parentheses is where you would put the arguments. If you only have one argument, make sure to put a comma or else it will throw an error. And so remember, threading that thread. These are threads, not processes. And so you're still running on the same core as Blender. And so if you're doing very intensive, CPU intensive stuff, the Blender UI will still update, but it will be buggy because you're on the same core because Blender right now doesn't still like multi-processing. So it's the same thread which will allow you to update your user for progress bars and stuff like that. But it will be a little bit buggy. And if you want to know about threading, there's lots of YouTube videos. Okay. We're just getting this, we're making sure that we're showing the actual progress bar because we're starting everything. Making sure our progress bar integer is set to zero because sometimes if they run it multiple times, sometimes it's not always that. I don't know why that is. Maybe someone else does, but that's fine. And then we're actually telling the thread. The thread's not started up here. The thread is started right here where we surprise say start. And then returning running modal. And that will actually then make sure it knows that we're calling the modal and it will add, it'll make sure that it's actually added to the stack and stuff like that. It's not a stack, but it's kind of like a stack. Now here is where the actual modal happens. So every time the timer is fired or a user moves the mouse or interacts with Blender in any way, this function itself is what's actually called. So we see right here at the beginning, we're tagging the area to redraw to make sure, that was pretty, to make sure that it actually shows that our progress bar is updated. We see here, we're checking if the user wants to, in Blender fashion, if they hit escape, we were actually going to set self.end early equals true. And that will next time that createCubes actually gets to that bottom line, it will see that's true and it will end the thread and then down here you'll see that we actually check, we'll get there. And then we call self.finance, which we haven't talked about. You just kind of tidy some things up, returns canceled. Here's where we actually are doing math, right? If we, sometimes if you creating cubes is not, it's going to be pretty fast. But sometimes if you have something that takes a long time to update between each iteration, you know, you don't want to necessarily get nothing, get the same result 10 times a second. And so right here, it just kind of helps keep things tidy if the self.updated. So we calculate progress, make sure it's an end to multiply by 100, set it to that actual property that we registered and set self.updated equals false, just keeping ourselves tidy. And then we check if the thread is actually alive or not. And if it's no longer alive, whether it's returned because it's early or it's returned because, well actually up there it will do that. So this is if it finished itself. So once the thread has finished, it's no longer alive and this will return that it's not alive and we can clean up with self.finished and return finished. Now, the last statement here, right, if none of these other, these two return ones actually fire, right, it's going to eventually get to return pass through. You can do two things. Pass through allows any other events that have triggered it to pass two other things inside Blender. So but if you don't want it, if you want the UI to freeze but not freeze in the sense of like it turns white you want it to freeze in the sense that they can't actually interact with the stuff. That way they're not messing things up while the other thread is working. You can actually return modal again, running modal again and it will freeze the actual UI and it will, but it will update the timer still. So, but if you don't, if you do pass through, it will, it'll let all other clicks and something that go through and they'll be able to use the user interface like normal. This is the last little bit here. Everything we've been talking about has actually been inside the operator class except for this header draw function. So, if that was confusing, I apologize. I try to include the class and the actual functions inside that class in each one if it was going to. So this is self that finish. This just removes the timer. You don't need to remove the modal operator does that itself when you finish or when you return and then we're just setting the progress bar to not be displayed. This is the actual thing that displays that the progress bar is what we appended to the header in the text file. So, okay. That is how I have found the best way to do a progress bar is multi-threaded. And it works really well most of the time. We use it right now to actually install our assets. We have, there's a true BDB has gigabytes upon gigabytes of assets and locking a user's computer up where it just goes, at least in Windows where it goes white screen is horrible. And most people don't know how to start Blender from the terminal or to do the whole console reveal thing which is another great way to show in a progress bar. But that's not great. And you can't automatically do it so it doesn't work. So this is the best way I have found to show the user that you're still doing stuff. And what's nice in that update function in the modal, I'll do lots of other stuff. I'll do like a timer update. I'll do what I'm actually working on so I can report back the cube name that I'm creating or something like that and it'll show it in the interface or in our part. It's usually what file we're zipping or unzipping or what zip file or something like that. If you're doing files, threading is really mostly the best for actual file based operating system thread based, sorry file system based work because what a thread will do is that normally if you write or copy or unzip something from a file, that function waits. It waits and it waits and waits until that file is unzipped or copied or moved. What threading will able to do is that it will do the decompressing of a file or whatever the CPU can do and then pass the rest off to the hard drive and then move on to the next one. It won't wait for the hard drive to copy or paste or move things around so there's a lot of useful things if you're moving files around for whatever reason inside Blender for your add-on. Otherwise, and usually the user interface isn't laggy at all because all the work is actually on the hard drive not the CPU. So, alright, so I've been Zach Easton with True VFX. Any questions? Alright, yes sir. Oh man. Well, if you ever use a True add-on you'll notice that we don't do this either. We don't know. But we have some ideas. Yes, GPL is definitely the way it is. It would be really awesome. Blender has been kind enough to give us the GPU and right now for now we saw the GBL or BGL library for accessing the OpenGL thing. But it'd be really nice and maybe someone has, oh actually, you know what that JNM guy that I talked about on YouTube, he actually has a repository where he has his own kind of version of an API for OpenGL inside Blender and you can use it. It's free. He said it's open source. You can use it. And so, yeah, you know JNM guy, that would be a really great guy to go to or to get his repository and see and maybe even do updates and stuff like that. Because it will auto, it will, it does. As I looked, he had panels, he had buttons, he had sliders, he had sliders even like where it was like a dot on a line and stuff like there's a lots of different stuff that he actually had that was a little bit more easier to work with. So I check there, see if that works with your style and what not. So, yeah. Yes, sir. Sure. So, I don't do C++. I've looked into it, actually, so we also do an add-on called Nodescapes, which is procedural terrain creation. You want that thing as fast as possible. And really, it is. If you have to do anything where you constantly do the Bpy access, basically, you're going to probably need to stick with Python. I've just recently seen some people who are trying to, basically, they make their own C++ objects. And then you can actually get, as a pointer, many of the properties inside Blender. And then you, I don't know what they do after that. I don't know how they know exactly, I guess they look at the source code. But one thing we've done with Nodescapes is what we do, we get all the data, as much as data as we can from Blender, right, load into arrays or whatever we do because Numba, or not Numba, sorry, Nodescapes is basically just an image if you think of it. It's a black and white image because it's just height values. And so we get all that array, we have all the information we need. And then we actually pass it to, I've done, I've dabbled a little bit in C because it is faster. And then there's a thing called Ctypes, which you use in order to get it. That's no fun, because then you also need to compile upon Windows, you need to compile upon Linux and Mac. So there's things called Scython, which I've tried to get to work and I've never been able to do, well, we're currently doing right now in Nodescapes. We just released it because we wanted to do multi-threading and we wanted to do M1 support. And the easiest way to do that without buying an M1 we found is actually a third-party module called Numba, N-U-M-B-A. I thought about talking about today, but I was like, that's a beginner, I don't know. So if you're doing a lot of math and you're not actually going into and actually selecting or going and dealing with anything in the Blender API necessarily, you can export everything, Numba is good. And so what Numba will do is that it compiles everything down to a hardware level code. It's as fast as C normally and it's very simple to do. So you write it in Python, you add a decorator from Numba and that will then get you, it automatically compiles it all for you. It does a lot. And with a simple argument to that decorator parallel equals true and then you replace a couple of things in the code, very simple, with basically Numba's version of that, you get multi-threading. And then there's a whole other level that allow you to do GPU. And not just GPU for NVIDIA, they also have a, right now it's beta, it's for AM... What's the other one? No! What's the other GPU? AMD? Thank you. I kept trying to say AMS and AMU and what not. AMD, they have a beta version for that so it's possible to do that. But we're just now looking into that so I couldn't give you any information about that. But Numba, if you need to get out of Blender and it's all math-based, basically and you can and know how to do parallel, I would recommend Numba. Not to give away all our secrets, but there's our secrets. All right, is there any other questions? Yes, sir? Yes. So like you said, it's the multi-processing one that's not supported but we're using multi-threading which is supported. So multi-processing is actually where you use multiple cores of the CPU. So like my CPU or like a normal CPU maybe has four or eight cores, but threads, it has twice that amount, right? You have kind of one thread and it's able to switch back and forth between these threads if one thread is busy. And so threading works and it works very all the time. The thing is, again, it's not... It's parallel but it's not parallel. It's kind of more like they're switching when one is busy. They're switching back and forth. And which allows you to... That's why I said if you're using Blender API for anything or if it's just really laborious, you're going to see stuttering in the UI. And so that's what it is. So it's like you have the Blender working in one thread and when this one's not doing anything it'll work on this one. And when this one's paused for a second it'll switch back and just... It kind of does something like that. And that's how the UI is able to do it while this one still works. Does that make sense? So thread was inside threading. Threading is the Python module. Thread was a class. It basically to create a thread. The one that you're not supposed to use is multi-processing. Does that make sense? So, yeah. That is my experience. It's been fine. I've used this. We try to make it compatible back to the most recent LTS and 2.93 at least. If it wasn't supported in the past it's at least been supported since 2.93. Okay. Any other questions? Yes, sir? Absolutely nothing. I'm just now really honestly getting very comfortable with it. That is the one that I've really found that it's best to do. Because again, it's not a background process. You're not doing something on a different core. So it's really only useful if you're trying to update something with the user interface that you don't want... Basically it's just anything to report back to the user. Your experience more than anything else. So inside actual functions it's not going to parallelize anything. Which is very frustrating because it would be really nice if you could do that inside. But Python in general has some difficulties with multi-processing compared to other ones. Other languages. Yes, sir? So... Mine. So actually I almost forgot to say this. If you go to this link right here, this GitHub link the two examples I said are on that. Hopefully letter for letter. I don't think I changed anything. So if you go to... Here's the actual word link but then a QR link. If you go there you actually might have the repository. It only has like four things. So it's not like you're going to be scrolling and scrolling and scrolling. Two of them are ones, the Python library module installing and the other one is the the progress bar. So hopefully it should work. It should be pretty simple to fix. I'm hoping. If not, hey, contact me. We have a Discord my email is ZachEason at gmail.com and so there's other stuff like that. Feel free to contact me. I don't mind doing that. Or come find me afterwards. If you try it tonight and you're like you suck. It didn't work at all. I'm like come back and find me tomorrow. I'm like, oh, okay, my bad bug and I can post a comment on an interview or something like that. Anything else? We have five minutes. Yes. Yeah, so I've been Yeah, so for those who didn't hear I should have done this very question and I apologize for those who are viewing it afterwards like myself and I'm like what are they asking? What is he answering? She asked basically how do you judge timeframe for creating a new add-on? That's a really good question. Honestly, we're about to start TrueTrain 5.0 and we're giving ourselves six months, but it might be more because we're going to, we've advanced as a developer and so there's a lot more stuff I want to implement and try and so we'll see. It might be six months and honestly the best way I know is to do and then like write down. Or like, you know, it really it's doing. It's doing and timing yourself. I have to say I time myself. I'm very bad about doing that. But yeah, I'm not the greatest. I am the greatest. You should listen to me, but I'm not the greatest. You shouldn't listen to me. So yeah, I apologize. I don't have a better option than that. I just kind of know. It's dependent upon your actual abilities and like how much you know what you don't know compared to the add on you're creating. So, but I will say hopefully if you follow a lot of the advice, especially the VS Code stuff, a lot of the banging your head against a keyboard until it breaks is usually taken away. Or at least it's left to trying to find whatever the API for what you're trying to do is. So, yes, sir. Oh, great question. Okay, so what he asks is like are there add-ons like currently shipped with Blender or maybe even that you buy to actually view and read their code? Yes and no. There's some stuff like I looked and kind of, it really depends. I would say definitely find the add-on that's doing what you want to do and then read the code. I would hope that all developers are totally fine with you doing that because we're all trying to lift each other up here, right? I'm giving away our secrets because I'm hoping to lift the Blender community as a whole up and it's like that. Like when we were developing Nodescapes, I definitely looked at the ant landscape add-on and like seeing, okay, like what are you doing? How are you finding these things? Because we're doing Matthew Tills for the noise at the very, very beginning and it was just so slow. I was like, so is ant doing this as well? And it turns out they were unfortunately, so we did some other work arounds, but yeah, so find the add-on that is doing what you're doing if you can find it and or doing something similar and see how they're doing it. And definitely usually the very popular add-ons are doing some really cool stuff, too. I believe I saw, I'm sorry, sorry. Yes? Not yet. So unfortunately when you become a full-time developer I feel like I don't mean like, sometimes I forget to even use our add-ons. I'm using the add-on that I'm currently building and stuff like that, but any more right now we really rely upon those using it. We have a fantastic user base that we're very grateful for and we're using it on that. So I wanted to do the stable diffusion or dream texture or stuff like that. Oh, for like the actual VS Code, AI for like VS Code stuff like that. Again, wanted to just haven't like gotten into and done the free trial and things like that, but I want to, I love to do it, yeah. Okay, I believe you because it looks cool and VS Code keeps like, I think they bought it now or something like that and now they keep showing events on YouTube. Oh, another thing, if you like VS Code, VS Code has really great videos online, on YouTube, especially they've been doing shorts fantastic. Very much enjoyable. Sorry. Yes, sir. And that's the last one. I don't think I have a number of time. Yeah. That is a fantastic thing. So for those who didn't hear because they didn't have a microphone, you can all, a lot of, actually all of the UI is written in Python or the Blender Python API. And so what you can do is you can actually right click open up script file because you have those developer extras added on and actually open up the script that's doing the API usually unless it's some very dynamic thing. You can actually see how they're doing it. Or if you can search sometimes, sometimes there's code like modifiers. I don't think the Python API is no longer doing it for the modifiers, but you can find old ones where they were doing it. And so, yeah, finding that, finding old use of Blender API too. All right. Thank you all so much. I am so glad you're all here.