Tuesday, March 2, 2010
2.50 Alpha 1 Python Part 2
In Part 1 of this series on Blender 2.50 Python, we explored the new Blender 2.50 Python User Interface. In Part 2, we will look at the new user interface, consisting of windows and panels. You are already familiar with windows -- things like the 3D window, the Outline Window, and the UV / Image Editor Window. These still behave as 2.4x type windows, which you can resize, split, join, and so on.
However, the way windows are built is completely different. In Blender 2.5, windows are assembled in units called Panels. You program each panel as a Python class. A window is a group of panels, with each panel in the window registered to it. In this tutorial, we will explore how Blender 2.5 windows are put together by both looking at the scripts that build the windows in the user interface, and actually changing these windows. Then we will create a panel based on Blender's panel template script, and register it to a window, adding our own panel to a Blender window. In the process, we will see where the python scripts for the windows shipped with Blender are kept and examine how the user interface is created. The goal is to show you how to find the code for the windows, as a starting point for you to change the Python code to add panels to existing windows. The way of building the User Interface has changed so much in 2.50 that just about all Blender Python 2.4x scripts that use windows need to be rewritten, basically from the ground up.
This tutorial is based on the Blender 2.5 Tour 9, Python tutorial, by Michael Fox (mfoxdogg), at: .
So start up Blender 2.5 Alpha 1. The 3D window has a default cube. We won't be doing anything with any Blender objects in this tutorial. We'll only be looking at the user interface scripts. First off, where are they? To find out, switch the 3D window to a Text window by going to the window type buttons menu. The text icon is the same as in Blender 2.4x. From the Text menu, select Open. Bundled into the distribution files is a .blender folder. It may be hidden on your computer, so enable unhiding folders in your operating system, if you don't see that folder. The Blender Python scripts are in the Scripts folder. By the way, there are other Python scripts in the Python/lib folder. You can look at these, which are part of the Python 3.1 distribution, to learn more about Python itself. Today, we're going to look at the Scripts folder.
The Scripts folder itself contains a number of folders: extensions, IO, modules, op, presets, templates, and ui. We're going to start by going to the ui folder, which contains the scripts for the windows in Blender's user interface. The script names start with either "properties_" or "space_". The ones starting with "properties_" are the scripts for the various properties windows. The scripts starting with "space_" are scripts for Blender's windows, such as console, dopesheet, and 3D. Space_view3d.py, for example, is the script for the 3D window.
We're going to start with the script for the Material window, properties_material.py. In the window on the far right, which you may need to expand a bit, click on the big spherical icon. This is the Material window, which is the window produced by this script. The window is divided into sections, which are coded as Property panels. Hide the details of each panel, so that only the headers -- things like Preview, Diffuse, Specular and so on -- show.
Corresponding to each of these panels is a Python class of starting with the words MATERIAL_PT. In the code, the panels are not coded in the order that you see them. In fact, there are panels that you don't see. The panel for the Diffuse settings is labeled "Diffuse", and the code to build the user interface elements, such as the list of shaders, is in the class called MATERIAL_PT_diffuse, specifically in the Draw function, which is required for any panel, some of the code of which is highlighted in pink. There's a class called MATERIAL_PT_specular for the specular panel, with its Draw function, a class called MATERIAL_PT_shading for the Shading panel, and so on.
All the way at the bottom is a list of the panel classes in this window, which are highlighted. This is the order that the panels will display in, although not all of them may display. These classes are registered when the register function, highlighted here, is called. Note that the Physics panel is not displayed. That's because Physics is not appropriate to the Blender Render material window. However, if we switch to Blender Game, where Physics is relevant, the panel displays. In the code for the Physics panel, we see that the panel only should display for the Blender Game engine.
One last thing. The material window class has the following properties:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "material"
Remember this when we build our panel, to add to the Material window. To build a panel, Blender has a template script called panel_simple.py, in the Templates folder. This script, by default, adds a "Hello World" panel, which displays the active object name, to the Object panel. Since we want to add this panel to the material window, we change bl_context to "material". The draw function actually draws the layout on the panel. The row() function creates a row. Three rows are created, one of which displays "Hello World" with an icon. The second row displays the name of the active object. The third row is an input area where we can change the name of the cube. Finally, this new class is registered.
If we press the Run Script button, the script runs. Look at the Material window. The Hello World panel was added at the bottom. Change the name of the cube to MyCube. Look in the outliner. The name of the object has changed.
Of course, there's a lot more, such as the details of how panels are drawn. We'll leave that for another tutorial. For now, I hope you have a better idea of how the new 2.5 interface works and how the scripts are organized. If you liked this tutorial, please hit the Subscribe button on Youtube, and discuss this video at forum.irakrakow.com. Happy Blendering!