<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <HTML ><HEAD ><TITLE >Python Scripting</TITLE ><META NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+ "><LINK REL="HOME" TITLE="Blender Documentation Volume I - User Guide" HREF="book1.html"><LINK REL="UP" TITLE="Extending Blender" HREF="p10374.html"><LINK REL="PREVIOUS" TITLE="Extending Blender" HREF="p10374.html"><LINK REL="NEXT" TITLE="Python Reference" HREF="x10601.html"></HEAD ><BODY CLASS="chapter" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#840084" ALINK="#0000FF" ><DIV CLASS="NAVHEADER" ><TABLE SUMMARY="Header navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TH COLSPAN="3" ALIGN="center" >Blender Documentation Volume I - User Guide: Last modified April 29 2004 S68</TH ></TR ><TR ><TD WIDTH="10%" ALIGN="left" VALIGN="bottom" ><A HREF="p10374.html" ACCESSKEY="P" ><<< Previous</A ></TD ><TD WIDTH="80%" ALIGN="center" VALIGN="bottom" ></TD ><TD WIDTH="10%" ALIGN="right" VALIGN="bottom" ><A HREF="x10601.html" ACCESSKEY="N" >Next >>></A ></TD ></TR ></TABLE ><HR ALIGN="LEFT" WIDTH="100%"></DIV ><DIV CLASS="chapter" ><H1 ><A NAME="chapter_python_scripting" ></A >Python Scripting</H1 ><P > Blender has a very powerful yet often overlooked feature. It exhibits an internal full fledged Python interpreter. </P ><P > This allows any user to add functionalities by writing a Python script. Python is an interpreted, interactive, object-oriented programming language. It incorporates modules, exceptions, dynamic typing, very high level dynamic data types, and classes. Python combines remarkable power with very clear syntax. It was expressly designed to be usable as an extension language for applications that need a programmable interface, and this is why Blender uses it. </P ><P > Of the two main ways of extending Blender, the other one Being binary plugins, Python scripting is more Powerful, versatile yet easier to comprehend and robust. It is generally preferred to use Python scripting than writing a plugin. </P ><P > Actually Python scripting had somewhat limited functionalities up to Blender 2.25, the last of NaN releases. When Open Sourcing Blender many of the new developers gathered around the Foundations elected to work on it and, together with UI change, Python API is probably the single part of Blender which got the greater development. A full reorganization of what existed was carried out and many new modules added. </P ><P > This evolution is still ongoing and even better integration is expected in forthcoming Blender versions. </P ><P > Blender has a Text Window among its windows types accessible via the <B CLASS="guiicon" > <IMG SRC="PartEX/python/gfx/textButton.png"> </B > button of the Window Type menu or via <B CLASS="keycap" >SHIFT F11</B >. </P ><P > The newly opened Text window is grey and empty, with a very simple toolbar (<A HREF="c10379.html#BSG.PYT.F.S68.001" >Figure 1</A >). From left to right there are the standard Window type selection button and the Window menu. Then the full screen button, followed by a toggle button which shows/hides the line numbers for the text and the regular Menu Button. </P ><DIV CLASS="figure" ><A NAME="BSG.PYT.F.S68.001" ></A ><DIV CLASS="mediaobject" ><P ><IMG SRC="PartEX/python/gfx/textButtons.png"></P ></DIV ><P ><B >Figure 1. Text Toolbar.</B ></P ></DIV ><P > The Menu Button (<B CLASS="guiicon" > <IMG SRC="PartEX/python/gfx/textSelectButton.png"> </B >) allows to select which Text buffer is to be displayed, as well as allowing to create a new buffer or loading a text file. </P ><P > If you choose to load a file the Text Window tempoarily becomes a File Selection Window, whith the usual functions. Once a text buffer is in the Text window, this behaves as a very simple text editor. Typing on the keyboard produces text in the text buffer. As usual pressing, <B CLASS="keycap" >LMB</B > dragging and releasing <B CLASS="keycap" >LMB</B > selects text. The following keyboard commands apply: </P ><P ></P ><UL ><LI ><P ><B CLASS="keycap" >ALT-C</B > or <B CLASS="keycap" >CTRL-C</B > - Copy the marked text into the text clipboard;</P ></LI ><LI ><P ><B CLASS="keycap" >ALT-X</B > or <B CLASS="keycap" >CTRL-X</B > - Cut out the marked text into the text clipboard;</P ></LI ><LI ><P ><B CLASS="keycap" >ALT-V</B > or <B CLASS="keycap" >CTRL-V</B > - Paste the text from the clipboard to the cursor in the Text Window;</P ></LI ><LI ><P ><B CLASS="keycap" >ALT-S</B > - Saves the text as a text file, a File Selection Window appears;</P ></LI ><LI ><P ><B CLASS="keycap" >ALT-O</B > - Loads a text, a File Selection Window appears;</P ></LI ><LI ><P ><B CLASS="keycap" >ALT-F</B > - Pops up the Find toolbox;</P ></LI ><LI ><P ><B CLASS="keycap" >SHIFT-ALT-F</B > or <B CLASS="keycap" >RMB</B > - Pops up the File Menu for the Text Window;</P ></LI ><LI ><P ><B CLASS="keycap" >ALT-J</B > - Pops up a Num Button where you can specify a linenumber the cursor will jump to;</P ></LI ><LI ><P ><B CLASS="keycap" >ALT-P</B > - Executes the text as a Python script;</P ></LI ><LI ><P ><B CLASS="keycap" >ALT-U</B > - Undo;</P ></LI ><LI ><P ><B CLASS="keycap" >ALT-R</B > - Redo;</P ></LI ><LI ><P ><B CLASS="keycap" >CTRL-R</B > - Reopen (reloads) the current buffer;</P ></LI ><LI ><P ><B CLASS="keycap" >ALT-M</B > - Converts the content of the text window into 3D text (max 100 chars);</P ></LI ></UL ><P > Blender's cut/copy/paste clipboard is <I CLASS="emphasis" >separate</I > from Window's clipboard. So normally you <I CLASS="emphasis" >cannot</I > cut/paste/copy out from/into Blender. To access your Windows clipboard use <B CLASS="keycap" >SHIFT-CTRL-C</B > <B CLASS="keycap" >SHIFT-CTRL-V</B > </P ><P > To delete a text buffer just press the 'X' button next to the buffer's name, just as you do for materials, etc. </P ><P > The most notable keystroke is <B CLASS="keycap" >ALT-P</B > which makes the content of the buffer being parsed by the internal Python interpreter built into Blender. </P ><P > The next section will present an example of Python scripting. Before going on it is worth noticing that Blender comes with only the bare Python interpreter built in, and with a few Blender-specific modules, those described in **REF** . </P ><DIV CLASS="tip" ><P ></P ><TABLE CLASS="tip" WIDTH="100%" BORDER="0" ><TR ><TD WIDTH="25" ALIGN="CENTER" VALIGN="TOP" ><IMG SRC="./stylesheet-images/tip.gif" HSPACE="5" ALT="Tip"></TD ><TH ALIGN="LEFT" VALIGN="CENTER" ><B >Other usages for the Text window</B ></TH ></TR ><TR ><TD > </TD ><TD ALIGN="LEFT" VALIGN="TOP" ><P > The text window is handy also when you want to share your .blend files with the community or with your friends. A Text window can be used to write in a README text explaining the contents of your blender file. Much more handy that having it on a separate application. Be sure to keep it visible when saving! </P ><P > If you are sharing the file with the community and you want to share it under some licence you can write the licence in a text window. </P ></TD ></TR ></TABLE ></DIV ><P > to have access to the standard Python modules you need a complete working Python install. You can download this from <A HREF="http://www.python.org" TARGET="_top" >http://www.python.org</A >. Be sure to check on <A HREF="http://www.blender.org" TARGET="_top" >http://www.blender.org</A > which is the <I CLASS="emphasis" >exact</I > Python version which was built into Blender to prevent compatibility issues. </P ><P > Blender must also be made aware of <I CLASS="emphasis" >where</I > this full Python installation is. This is done by defining a <TT CLASS="literal" >PYTHONPATH</TT > environment variable. </P ><DIV CLASS="formalpara" ><P ><B ><B >Setting <TT CLASS="literal" >PYTHONPATH</TT > on Win95,98,Me. </B ></B > Once you have installed Python in, say, <TT CLASS="literal" >C:\PYTHON22</TT > you must open the file <TT CLASS="literal" >C:\AUTOEXEC.BAT</TT > with your favourite text editor, add a line: </P ></DIV ><P > <TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><PRE CLASS="programlisting" > SET PYTHONPATH=C:\PYTHON22;C:\PYTHON22\DLLS;C:\PYTHON22\LIB;C:\PYTHON22\LIB\LIB-TK </PRE ></TD ></TR ></TABLE > </P ><P > and reboot the system. </P ><DIV CLASS="formalpara" ><P ><B ><B >Setting <TT CLASS="literal" >PYTHONPATH</TT > on WinNT,2000,XP. </B ></B > Once you have installed Python in, say, <TT CLASS="literal" >C:\PYTHON22</TT > Go on the "My Computer" Icon on the desktop, <B CLASS="keycap" >RMB</B > and select <TT CLASS="literal" >Properties</TT >. Select the <TT CLASS="literal" >Advanced</TT > tab and press the <TT CLASS="literal" >Environment Variables</TT > button. </P ></DIV ><P > Below the System Variables box, (the second box), hit <TT CLASS="literal" >New</TT >. If you are not an administrator you might be unable to do that. In this case hit <TT CLASS="literal" >New</TT > in the upper box. </P ><P > Now, in the Variable Name box, type PYTHONPATH, in the Variable Value box, type: </P ><P > <TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><PRE CLASS="programlisting" > C:\PYTHON22;C:\PYTHON22\DLLS;C:\PYTHON22\LIB;C:\PYTHON22\LIB\LIB-TK </PRE ></TD ></TR ></TABLE > </P ><P > Hit OK repeatedly to exit from all dialogs. You may or may not have to reboot, depending on the OS. </P ><DIV CLASS="formalpara" ><P ><B ><B >Setting <TT CLASS="literal" >PYTHONPATH</TT > on Linux and other UNIXes. </B ></B > Normally you will have Python already there. if not, install it. You will have to discover where it is. This is easy, just start a Python interactive shell by opening a shell and by typing <TT CLASS="literal" >python</TT > in there. Type the following commands: </P ></DIV ><P > <TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><PRE CLASS="programlisting" > >>> import sys >>> print sys.path </PRE ></TD ></TR ></TABLE > </P ><P > and note down the output, it should look like </P ><P > <TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><PRE CLASS="programlisting" > ['', '/usr/local/lib/python2.2', '/usr/local/lib/python2.2 /plat-linux2', '/usr/local/lib/python2.0/lib-tk', '/usr/lo cal/lib/python2.0/lib-dynload', '/usr/local/lib/python2.0/ site-packages'] </PRE ></TD ></TR ></TABLE > </P ><P > Add this to your favourite <TT CLASS="literal" >rc</TT > file as an environment variable setting. For example, add in your <TT CLASS="literal" >.bashrc</TT > the line </P ><P > <TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><PRE CLASS="programlisting" > export PYTHONPATH=/usr/local/lib/python2.2:/usr/local/lib/ python2.2/plat-linux2:/usr/local/lib/python2.2/lib-tk:/usr /local/lib/python2.2/lib-dynload:/usr/local/lib/python2.0/ site-packages </PRE ></TD ></TR ></TABLE > </P ><P > all on a single line. Open a new login shell, or logoff and login again. </P ><DIV CLASS="section" ><H1 CLASS="section" ><A NAME="python_example" ></A >A working Python example</H1 ><P > Now that you've seen that Blender is extensible via Python scripting and that you've got the basics of script handling and how to run a script, before smashing your brain with the full python API reference let's have a look to a quick working example. </P ><P > We will present a tiny script to produce polygons. This indeed duplicates somewhat the <TT CLASS="literal" ><B CLASS="keycap" >SPACE</B >Add>>Mesh>>Circle</TT > toolbox option, but will create 'filled' polygons, not just the outline. </P ><P > To make the script simple yet complete it will exhibit a Graphical User Interface (GUI) completely written via Blender's API. </P ><DIV CLASS="section" ><H2 CLASS="section" ><A NAME="python_example.1" ></A >Headers, importing modules and globals.</H2 ><P > The first 32 lines of code are reported in <A HREF="c10379.html#BSG.PYT.L.S68.001" >Example 1</A >. </P ><DIV CLASS="example" ><A NAME="BSG.PYT.L.S68.001" ></A ><P ><B >Example 1. Script header</B ></P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><PRE CLASS="programlisting" > 001 ###################################################### 002 # 003 # Demo Script for Blender 2.3 Guide 004 # 005 ###################################################S68 006 # This script generates polygons. It is quite useless 007 # since you can do polygons with ADD->Mesh->Circle 008 # but it is a nice complete script example, and the 009 # polygons are 'filled' 010 ###################################################### 011 012 ###################################################### 013 # Importing modules 014 ###################################################### 015 016 import Blender 017 from Blender import NMesh 018 from Blender.BGL import * 019 from Blender.Draw import * 020 021 import math 022 from math import * 023 024 # Polygon Parameters 025 T_NumberOfSides = Create(3) 026 T_Radius = Create(1.0) 027 028 # Events 029 EVENT_NOEVENT = 1 030 EVENT_DRAW = 2 031 EVENT_EXIT = 3 032 </PRE ></TD ></TR ></TABLE ></DIV ><P > After the necessary comments with the description of what the script does there is (lines 016-022) the importing of Python modules. </P ><P > <TT CLASS="literal" >Blender</TT > is the main Blender Python API module. <TT CLASS="literal" > NMesh</TT > is the module providing access to Blender's meshes, while <TT CLASS="literal" >BGL</TT > and <TT CLASS="literal" >Draw</TT > give access to the OpenGL constants and functions and to Blender's windowing interface, respectively. The <TT CLASS="literal" >math</TT > module is Python's mathematical module, but since both the 'math' and the 'os' modules are built into Blender you don't need a full Python install for this! </P ><P > The polygons are defined via the number of sides they have and their radius. These parameters have values which must be defined by the user via the GUI hence lines (025-026) creates two 'generic button' objects, with their default starting value. </P ><P > Finally, the GUI objects works with, and generates, events. Events identifier are integers left to the coder to define. It is usually a good practice to define mnemonic names for events, as it is done here in lines (029-031). </P ></DIV ><DIV CLASS="section" ><H2 CLASS="section" ><A NAME="python_example.2" ></A >Drawing the GUI.</H2 ><P > The code responsible for drawing the GUI should reside in a <TT CLASS="literal" >draw</TT > function (<A HREF="c10379.html#BSG.PYT.L.S68.002" >Example 2</A >). </P ><DIV CLASS="example" ><A NAME="BSG.PYT.L.S68.002" ></A ><P ><B >Example 2. GUI drawing</B ></P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><PRE CLASS="programlisting" > 033 ###################################################### 034 # GUI drawing 035 ###################################################### 036 def draw(): 037 global T_NumberOfSides 038 global T_Radius 039 global EVENT_NOEVENT,EVENT_DRAW,EVENT_EXIT 040 041 ########## Titles 042 glClear(GL_COLOR_BUFFER_BIT) 043 glRasterPos2d(8, 103) 044 Text("Demo Polygon Script") 045 046 ######### Parameters GUI Buttons 047 glRasterPos2d(8, 83) 048 Text("Parameters:") 049 T_NumberOfSides = Number("No. of sides: ", EVENT_NOEVENT, 10, 55, 210, 18, 050 T_NumberOfSides.val, 3, 20, "Number of sides of out polygon"); 051 T_Radius = Slider("Radius: ", EVENT_NOEVENT, 10, 35, 210, 18, 052 T_Radius.val, 0.001, 20.0, 1, "Radius of the polygon"); 053 054 ######### Draw and Exit Buttons 055 Button("Draw",EVENT_DRAW , 10, 10, 80, 18) 056 Button("Exit",EVENT_EXIT , 140, 10, 80, 18) 057 </PRE ></TD ></TR ></TABLE ></DIV ><P > Lines (037-039) merely grant access to global data. The real interesting stuff starts from lines (042-044). The OpenGL window is initialised, and the current position set to x=8, y=103. The origin of this reference is the lower left corner of the script window. Then the title <TT CLASS="literal" >Demo Polygon Script</TT > is printed. </P ><P > A further string is written (lines 047-048), then the input buttons for the parameters are created. The first (lines 049-050) is a Num Button, exactly alike those in the various Blender Button Windows. For the meaning of all the parameters please refer to the API reference. Basically there is the button label, the event generated by the button, its location (x,y) and its dimensions (width, height), its value, which is a data belonging to the Button object itself, the minimum and maximum allowable values and a text string which will appear as an help while hoovering on the button, as a tooltip. </P ><P > Lines (051-052) defines a Num Button with a slider, with a very similar syntax. Lines (055-056) finally creates a <TT CLASS="literal" >Draw</TT > button which will create the polygon and an <TT CLASS="literal" >Exit</TT > button. </P ></DIV ><DIV CLASS="section" ><H2 CLASS="section" ><A NAME="python_example.3" ></A >Managing Events.</H2 ><P > The GUI is not drawn, and would not work, until a proper event handler is written and registered (<A HREF="c10379.html#BSG.PYT.L.S68.003" >Example 3</A >). </P ><DIV CLASS="example" ><A NAME="BSG.PYT.L.S68.003" ></A ><P ><B >Example 3. Handling events</B ></P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><PRE CLASS="programlisting" > 058 def event(evt, val): 059 if (evt == QKEY and not val): 060 Exit() 061 062 def bevent(evt): 063 global T_NumberOfSides 064 global T_Radius 065 global EVENT_NOEVENT,EVENT_DRAW,EVENT_EXIT 066 067 ######### Manages GUI events 068 if (evt == EVENT_EXIT): 069 Exit() 070 elif (evt== EVENT_DRAW): 071 Polygon(T_NumberOfSides.val, T_Radius.val) 072 Blender.Redraw() 073 074 Register(draw, event, bevent) 075 </PRE ></TD ></TR ></TABLE ></DIV ><P > Lines (058-060) defines the keyboard event handler, here responding to the <B CLASS="keycap" >QKEY</B > with a plain <TT CLASS="literal" >Exit()</TT > call. </P ><P > More interesting are lines (062-072), in charge of managing the GUI events. Every time a GUI button is used this function is called, with the event number defined within the button as a parameter. The core of this function is hence a "select" structure executing different codes accordingly to the event number. </P ><P > As a last call, the <TT CLASS="literal" >Register</TT > function is invoked. This effectively draws the GUI and starts the event capturing cycle. </P ></DIV ><DIV CLASS="section" ><H2 CLASS="section" ><A NAME="python_example.4" ></A >Mesh handling</H2 ><P > Finally, <A HREF="c10379.html#BSG.PYT.L.S68.004" >Example 4</A > shows the main function, the one creating the polygon. It is a rather simple mesh editing, but shows many important points of the Blender's internal data structure </P ><DIV CLASS="example" ><A NAME="BSG.PYT.L.S68.004" ></A ><P ><B >Example 4. Script header</B ></P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><PRE CLASS="programlisting" > 076 ###################################################### 077 # Main Body 078 ###################################################### 079 def Polygon(NumberOfSides,Radius): 080 081 ######### Creates a new mesh 082 poly = NMesh.GetRaw() 083 084 #########Populates it of vertices 085 for i in range(0,NumberOfSides): 086 phi = 3.141592653589 * 2 * i / NumberOfSides 087 x = Radius * cos(phi) 088 y = Radius * sin(phi) 089 z = 0 090 091 v = NMesh.Vert(x,y,z) 092 poly.verts.append(v) 093 094 #########Adds a new vertex to the center 095 v = NMesh.Vert(0.,0.,0.) 096 poly.verts.append(v) 097 098 #########Connects the vertices to form faces 099 for i in range(0,NumberOfSides): 100 f = NMesh.Face() 101 f.v.append(poly.verts[i]) 102 f.v.append(poly.verts[(i+1)%NumberOfSides]) 103 f.v.append(poly.verts[NumberOfSides]) 104 poly.faces.append(f) 105 106 #########Creates a new Object with the new Mesh 107 polyObj = NMesh.PutRaw(poly) 108 109 Blender.Redraw() </PRE ></TD ></TR ></TABLE ></DIV ><P > The first important line here is number (082). Here a new mesh object, <TT CLASS="literal" >poly</TT > is created. The mesh object is constituted of a list of vertices and a list of faces, plus some other interesting stuff. For our purposes the vertices and faces lists are what we need. </P ><P > Of course the newly created mesh is empty. The first cycle (lines 085-092) computes the x,y,z location of the <TT CLASS="literal" >NumberOfSides</TT > vertices needed to define the polygon. Being a flat figure it is z=0 for all. </P ><P > Line (091) call the <TT CLASS="literal" >NMesh</TT > method <TT CLASS="literal" >Vert</TT > to create a new vertex object of co-ordinates (x,y,z). Such an object is then appended (line 096) in the <TT CLASS="literal" >poly</TT > Mesh <TT CLASS="literal" >verts</TT > list. </P ><P > Finally (lines 095-096) a last vertex is added in the centre. </P ><P > Lines (099-104) now connects these vertices to make faces. It is not required to create all vertices beforehand and then faces. You can safely create a new face as soon as all its vertices are there. </P ><P > Line (100) creates a new face object. A face object has its own list of vertices <TT CLASS="literal" >v</TT > (up to 4) defining it. Lines (101-103) appends three vertices to the originally empty <TT CLASS="literal" >f.v</TT > list. The vertices are two subsequent vertices of the polygon and the central vertex. These vertices must be taken from the Mesh <TT CLASS="literal" >verts</TT > list. finally line (104) appends the newly created face to the <TT CLASS="literal" >faces</TT > list of our <TT CLASS="literal" >poly</TT > mesh. </P ></DIV ><DIV CLASS="section" ><H2 CLASS="section" ><A NAME="python_example.5" ></A >Conclusions</H2 ><P > If you create a <TT CLASS="literal" >polygon.py</TT > file containing the above described code and load it into a Blender text window as you learned in the previous section and press <B CLASS="keycap" >ALT-P</B > in that window to run it you will see the script disappearing and the window turn grey. In the lower left corner the GUI will be drawn (<A HREF="c10379.html#BSG.PYT.F.S68.101" >Figure 2</A > ) </P ><DIV CLASS="figure" ><A NAME="BSG.PYT.F.S68.101" ></A ><DIV CLASS="mediaobject" ><P ><IMG SRC="PartEX/python/gfx/python_demo_gui.png"></P ></DIV ><P ><B >Figure 2. The GUI of our example.</B ></P ></DIV ><P > By selecting, for example, 5 vertices and a radius 0.5, and by pressing the <TT CLASS="literal" >Draw</TT > button a pentagon will appear on the xy plane of the 3D window (<A HREF="c10379.html#BSG.PYT.F.S68.102" >Figure 3</A > ) </P ><DIV CLASS="figure" ><A NAME="BSG.PYT.F.S68.102" ></A ><DIV CLASS="mediaobject" ><P ><IMG SRC="PartEX/python/gfx/python_demo_result.png"></P ></DIV ><P ><B >Figure 3. The result of our example script.</B ></P ></DIV ></DIV ></DIV ></DIV ><DIV CLASS="NAVFOOTER" ><HR ALIGN="LEFT" WIDTH="100%"><TABLE SUMMARY="Footer navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" ><A HREF="p10374.html" ACCESSKEY="P" ><<< Previous</A ></TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" ><A HREF="book1.html" ACCESSKEY="H" >Home</A ></TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" ><A HREF="x10601.html" ACCESSKEY="N" >Next >>></A ></TD ></TR ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" >Extending Blender</TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" ><A HREF="p10374.html" ACCESSKEY="U" >Up</A ></TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" >Python Reference</TD ></TR ></TABLE ></DIV ></BODY ></HTML >