Support Blender Core Development with a monthly contribution.
The creators who share. Access production content and knowledge from the Open Movies.
Latest news and updates on Blender development.
Join the community and help with design, development, docs and more.
A platform to collect and display the Blender Benchmark results.
Documentation on Blender's features, tools and API.
The yearly event that brings together the Blender community in one place.
Download the latest Blender version, or try the beta!
Introduction & copy-pasting
Names & Objects
Stuff on Lists
Collections: Mass-Rename of Objects
For vs. While
Your Own Operator
From Script to Add-on
Roast my Add-on
The Roast of Nature Clicker
Readability & Understandability
Render 10,000 OBJ files
Mass-Rename Bones & Vertex Groups
Rendering from 'all' angles
2nd April 2020
Operators are the first step to creating custom buttons, menu items, and panels in Blender. In this chapter of Scripting for Artists, Sybren explains how to create your own operators.
Join to comment publicly.
16th May 2020 - 20:49
As someone who really struggled with Python and the Blender API a year or so ago, these videos are a life saver! I love your way of teaching. It's very clear and easy to understand :)
29th November 2020 - 05:20
I am following along verbatim, step-by-step, but the monkey_grid.py is not registering, where I cannot find it in F3 menu. In addition, when I save the file, close out, and restart blender, the monkey_grid is not found in bpy.ops.mesh nor F3 menu. I am working with Blender 2.9.1. Is there an update to 2.9.1 which can potentially be prevent the scripts from registering? Or, could a step be missing from the video? Thank you in advance for your help.
29th November 2020 - 22:22
@Sybren A. Stüvel
4th December 2020 - 18:19
@Jay.w.overstreet i got this from the youtube comments and it worked: Edit>Preferences>Interface tick Developers Extras
30th December 2020 - 23:58
@George Castro Thanks! I will give it a try.
7th December 2020 - 23:32
@Jay.w.overstreet Same problem here, checked the code all over for typos but it seems exactly like in the video. It does not register for me in 2.91.
11th January 2021 - 13:59
Be sure to distinguish between "does not register" (i.e. bpy.ops.your.operator() doesn't even run in the console) and "cannot be found in the menu". The latter could be caused by the Operator Search menu changes in Blender 2.90.
7th May 2021 - 12:19
@Jay.w.overstreet Be sure to enable Developer Extras in the preferences, otherwise your operator won't show up in the F3 menu.
3rd April 2020 - 17:10
Very clear, very informative!
Thanks a lot Sybren!
7th April 2020 - 01:38
Nice tutorial. I have a question: I want to add Suzzannes along the Z axis as well.
I came up with the following code:
description="Number of Suzannes in the Z-direction",
def execute(self, context):
for idx in range(self.count_x * self.count_y * self.count_z):
x = idx % self.count_x
y = idx // self.count_x
z = idx // self.count_x
location=(x, y, z)
This line is not producing the correct output:
z = idx // self.count_x
I will continue to experiment on my own, but I wanted to know what operation I need to use here.
Thanks again Sybren for this tutorial!
7th April 2020 - 10:44
*@Gregory L. Hatcher* when you add another dimension the math becomes a bit tricker indeed. What is probably easier is to have three nested for-loops, each counting in the X, Y, and Z direction. Something like this:
for x in range(self.count_x):
for y in range(self.count_y):
for z in range(self.count_z):
bpy.ops.mesh.primitive_monkey_add(size=self.size, location=(x, y, z))
(except that in comments the indentation isn't maintained -- indent each for another step like always)
7th April 2020 - 18:09
*@Sybren A. Stüvel* Thanks! Working as expected now. However, I did discover a few interesting patterns experimenting with different combinations of the // and % operators. :)
13th September 2020 - 15:03
*@Gregory L. Hatcher* I added a z-axis to my function too. Seems to work just by using modulo with each of the respective counts. The floor division operator // is not necessary.
x = idx % self.count_x
y = idx % self.count_y
z = idx % self.count_z
EDIT: Okay it's not that simple, this seems to work with distinct values though
EDIT 2: To make it work for non-distinct values too is actually more similar to the original 2D solution. Use an additional modulo with the next dimension in line (resetting y back to zero in time for additional layers) then for the new dimension floor divide by x times y (as that would make up an entire 2D layer of monkies)
x = idx % self.count_x
y = (idx // self.count_x) % self.count_y
z = idx // (self.count_x * self.count_y)
11th January 2021 - 15:13
16th April 2021 - 00:11
Finding this whole series incredibly helpful. @Sybren A. Stüvel, you are a gifted instructor.
I really appreciate how you referred back to the earlier video in this one to help solidify our understanding without introducing too many new chunks of code at once.
7th May 2021 - 12:20
@Jim Conrad Thanks!
5th November 2022 - 10:43
Great Tutorial! I'm new to programing language trying to understand how everything works. As you said there are many ingredients in the operator script, the Identifier, the label, the executer, registration, etc. And the main idea of creating an operator through scripting is to create a class include all ingredients.But it’s very difficult when I try to do it myself, made many mistakes. I find out that the def registration block, the def unregistration block and the if idiom has no indent as the class(the script won’t work with them indented). Does it mean that they are not parts of the class? and only the identifier, label, description, executor, the invoke, and the modal should be included inside the class? If that's true, then the script only have (primarily) 2 parts, the class(indicating what this operator does) and the other parts(indicating what and how blender should do with this class above), so when we click run button, the only code being executed is resister(),and only when we click the operator button in UI(/ hit enter in the blender console) would the class block actually be run? And if there is anything wrong inside the class block, we won’t able to fin out until then?
7th November 2022 - 11:58
@原苗苗 Just got the answer from the episode 9.Thanks again.
8th May 2020 - 11:16
I have the blender 2.82 and the operator monkey_grid doesnt appears in f3 and console menu.
I need to save the script in a special place?
14th May 2020 - 19:57
*@emi.15.xion* You need to install it as an add-on. Then Blender saves it in a special place. See Blender's Directory Layout for more info.
4th June 2020 - 14:19
*@Sybren A. Stüvel* THanks!!!!! IT works!
25th May 2020 - 16:21
Thanks for this tuto. Could you provide more? I am especially interested in modal operators. Sometimes modal methods are combined with execute, others only invoke. For reasons I don't understand every tuto I found is about creating menus and buttons, but basic tools (e.g. transform ) running modal for good reason. I feel quite lost about this topic and I am surely not the only one.
11th January 2021 - 14:00
@kontakt5 Modal operators are handled in chapter 15. Maybe at some point I'll extend the series, but for now this is it.
12th January 2022 - 23:56
On blender 3.0, i am having difficulty getting the operator to register. It gives me a console error telling me that the name is incorrect.
I have a simple code like this
bl_idname = "mesh.pewTest"
bl_label = "pew testing"
12th January 2022 - 23:58
@Raul Aparicio Here is error i get,
raceback (most recent call last):
File "\operatorTest.py", line 18, in
File "\operatorTest.py", line 13, in register
NameError: name 'MESH_ODN_Connect' is not defined
Error: Python script failed, check the message in the system console
13th January 2022 - 00:40
@Raul Aparicio i figured out my issue. Apparantly there are very strict naming convetions when using the "MESH_OT_" deal, so having "MESH_OT_pewTest" spit out errors. Chaning it to "MESH_OT_Pewtest" worked
6th February 2022 - 11:30
@Raul Aparicio It's not that strict; the problem is that your register function doesn't seem to even mention MESH_OT_pewTest.
This comment system isn't the best for getting help with chunks of code. I'd suggest the Python channel on Blender Chat instead.