Blender Studio
  • Films
  • Training
  • Characters
  • Pipeline
  • Blog
  • Sign in
  • Join
  • BLENDER.ORG

    • Download

      Get the latest Blender, older versions, or experimental builds.

    • What's New

      Stay up-to-date with the new features in the latest Blender releases.

    LEARNING & RESOURCES

    • Blender Studio

      Access production assets and knowledge from the open movies.

    • Manual

      Documentation on the usage and features in Blender.

    DEVELOPMENT

    • Developers Blog

      Latest development updates, by Blender developers.

    • Documentation

      Guidelines, release notes and development docs.

    • Benchmark

      A platform to collect and share results of the Blender Benchmark.

    • Blender Conference

      The yearly event that brings the community together.

    DONATE

    • Development Fund

      Support core development with a monthly contribution.

    • One-time Donations

      Perform a single donation with more payment options available.

Films
Training
Blog
Pipeline and Tools
Characters
Search
Login
Join

Course

Scripting for Artists
feed Course Overview
feed Blender Versions
Videos keyboard_arrow_down
  1. 01

    Introduction & copy-pasting

    Free
  2. 02

    Names & Objects

  3. 03

    Stuff on Lists

  4. 04

    Data Types

  5. 05

    Collections: Mass-Rename of Objects

  6. 06

    Blender Collections

    Free
  7. 07

    For vs. While

    Free
  8. 08

    Your Own Operator

    Free
  9. 09

    From Script to Add-on

    Free
  10. 10

    User Interfaces

    Free
  11. 11

    Custom Properties

    Free
  12. 12

    Asset Linking

    Free
  13. 13

    Roast my Add-on

    Free
  14. 14

    The Roast of Nature Clicker

    Free
  15. 15

    Modal Operators

    Free
  16. 16

    Readability & Understandability

Tech keyboard_arrow_down
  1. 01

    Updating F-Curves

  2. 02

    Render 10,000 OBJ files

  3. 03

    Mass-Rename Bones & Vertex Groups

  4. 04

    Rendering from 'all' angles

Course

Scripting for Artists
feed Blender Versions
Videos keyboard_arrow_down
  1. 01

    Introduction & copy-pasting

    Free
  2. 02

    Names & Objects

  3. 03

    Stuff on Lists

  4. 04

    Data Types

  5. 05

    Collections: Mass-Rename of Objects

  6. 06

    Blender Collections

    Free
  7. 07

    For vs. While

    Free
  8. 08

    Your Own Operator

    Free
  9. 09

    From Script to Add-on

    Free
  10. 10

    User Interfaces

    Free
  11. 11

    Custom Properties

    Free
  12. 12

    Asset Linking

    Free
  13. 13

    Roast my Add-on

    Free
  14. 14

    The Roast of Nature Clicker

    Free
  15. 15

    Modal Operators

    Free
  16. 16

    Readability & Understandability

Tech keyboard_arrow_down
  1. 01

    Updating F-Curves

  2. 02

    Render 10,000 OBJ files

  3. 03

    Mass-Rename Bones & Vertex Groups

  4. 04

    Rendering from 'all' angles

Videos

Your Own Operator

April 2nd, 2020

info License: CC-BY Free
Download (94.4 MB)
Download English Subtitles
Report Problem
Sybren A. Stüvel
Sybren A. Stüvel Publisher

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.

  • Ingredients of an operator: 00:50
  • Creating your own operator: 03:15
  • Passing parameters to the operator: 08:17
  • An explanation of classes in Python: 15:57
  • Using the context: 17:10
  • Limiting when the operator can be used: 17:57

Join to comment publicly.

31 comments

Tchelet Levi
Tchelet Levi May 16th, 2020

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 :)

Jay Overstreet
Jay Overstreet Nov. 29th, 2020

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.

Jay Overstreet
Jay Overstreet Nov. 29th, 2020

@Sybren A. Stüvel

Show more replies
George Castro
George Castro Dec. 4th, 2020

@Jay.w.overstreet i got this from the youtube comments and it worked: Edit>Preferences>Interface tick Developers Extras

Jay Overstreet
Jay Overstreet Dec. 30th, 2020

@George Castro Thanks! I will give it a try.

Guy Wilkinson
Guy Wilkinson June 5th, 2023

@George Castro  thank you so much for this!

Marlon Boettger
Marlon Boettger Dec. 7th, 2020

@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.

Sybren A. Stüvel
Sybren A. Stüvel Jan. 11th, 2021

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.

Sybren A. Stüvel
Sybren A. Stüvel May 7th, 2021

@Jay.w.overstreet Be sure to enable Developer Extras in the preferences, otherwise your operator won't show up in the F3 menu.

Petr Kutek
Petr Kutek July 19th, 2023

@Jay Overstreet Hello, I have the same problem and I can't figure out what I'm doing wrong. The operator can be launched in the Python console window, but I don't see it in the F3 menu. Have you found any solution?

Guillaume Thelissen
Guillaume Thelissen April 3rd, 2020

Very clear, very informative! Thanks a lot Sybren!

Gregory L. Hatcher
Gregory L. Hatcher April 7th, 2020

Nice tutorial. I have a question: I want to add Suzzannes along the Z axis as well.

I came up with the following code:

count_z: bpy.props.IntProperty( name="Z", description="Number of Suzannes in the Z-direction", default=3, min=1, soft_max=10 )

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 bpy.ops.mesh.primitive_monkey_add( size=0.2, 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!

Sybren A. Stüvel
Sybren A. Stüvel April 7th, 2020

*@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)

Gregory L. Hatcher
Gregory L. Hatcher April 7th, 2020

*@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. :)

Show more replies
felixpitau
felixpitau Sept. 13th, 2020

*@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)
gines capote
gines capote Jan. 11th, 2021

Thanx :)

Jim Conrad
Jim Conrad April 16th, 2021

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.

Sybren A. Stüvel
Sybren A. Stüvel May 7th, 2021

@Jim Conrad Thanks!

原苗苗
原苗苗 Nov. 5th, 2022

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?

原苗苗
原苗苗 Nov. 7th, 2022

@原苗苗 Just got the answer from the episode 9.Thanks again.

Nathan Vasil
Nathan Vasil March 18th, 2023

I'm confused by the """The Tooltip""" thing.  I though triple quotes indicated a comment in Python?  But it seems that this comment is being integrated into the actual class as seen by Blender.  Is there some parser that sits between the text editor and Python that changes what Python sees?

Sybren A. Stüvel
Sybren A. Stüvel April 16th, 2023

@Nathan Vasil They are not comments, they are regular strings. They are used for documentation, and get picked up by Python. Try print(your_function.__doc__) in your own code, you should see the function's docstring.

emi.15.xion
emi.15.xion May 8th, 2020

HI! 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?

Sybren A. Stüvel
Sybren A. Stüvel May 14th, 2020

*@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.

emi.15.xion
emi.15.xion June 4th, 2020

*@Sybren A. Stüvel* THanks!!!!! IT works!

kontakt-2
kontakt-2 May 25th, 2020

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.

Sybren A. Stüvel
Sybren A. Stüvel Jan. 11th, 2021

@kontakt5 Modal operators are handled in chapter 15. Maybe at some point I'll extend the series, but for now this is it.

Raul Aparicio
Raul Aparicio Jan. 12th, 2022

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

import bpy class MESH_OT_pewTest(bpy.types.Operator):     """Do Something"""     bl_idname = "mesh.pewTest"     bl_label = "pew testing"          def execute(self,context):         print("pew")                  return{'FINISHED'}

def register():     bpy.utils.register_class(MESH_ODN_Connect) def unregister():     bpy.utils.unregister_class(MESH_ODN_Connect)

if name=='main':     register()

Raul Aparicio
Raul Aparicio Jan. 12th, 2022

@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

Raul Aparicio
Raul Aparicio Jan. 13th, 2022

@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

Sybren A. Stüvel
Sybren A. Stüvel Feb. 6th, 2022

@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.

  • Films
  • Training
  • Blog
Pipeline and Tools
  • Cloud Rig
  • Blender Kitsu
  • Contact Sheet Add-on
  • Blender Purge
  • Blender Cloud Services
Characters
  • Cat
  • Dog
  • Chicken & Sets
  • Einar
Studio
  • Terms & Conditions
  • Privacy Policy
  • Contact
  • Remixing Music
  • blender.org

Blender Studio

The creators who share.

Facebook Logo Twitter Logo YouTube Logo
Loading...