Scripting examples for 2.5 - update: Mar 26th 2010

This post has been updated for Blender 2.5 build 26234

Some time ago I downloaded a development build of Blender 2.5 for the first time. I wanted to see for myself if it was already feasible to start writing scripts for it.
Since I didn’t find any examples of where to begin, I’m documenting my progress in this thread. Hopefully it’s of use for other people. You’re of course welcome to share your own examples. Together we can make the transition to the new api much faster.

Table of contents

Scripts (checked with build 26234)

  1. Hello world - a first test
  2. Ping pong - operators and pushbuttons
  3. Monkify - tools panel, poll() and predefined operators
  4. Armature - script without a gui, bones, transform() and angles
  5. Icons - custom groups for operators
  6. Dropdown - dropdown boxes and retrieving materials
  7. Subclassing RNA - add custom properties and functions to types (by ideasman42)
  8. Keyframes - inserting a keyframe (by taniwha)
  9. CrystalSpace - inheriting and unsetting properties (by sueastside)
  10. Export - access and export a custom property (by Borgleader)
  11. Measure - full script, context dependencies (by pontiac)
  12. Twitter - full script, connecting to the web (by deflinto)
  13. Gems - add mesh, integration in add-menu, eternal editable (by dreampainter)
  14. Files - using the file select window (by Darknet)
  15. Edge intersection - addon-registration, mathutils module, and more (by zeffii)

General info (checked with build 26234)

  1. Abbreviations - class types and layout items
  2. Icons - overview of all icons and their names (script 5)
  3. Script window - information on creating a custom script window
  4. Columns - information on creating a multiple column layout
  5. Properties, ID-Properties and their differences - lot of documentation

Outdated examples (please update)

  1. Gears - menu items, properties and mesh editing (by varkenvarken)
  2. Custom mesh - dynamic parameters, adding to add_mesh menu (by FourMadMen)
  3. Keymap - adding functions to the keymap (by vidar_nelson)
  4. Popup - creating a simple popup menu (by Loolarge)

Script example 1

Here’s my first script. I’m using the api documentation found here. One of the more interesting pages, to get started on the user interface, is the Layout page.

class ObjectButtonsPanel(bpy.types.Panel):
    bl_space_type = "PROPERTIES"
    bl_region_type = "WINDOW"
    bl_context = "object"

class OBJECT_PT_hello(ObjectButtonsPanel):
    bl_label = "My new panel"
    
    def draw(self, context):
        layout = self.layout
        
        ob = context.object
        type = ob.type.capitalize()
        
        row = layout.row()
        row.label(text="Hello world!", icon='WORLD_DATA')
        col = layout.column()
        row = col.row()
        row.label(text="The currently selected object is: "+ob.name)
        row = col.row()
        if type == 'Mesh':
            row.label(text="It is a mesh containing "+str(len(ob.data.verts))+" vertices.")
        else:
            row.label(text="it is a "+type+".")
        row = layout.row()
        row.alignment = 'RIGHT'
        row.label(text="The end")

bpy.types.register(OBJECT_PT_hello)

Just copy/paste it into the text editor and run it with alt+P. Then go to the “Properties” window (used to be the buttons-window in 2.4x) and select the object panel. At the very bottom of it (just collapse the Transform, Relations, etc. panels) you’ll find our very own new panel. It’ll update realtime, based on what object is selected in the 3d-view.

And here’s a screenshot of the result.

http://sites.google.com/site/bartiuscrouch/images/25_01.png

If you got any questions about the code: just ask! There are a lot of new things and not everything might be clear.

Disclaimer: I don’t know if I’m doing things the correct way. Do not experiment in blend-files which contain important work.

go into 2.5 folder find io folder

there are several examples of scripts there

i 'm beginning to look at this too to learn more

but thanks for helping learning this new way of doing things in 2.5

tht should be very interesting cause the new opeators can reproduce precisely what you do in blender i think

so that’s another lvel of flexibility we did not have before !

erroer on script

now i tried to save this example and run it from the version i ahve and i got so many error

what is the version number your are using from graphical.org ?
may it will work with a new version and is it for vista 32 bits ?

i got about a dozen questions general about new 2.5
should i ask it here or open a new thread for theses?
thanks

The two scripts in the io folder are useful to get to know some basics, but don’t cover everything. I’m for example still looking for how to add a button that when pressed, will execute a function. It seems you have to define a custom operator for that, but I haven’t found yet how to do that.

About what I’m using: Windows XP, 32 bit. SVN revision 22647 (the most recent build I could find, there is a link to it in my previous post). Please let me know if you still can’t get it to work.
I think it’s best if we keep this thread for script examples and discussion on these given samples (though everybody is free, and actually encouraged, to post their own examples). General questions on 2.5 can probably better be posted in another thread (isn’t there a big one in News & Discussion?).

tried to test the XP version seems to work ok on my vista
seems that this version does not have suzanne
i’ll try to import from 2.49 a suzanne object

also tried to run your little sample script and get nothing at all
no errors nothing ?
i can see the script in text editor

any suggestions?

now sorry it was not io folder with only 2 scripts

it’s the other one UI folder
there are 10 or 20 scripts there with examples for GUI

got to take the time to look at theses to understand more how to for GUI
should be very interesting !

Thanks

i was able to see the panel with your script!

wow but it is so small miniature panel at the bottom of the button window

is there a way to make it a lot bigger may be even full screen

with some color ect…

would it be worth to make a tut on PDF to show that an other things later on ?

like it looks like the first part tell blender to open this new panel at bottom of properties window
which is very small i guess

class ObjectButtonsPanel(bpy.types.Panel):
space_type = “PROPERTIES”
region_type = “WINDOW”
context = “object”

is there away to open up sort of a pop new window where it’s bigger and can put a lot more stuff like buttons
menu ect…?

Thanks

This post has been updated for Blender 2.5 build 31315

Script example 2

import bpy
# version 1.3.0
# tested on 31315


class OBJECT_PT_pingpong(bpy.types.Panel):
    bl_space_type = "PROPERTIES"
    bl_region_type = "WINDOW"
    bl_context = "object"
    bl_label = "Ping Pong"
    
    display = 0
    
    def draw_header(self, context):
        layout = self.layout
        layout.label(text="", icon="PHYSICS")
    
    def draw(self, context):
        layout = self.layout
        row = layout.row()
        split = row.split(percentage=0.5)
        colL = split.column()
        colR = split.column()
        
        if self.display == 0:
            colL.operator("pipo", text="Ping")
        else:
            colR.operator("pipo", text="Pong")


class OBJECT_OT_pingpong(bpy.types.Operator):
    bl_label = "PingPong operator"
    bl_idname = "pipo"
    bl_description = "Move the ball"

    def invoke(self, context, event):
        import bpy
        
        self.report("INFO", "Moving the ball")
        bpy.types.OBJECT_PT_pingpong.display = 1 - bpy.types.OBJECT_PT_pingpong.display
        return{"FINISHED"}

http://sites.google.com/site/bartiuscrouch/images/25_02.png

You’ll find the new panel at the bottom of the object properties.
Whenever you press the button, another button shows up and the text “Moving the ball” is displayed in Blender’s infobar (usually top right of your screen).

Analysis

The OBJECT_PT_pingpong class is to draw the gui.

‘bl_space_type’ is the kind of space it shows upis. “PROPERTIES” is the new name for what the buttons window was in Blender 2.4x, so that’s where you’ll find it.
‘bl_region_type’ is the kind of region it shows up in.
‘bl_context’ is when the panel will show (so you will need to have an object selected, for the panel to show up).
‘bl_label’ is the text displayed in the header.

‘display’ is a custom variable which we use te determine which button needs to be displayed.

‘draw_header’ is used to draw extra things in the header. In our case an icon. You can also use it to draw a checkbox that enables or disables all the settings in the panel.
‘draw’ defines the content of the panel. There is a single row, which is split in half. Each half contains a column. Aditionally we draw a button in one of these columns. The ‘display’ variable determines which one we draw. 0 = the left one, 1 = the right one. These buttons refer to an operator called ‘pipo’, which is the idname of the next class.

The OBJECT_OT_pingpong class defines our custom operator.

‘bl_label’ is the default text that’s used by buttons in the user-interface (which we overwrite by for instance: text=“Ping” )
‘bl_idname’ is what we use to refer to this operator.
‘bl_description’ is the text that shows up when you hover over a button that calls this operator (a bit like a tooltip).
‘invoke’ is called whenever a button calls the class.
‘report’ displays a message in the main header of Blender. After this line we also set the ‘display’ variable to the other value (0 if it’s 1 right now, and vice versa).

Please feel free to discuss this example, or add your own examples. I’ll add a table of contents to the first post with direct links to the posts containing the examples.

hi Crouch,
great work again.

what I am specifically interested in for 2.5 is Materials.
I think, it would be possible to write a Materials Library in Python.
After all it’s just calling functions.
once the first few were done, it would be easy to add more. :wink:

It has long been a problem, especially with materials, that presets are saved in the .blend file.
This is no good if you need, or as a new user want, extensive library’s.
So I think Python provides a great solution to this.

So, what i would envision is a panel in the Materials menu.
The panel could have several new options.
Car Paint, Metal, Glass, Wood, Stone, Skin, Ocean, whatever…
This could then be extended to include Particle presets such as,
Grass, Hair, Smoke, Water & Sky.
This would save previous overhead problems & well,
be one great intro to Blender & Python 3.1. :slight_smile:

So that’s the short version!

Crouch, it’s inspiring to see what you do.
Mindrones & I would like to talk to you on #blenderwiki if you get a chance.

Thanks.

@ crouch

PDF tut - doc

you give some explanations which is great for people to understand the possibilities

but are you going to prepare a PDF tut intro to 2/5 scripting

if not i think i’m going to begin to prepare something as we go along

but not easy cause the API does not have all the Doc details

but at least i can prepare pictures and the sequence of events to get some results

with some basic examples to show the how to in new API

that could be save on the wiki as intro to scripting for futur reference to noobies!

let me know what you think

i’ll continue to study further the new ways of 2.5!

Thanks

when you make a simple new panel in blender window

1 -
is there any kind of col or row numbers to specify where things are going
like we had for buttons for instance in 2.49

i can see this

col = layout.column()
row = col.row()

but here is no column or row number for theses
just does it say to change line or col and how many are there ?

2 - UI
not certain but is there going to be an independant UI like we had before
where you can put several buttons menu opengl graphic ect…
but for that you need a much larger window or UI to place things around
and hopefully not inside blender windows

confusing new panel

the thing is that when you add a panel in blender’s window
right not it’s confusing cause you cannot tell if this a blender’s panel or a customize added new panel

when i did it at first i ddi not see the new panel it was almost invisible in blender
but then i saw it at the bottom - very strange to see this there and no easy way to tell if this a customized panel or not !

Thanks

Thanks for all the nice words. So far this thread is only some basic documentation on my own experiments with 2.5
I might write a proper introduction tutorial to Blender 2.5 python scripting later on, but first I’ll have to understand things myself ;).

Meta: I’ll have a look if I can find out a bit more about materials. I’ll try to catch you and Mindrones on irc (is mindrones in the same timezone as you are?)

To answer Ricky’s questions:

  1. I think of the new layout as some kind of div-system (as in html/css). You’ve got a space to which you can add boxes (rows and columns). You can add extra boxes to them or split them (the percentage parameter determines how). You add the items (buttons, texts, etc.) to these boxes. Rows are as wide as the panel, while the panel will be as high as needed to place all the items.
    It’s a bit hard to describe in words. I’ll post again later and try to do a mock-up image with some better explanation.

  2. If I recall correctly, the scripts window has been completely removed from Blender 2.5 The new way to display scripts (if they need a gui), is to integrate them with existing panels. The impossibility to see a difference between hardcoded panels and python content is actually an advantage in my opinion.
    So far I’ve written two examples that show up in a slightly obscure location, but that’s not the only way. You can have them show up in other places as well. I’ll see if I can do an example on that later (will still have to research how to do it ;))

well i’m trying to learn as i go along
and i guess that other peoples are interested too
cause doc right now is rare

1 -news for -mathutil module

now i learn something yesterday about mathutil

it seems that this module and geomertry are again in 2.5
but the only problem with the new mathutil module is that all angle are in radians instead of degrees
so i you have old scripts with angles in degrees and want to use this in 2.5 you need to change the degrees to radians

2 - panels confusion
is it nice to see that we can add panel inside blender now
it will be usefull for special custom made functions and that’s good

but i found it confusing in blender’s panel window
if there was a better way to differentiate betwen the nativ panels and the new added panels like a red perimeter for instance - at least you would at a glance see that it’s a custom panel not something that belong to blender

3 other UI
well if you need to add a lot of buttons and where do you place theses
i hope we gone get an independant ui panel of whatever size we need
where we can organise things as we wish!

cause as is it right now there are no space unless you icrease manually the size of the window which is not very practical - i would prefer an independant window

Thanks for your involvment

Hey,
thanks for the sample scripts. I just opened 2.5 for the first time to try and convert over some scripting I’ve been doing in 2.49 and was slightly shocked to learn that not even my include modules lines were valid any longer:) Your scripts will be very helpful to re-examine how things work. I looked for the io folder that ricky mentioned and I didn’t see it on my version? (same build as you listed above?) I’ve got a plugins folder and then 3 folders inside that–none containing scripts. I need as many resources as I can get at this point:)

Thanks!

Ryan

EDIT: Apparently the folder is hidden on the mac version. brilliant!

check the UI folders

it has several script as example

and it show how to add some object in 2.5

This post has been updated for Blender 2.5 build 26750

mp3man4: inside blender’s main folder there is a hidden folder called “.blender” Inside that folder you’ll find the io and ui folders.

Script example 3

We’re going to create a tool that changes an object into a monkey (obviously you don’t want to run this on important files). And this time we’ll place the user interface at a logical location.

class OBJECT_OT_monkify(bpy.types.Operator):
    bl_idname = "OBJECT_OT_monkify"
    bl_label = "Monkify"
    bl_description = "Replace the current mesh with a monkey"
    
    def poll(self, context):
        if not context.active_object:
            return
        return context.active_object.type == 'MESH'
    
    def invoke(self, context, event):
        ob = context.active_object
        me = ob.data
        if len(me.verts) > 0:
            me.verts[0].selected = True
        if len(me.verts) > 1:
            me.verts[1].selected = False
        me.update()
        bpy.ops.object.editmode_toggle()
        bpy.ops.mesh.select_all(action='TOGGLE')
        bpy.ops.mesh.select_all(action='TOGGLE')
        bpy.ops.mesh.delete(type='VERT')
        loc = (ob.location[0], ob.location[1], ob.location[2])
        bpy.ops.mesh.primitive_monkey_add(location=loc)
        bpy.ops.object.editmode_toggle()
        return{'FINISHED'}
 
bpy.types.register(OBJECT_OT_monkify)

menu_func = (lambda self, context: self.layout.operator('OBJECT_OT_monkify'))
bpy.types.VIEW3D_PT_tools_objectmode.prepend(menu_func)

http://sites.google.com/site/bartiuscrouch/images/25_09.png

First run the script and then the tool will show up in the object tools (press T in the 3d-view).

Analysis
I’m going to highlight new things only. The other parts are already described in previous posts.

The OBJECT_OT_monkify class is a custom operator
bl_description will show up as the tooltip of the pushbutton in the gui.
poll() is a function that determines if the operator can be used. If it returns False, the operator button will be greyed out. I’m testing both if there is an active object and if that object is a mesh.

bpy.ops.object.editmode_toggle() enters editmode (we can be certain that originally we are in objectmode, since we’ll register the operator in the 3d-view object mode tools panel. You can also use context.mode to check what mode you are in).
bpy.ops.mesh.delete(type=‘VERT’) deletes all selected verts of the active mesh.
menu_func is a custom function that references the new operator class and the last line prepends that to the toolbar, making the button show up.

This post has been updated for Blender 2.5 alpha 0

Just a quick post on some things you’ll often come across when you browse the scripts that are already included with blender (the ones in the ui and io folders).

A lot of the classes are named like INFO_MT_help() and OBJECT_PT_transform(). The first part (INFO and OBJECT) are pretty clear, they define the window category. The last part is simply the function name. But what about the middle parts? Here is what I came across so far:

OT: operater type
MT: menu type
HT: header type
PT: panel type

Please note that I’m not certain if those are the correct abbreviations, but it does give a good general explanation.

— The text below has become obsolete, as of Blender 2.5 alpha 0

When looking through PT (panel) classes, you’ll find a lot of different item#() functions. Here’s a list:

itemL: label (just plain text)
itemM: menu (menu button)
itemO: operator (push button)
itemR: rna property (displays a value)
itemS: spacer (empty space)

You can also find them in the api. Again: I’m not certain if this is really what the abbreviations mean, but it gives some explanation and makes it easier to remember.

when you say RNA

first what is the meaning of RNA ?
and also API means what ?

and in the API there is a module RNA with some 200 functions inside

are you saying that all theses functions are only use to show values like print equivalent somewhere in blender ?

and the last list of items for things inside class
are theses fields variables or methods inside the class itself?

i think i’m preraring some sort of PDF tut on basic things for new 2.5 scripting
that’s will become handy later on

also this T- in 3D viewport
VIEW3D_PT_tools_objectmode class defines the user interface panel.

is this an equivalent of the old GUI we had in 2.49 or an equivalent?
meaning that this panel which os more like a window can be use to put buttons and graphics?

Thanks

You should see the content of the /io folder, too.

This is really cool thread. Thank you very much Crouch for this :slight_smile:

Ricky: When I say api (application programming interface), I should actually say the api docs. I was referring to the docs.
The rna module in the docs is a mix of a lot of things. There are a lot of operators (like MESH_OT_select_inverse). But there are also references to properties (like the startframe). ItemR() displays properties in the interface and lets you change them. An example is the startframe I mentioned. In the ui code it is:

col.itemR(scene, "start_frame", text="Start")

In the user interface it shows up as a slider, with which you can set the property (it’s a rna property of the scene).
The tools panel (which shows up when you press T in the 3d-view) is more like a replacement for the old buttons window in 2.4x. But only the operator buttons are shown. It also displays a custom tool shelf where users can put links to often used functions (though I think this is still wip)

jms: the io and ui folder are very useful indeed. I’ve used them both to get started with scripting in 2.5

JiriH: thanks :). Feel free to add examples yourself once you start experimenting.

here are some questions to better understand the meaning of things for the last script

q1 - class
it is necessary to use class?
i mean you can add a predefine mesh outside a class
like

bpy.ops.object.mesh_add(type=‘CUBE’)

So any specific reasons why you are using classes ?
mind you it is good to know that it can be done that way too!

q2- duplicated line
bpy.ops.mesh.select_all_toggle()

this line is shown twice - not usefull i guess

q3 - selected object
context.active_object.type == ‘MESH’:

this command seems to do a selection and an action at the same time !
and the context is define at the beginning as being objectmode
do you kow how to do this outside a class?

and is this line equivalent to the old selected object?

q4 - layout item
what is the meaning of theses 2 lines?
layout.itemL(text=“Change mesh:”)
layout.itemO(“object.monkify”)
only test to be shown may be ?

q5 -function of theses lines
if len(me.verts) > 0:
me.verts[0].selected = True
if len(me.verts) > 1:
me.verts[1].selected = False

What theses lines do ?
i mean it looks like testing if there is more than one vert in the mesh ?

q6 - edit mode
is it necessary to be in edit mode to add the new object?
it looks like your replacing the verts of an existing mesh - may be it’s that

   another way would be to erase the selected object and add a new monkey ?

Thanks