# Blender 3D: Blending Into Python/Printable version

The current, editable version of this book is available in Wikibooks, the open-content textbooks collection, at
https://en.wikibooks.org/wiki/Blender_3D:_Blending_Into_Python

# Optimize
## Writing Optimal Exporters and Importers for Blender:Python

If you are starting out in writing a script, don't take these guidelines too seriously, its worth getting things working and then sight a need for optimization before you begin to look for areas to optimize your script.
If you're making a tool for others, keep in mind that they might use it with larger datasets than those you have been testing with. So before releasing it can be good time to try to optimize.
For more generic python performance tips see http://wiki.python.org/moin/PythonSpeed/PerformanceTips

## Getting Objects (Exporting/General Blender)

   Blender.Object.Get is often used to get all objects for exporting. This is bad practice since Object.Get will return objects from every scene in Blender, this is almost never what the user wants and could result in overlapping data, but also could take a long time if the user has 2 or more large scenes consuming a lot of memory.
   Instead use Blender.Scene.GetCurrent.getChildren This returns all objects from the current scene.
   Another alternative is to use Blender.Object.GetSelected which returns selected objects on visible layers in the current scene.

## Getting Mesh data (Exporting Only)

   Meshes are not just thin wrappers like most of the other Types in Blender so you want to avoid meshObject.getData and meshObject.data as much as possible, its best practice only calling each mesh data once.
   To get the name of the data the object references do not use ob.getData.name simply to get the name of the object. Instead use obj.getData(1) ... meaning obj.getData(1=name_only) this is nice because it works for all data types, its just that
   Note, recently (as of 15/10/05) the addition of the Mesh module (a thin wrapper around Blenders mesh data) means that you can do a meshObject.getData(mesh=1) without the problem NMesh has, however this is new and doesn't support all the NMesh functions.

## Use new python functionality mesh.transform (Exporting Only)

   As of Blender 2.37 nmesh.transform(ob.matrix) can be used to transform an NMesh by a 4x4 transformation matrix.
   On my system it is over 100 times faster than transforming each vert's location and normal by a matrix within python. Though the overall speed gained by using this in my obj exporter was about %5.
   make sure that if you are exporting vertex normals add a 1, mesh.transform(matrix, recalc_normals=1) This avoids un-needed vertex normal transforming.

## Beware of python hogging memory. (python generally)

   You may ignore this point, for small applications, but I have found that for larger scenes this can become a problem if not allowed for early on.
   A List in python (and therefore blender:python) is never deallocated, however python can re-use the memory whilst the script is running. Basically making large lists in python and a lot of recursive variable assignment can leak memory that can only be regained with a restart. - *If you can- avoid making large lists.
   This is Fixed in Python 2.4.1 which will compile with blender.

## Lists (Python General)
   ### List Lookup

      In Python there are some tricky list functions that save you having to search through the list.
      Even though you're not looping on the list data python is, so you need to be aware of functions that will slow down your script by searching the whole list.
      The above functions performs a full loop on the list, so if you can avoid using them on large lists, your script will run faster.

   ### Modifying Lists

      In python we can add and remove from a list, This is slower when lists are modified in length at the start of the list, since all the data after the index of modification needs to be moved up or down 1 place.
      Of course the most simple way to add onto the end of the list is to use myList.append(listItem) or myList.extend(someList) and the fastest way to remove an item is myList.pop
      To use an index you can use myList.insert(index, listItem) and pop also takes indicies for list removal, but these are slower.
      Sometimes its faster (but more memory hungry) to just rebuild the list.
      Say we want to remove all triangle faces in a list.
      Rather then
      It is faster to build a new list with list comprehension.

   ### Adding list items

      If you have a list that you want to add onto another list, rather then appending in a for loop, use
      instead of...
      Note that insert can be used when needed, but it is slower than append especially when inserting at the start of a long list. This example shows a very suboptimal way of making a reversed list.

   ### Removing List Items

      Use myList.pop(i) rather then myList.remove(listItem)
      This requires you to have the index of the list Item but is faster since remove needs to search the list.
      Using pop for removing list items favors a while loops instead of a for loop.
      Here is an example of how to remove items in 1 loop, removing the last items first, which is faster (as explained above)
      A fast way of removing items, where you can mess up the list order, is to swap 2 list items, so the item you remove is always last.
      When removing many items in a large list this can provide a good speedup.

   ### Avoid Copying Lists

      When passing a list/dictionary to a function, it is better to have the function modify the list rather then returning a new list. This means python dosn't need to create a new list in memory.
      Functions that modify a list in their place are more efficient then functions that create new lists.
      normalize(vec) faster: no re-assignment ...is faster then.
      vec = normalize(vec) slower, only use for functions that are used to make new, unlinked lists.
      Also be note that passing a sliced list makes a copy of the list in python memory eg..
      foobar(mylist[4:-1])
      If mylist was a large list of floats, a copy could use a lot of extra memory.

## Dictionaries (Python General)
   ## Dict Lookup

      When you access a dictionary item, someDict['foo'] A lookup is performed, pythons lookups are very fast, but if your are accessing this data in a loop its better to make a variable that can be referenced faster.

# Strings
## Pathnames (Exporting)

   Blender pathnames are not compatible with path names from other generic python modules.
   python native functions don't understand blenders // as being the current file dir in blender and # to be the current framenumber.
   A common example is where your exporting a scene and want to export the image paths with it.
   Blender.sys.expandpath(img.filename)
   Will give you the absolute path, so you can pass the path to functions from other python modules.

## Correct string parsing (Import/Exporting)

   Since many file formats are ASCII, the way you parse/export strings can make a large difference in how fast your program runs.
   When importing strings to make into blender there are a few ways to parse the string.

   ### Passing String

      Use float(string) rather then eval(string) and if you know the value will be an int then int(string) float will work for an int too but its faster if ints are converted as ints.

   ### Checking String Start/End

      If your checking the start of a string for a keyword, use...
      ...rather then
      Using Startswith is slightly faster (about 5%).
      myString.endswith('foobar') can be used for line endings too.
      Also, if your unsure whether the text is upper or lower case use lower or upper string function. Eg. if line.upper.startswith('VERT ')

## Writing Strings to a File (Python General)

   Here are 3 ways of joining multiple strings into 1 string for writing
   This really applies to any area of your code that involves a lot of string joining.
   Pythons string addition. Dont use if you can help it, especially in the main data writing loop.
   String formatting. Use this when you're writing string data from floats and int's
   Pythons string joining function. To join a list of strings
   join is fastest on many strings, string formatting is quite fast too (better for converting data types). And string arithmetic is slowest.

# Other
## Profile your code (Python General)

   Simply timing sections of your code will point you to the part that needs optimizing. Eg

## Psyco JIT Compiler (Python General)

   A python module called psyco exists that can dynamically compile some of python functions. Most of the speed gains affect algorithms written in python, so importers and exporters have less to gain from them then scripts that deal with 3d math.
   For many scripts, a no brainier way of using psyco is to do a.
   Psyco can also profile your code.
   For scripts to be distributed it is polite to try loading psyco to avoid raising an error.
   Note that psyco reports to use a lot of system memory, if you run out of ram it may be best not to use psyco.

## Use Try/Except Sparingly

   The try function is useful to save time writing code to check a condition,
   However 'try' is about 10 times slower then 'if', so dont use 'try' in areas of your code that execute in a loop that runs many times (1000's or more).
   There are cases where using 'try' is faster than checking wether the condition will raise an error, so it is worth experimenting.

## Python Objects
   ### Use "is" instead of "=="

      In some cases "is" can be used instead of "==" for comparison, "is not" for "!=".
      "==" Checks whether the 2 variables are the same value, where as "is" tests that the python object is the same, shares the same memory - are both an instance of the same object. (Python Object, not Blender a Object)
      The advantage of using "is" is that its faster since it dosent need to compare as much data.
      Here is a benchmark test that compares a python class and a blender vector- one the same and one different.
      My Computer showed the following results. I should do more tests- but this is representative of other tests.
      The same test with vec1, vec2, class1, class2 as ints and floats.
      "is" still faster.

# Image Functions
### Edit Image in External Program

This runs in linux (probably any unix), and launches The Gimp. It could probably be modified to launch Photoshop in windows.
In Gnome, KDE and Mac OS X, you can use a command to open documents using the default or a specified application.
* KDE: kfmclient openURL <URL, relative or absolute path>
* Gnome: gnome-open <any URL or path Gnome understands>
* Mac OS X: open [-a <application name>] <path>
Win32 has some open command too, maybe somebody could add this in.

### Find Images

This script recursively searches for images that have broken files references.
It works by giving the user a root path, then finds and re-links all images within that path.
Its very useful when migrating projects to different computers.

### Remove Double Images

This script finds images that are referenced more than once, and looks through all meshes texface's, and assigns only one of the images.
If a face has no users the image is removed.
This is useful because when an image is loaded more than once, it's also loaded into system memory and graphics card memory more than once, wasting resources.
Support for image type textures still needs doing.

# Material Functions
### Toon Material Batch Conversion Script

this script changes *all* materials in your currently open blend file to toon materials. after executing, check the blender console for script output.
as this script alters *all* of your material settings in your currently opened blend file, you should *not* run it on a project that has not been saved yet! changes made to materials while using this script cannot be undone!
note: changes are not permanently committed to your blend file unless you choose to save your file after executing this script.

# Curve Functions
### Length of a curve

This function gets the combined length of all edges. Most useful to get the length of a curve. Be careful, because it will get the length of every curve in a curve object!
Note that this function doesn't take the object's transformation into account when getting the length.

# Text Functions
### Paste Text in Unix

Paste text in X11, requires uclip

### Save all Texts as files

Saves all text editor texts as files in the current working directory. WARNING: This will overwrite files with those names!

# Mesh Functions

Examples and functions for Blenders NMesh, GMesh and new Mesh module.

### Mesh tool template

Use this to base your editmode mesh tool on.

### Desaturate Meshes VertCol

Uses the new Mesh module. In Blender 2.4 only. Desaturates using the same weighting as Photoshop uses.

### Point inside a Mesh

This function returns 1/0 depending on whether the provided point is inside a mesh. It relies on the mesh having a continuous skin, no holes in it. (Otherwise the problem doesn't make sense.)
It uses the method of seeing how many face intersections there are along a line segment between that point, and a point somewhere outside the meshs bounds.
An even number of intersections means it's outside, an odd for inside. Hence we return len(intersections) % 2 where intersections generates a list of intersections.
This function uses a Z direction vector so we can save some CPU cycles by first doing an X/Y bounds test to see if the points could intersect, before doing a full ray intersection.

### Scanfill for importers

This function takes a mesh and a list of vert indicies representing an ngon. It returns a list of tri indicies that make up the scanfilled face. This is much more useful for importers.
it also handles cases where scanfill does not work by returning a triangle fan.
It may be faster then using the mesh.fill function on your original mesh because cycling editmode can be slow on a lot of data. Another advantage with this function over simply using fill is you can be sure the faces will be flipped the right way, according to the order of the indicies.

### Triangulate NMesh

This is a function to be used by other scripts, its useful if you want to make your life simpler by only dealing with triangles.
The shortest edge method is used for dividing the quad into 2 tri's.

### Fix vertex winding in "bowtie" quads

Sometimes you may encounter quad faces which, although correctly coplanar, aren't quite "full". This comes from the vertices being in the wrong order, and causes the face to overlap itself, often leaving undesired holes and black areas where the normals point the wrong way. To see what this all means, just make a plane and switch places for the vertices at any edge. The connecting edges will then cross. Since the normals of the face don't make sense in this situation, the script can't guarantee that the normal points outwards after finishing.

### Remove Verts Without removing entire faces

Script that uses the mesh template above. removes verts but surrounding quads will be converted to tri's. Note This only works with NMesh.

### GMesh AutoSmooth Mesh

This function uses GMesh to autosmooth manifold meshes, it requires the GMesh module.
Be careful because it will smooth your mesh in place, so make a copy of your original object if you don't want it modified.

### ScanFill

To simulate typing "Shift F" in blender to create scanfill selected edge loop (edit mode only)
This will only work if the 3D view is open.

### Expanded Scanfill function

Self contained scanfill function, based on the code above. Note, this function needs a 3D view to be available
Example function usage.

### Copy NMesh Face

Returns a new face that has the same properties as the original face but with no verts

### Returns the Faces centre as a Vector

Note, Blenders Mesh API now has face.cent access
Take 1 NMFace and return a vector as its centre, will use an existing vector object "cent" if provided.

### Flip Faces Up

I used this script to flip all faces in many terrain meshes to point up. It uses Mesh as opposed to NMesh.

### Scale UVs

Scales all uv coords for selected mesh objects.

### Find a material in all Meshes in all Scenes

Sometimes You have a lot of mesh object and materials you don't want any of them to use. This script can help you find those objects.

### Faces share an edge

The 2 faces share an edge, its best to make sure your not comparing the same faces, and remove the first 'if'.

### Get Edge Angles

Returns a list of angles, the combine angle difference of all faces that use the edges. the angles returned are in sync with mesh.edges. Edges with 0 or 1 faces will have Zero angle.
This function uses Blender.Mesh not Blender.NMesh mesh data.

### Mesh Ray Intersect

Intersect a ray with a mesh, Assume the mesh has no loc/size/rot.

### Copy Vertex UV to Face UV

Copies the Vertex UV coordinates (Sticky) to face UV coordinates (TexFace).

# Math Functions

Here is the place to add math examples, they can be blender specific or generic python math functions.

### Changing Rotation Axis Order

If you ever have trouble converting between different rotation systems its possible that the order of rotations is the problem.

### Get Angle between 3 points

Get the angle between line AB and BC where b is the elbow.

### Point inside a tri (2D)

Returns True if pt is inside the triangle.
only gives a correct answer when pt lies on the triangles plane.

### Apply Matrix

Applys a 4x4 transformation as returned by object.getMatrix, to a vector (3d point in space)
This is useful for finding out the position of a vertex in worldspace.
Blender 2.43 supports this simply by doing "newvwec = vec*matrix" but its good to know how to do it manually

### 2D Line Intersection

Intersect 2 lines, if so where.
If there is no intersection the retured X value will be None and the y will be an error code.
The first line is (x1,y1, x2,y2), the second (_x1,_y1, _x2,_y2)

### Round to power of 2

This function takes any number and rounds it to the nearest power of 2 value (2,4,8,16,32,64,128,256,512,1024,2048, 4096...) This is useful for rounding textures to sized that load into graphics card memory.
It returns 3 values. rounded down, round closest, rounded up.

### Closest Point (snapping)

Returns the vector that is closest to point. Good for snapping.

# Blender Object Scripts
### Linked Duplicate Object

There is no function in B:Python to make a linked duplicate of an object (Alt+D) so here is a function that does it for you.
Note Since this was written Blender.Object.Duplicate has been added as well as object.copy

### Select Double Objects

Finds double object- objects that have the same dataname, type and loc/size/rot

### NLA strips Examples

Example code for manipulating NLA strips and action strips

# Blender Windowing and User Interface Scripts
### Auto Buttons

Auto Buttons is a really easy way to add a stack of buttons into any script.
Add the AutoButtons text to the bottom of any script and any function ending with _bgui will have a button that calls it.
An example of a function that could use this

### Popup Menu Wrapper

This script takes a string that you would normally give to Draw.PupMenu splitting up the menus by the groupsize.

# General Python

Here add general python code, useful when Python scripting.

### Benchmark Script

Script that times different functions.

### Iterate Multiple Lists

Sometimes you want to loop over more than 1 list at once. if the lists your dealing with are large then creating a new list for the purpose can be slow and use too much memory. This class takes multiple lists and treats them like 1 big list. without having to make a new list.
Some examples
Another example that takes verts from 3 meshes and adds them to 1 mesh using this iterator and list comprehension.

### Binary Conversion (Without Struct)

Thanks to SJH 07/29/2004 20:26:03

### Randomize List

Returns a randomized list. Note if you can import random, use random.shuffle(ls) instead.

### Remove Doubles in List

Removes doubles in a list, modifying the original list. (will use an objects cmp function)

### Remove Doubles in List (Hash)

Return a new list with no doubles.

### Get flag properties of a sum

A lot of properties in Blender are flags and stored in a sum of exponentials of 2. To find out that a specific flag is set and it is included in the sum try this function:
Call the function in that way:

### Fraction Data Type

Allows creation of fraction data and all operations on them within the real number system.

### Get a name with sane chars

This function can be used when you are making a filename from an object/mesh/scene... name. Blender supports many characters in a name that a filesystem may not.
saneFilechars replaces these characters with "_"

# Colour Scripts

A place for scripts that deal with colours.

### RGB to HSV

Convert Red/Green/Blue to Hue/Saturation/Value
r,g,b values are from 0.0 to 1.0
h = [0,360], s = [0,1], v = [0,1]
if s == 0, then h = -1 (undefined)
The Hue/Saturation/Value model was created by A. R. Smith in 1978. It is based on such intuitive color characteristics as tint, shade and tone (or family, purety and intensity). The coordinate system is cylindrical, and the colors are defined inside a hexcone. The hue value H runs from 0 to 360º. The saturation S is the degree of strength or purity and is from 0 to 1. Purity is how much white is added to the color, so S=1 makes the purest color (no white). Brightness V also ranges from 0 to 1, where 0 is the black.

### HSV to RGB

Convert Hue/Saturation/Value to Red/Green/Blue

# Render Functions
### Render to a dir
### Render from all cameras

This script renders an animation from all cameras in a scene, it makes a new name from the camera and leaves the scene as it was originally.
Be sure to use useful camera names.

# Scriptlinks
### Monitor Image

This Script needs to be used as a redraw scriptlink. It checks the date of the current image and attempts to reload the image, and if successful it redraws the image.

### Dynamic Text

This script needs to be used as a FrameChanged script linked to a Text object. Change the Years.append line to choice the years of the timeline.

# External Utils
### Compress All Blend files (Unix Only)

Sine blender 2.41, support for GZip compression has been integrated into blender. So you can gzip all blend files and they will still open as expected.
This utility searches your hard-disk for blend files and gzips them if they are not already compressed.
Note: python3 required.

# Orphan Scripts

Hi, post unmaintained scripts here.
Be wary of malicious code, especially the OS module, check in the history every so often for edits to see nobody's doing bad stuff.
Currently there are two scripts here in need of nice mothers or fathers.
This script is a simple L system that allows you to use pre-defined meshes. It DOES work in 2.43 and could possibly be a building generator (with some work).
This script apparently WONT work in blender 2.43, updates welcome.

# Features

Here is the temp location for features Campbell and Vince from MetaVR wish to add for improved modelling in simulation.
* Vert Select to UV Selection.
* UV Window, Align weld- to be able to welt to the left, right,top,bottom.
* Relax vertex to surrounding.
* Relax vertex- make the vertex evenly spaced and fit the surrounding faces/verts.
* Rotate along edge.
* Projection UV mapping modifier. (use cameras?)
* Move uv island to another edge non connected edge
* BuildingGenerator: BuildingGenerator — building Generator

# Blender Python C API
## Mini Unfinished Guide to adding a C/API extension

Add blurb- what this is good for etc.
Heres a mini tutorial
* Find a variable that you can not access from BPython
* Look for a button that modifies the value in the user interface
* Write down the buttons tooltip
* Use a find tool to find the Tooltip for the button in the source code (There are some source code searching tools you can get)
* The line with the tooltip will also reference a variable. Now you know what the variable name is for the button.
* Go into Python code folder and open the relevant C file (Lamp.c, Material.c etc.)
* Find a similar exististing variable in the c file- (e.g., if your setting a flag, then find another BPy function that sets a flag)
* Look for every instance of this variable, under each instance, copy it and replace the name with your new one. make the obvious modifications.
make sure to add the setattr and getattr values for class variable names. You don't have to do this, but you probably should eventually.
Recompile and test!
Voila
Note Sometimes not all variables are seen directly from the UI. As fas as I know all blender datatypes are structs internally. To find all the variables used by this DataType- Look through the files in- Blender/source/blender/makesdna/... They are named well and you can see all the variables.

# 2.5 quickstart

In Blender 2.5 bpy replaces the old Blender module, introducing with it a completely new Python API. This page is designed to give an overview of how to perform key scripting tasks with bpy, and should be of interest both to newcomers and those transitioning from the 2.4x releases.

## The console

The built-in Python console has had a major overhaul in Blender 2.5, and now supports autocompletion (press Ctrl+Space). This is great for exploring all the new functions, though inline documentation is sparse.
Latest version (14-7-2010) activate console: Shift+F4.

## Context + Operation = Result

The 2.5 series introduces the bpy.ops module. Once you register your script as an "operation" it will integrate directly into the UI and can appear as a standard button identical to the built-in tools (which also use ops). Usefully for programmers, the function call of each operation appears in the tooltip of its button.
There is also a big conceptual change in ops: instead of being explicitly passed a target, operations deduce one from Blender's current "context". The context includes an array of what is currently selected, the current active object or bone, the active editing mode, the state of the Blender window, user preferences, and more besides.
Operations take no arguments and return no values. For this reason calling them from within complex scripts is considered sloppy, since you must indirectly set the operation's target, then (unless you already have a pointer) hunt indirectly for its results. Calling objects' functions directly is still supported, of course; unfortunately, as of 2.5 alpha 0 there are still a lot of ops that can't be replicated with direct calls.

## Performing tasks in 2.5

Remember that ops functions do not return a value. After calling one to create an object, you will need to get a handle to the result yourself!

### Creation and destruction
#### bpy.ops.object.add(type='EMPTY')

    Creates an object and empty datablock, and links it to the current scene. See also #Manual object creation.

#### bpy.ops.scene.new(type='EMPTY')

    Creates a new scene. Can be a clone or full duplicate of the current scene.

#### mesh_object.data.add_geometry(verts, edges, faces)

    Adds verts, edges and faces to a mesh. Object mode only.

#### object.modifiers.new(type="ARMATURE",name="Armature")

    Adds a modifier to an object.

#### bpy.ops.mesh.edge_face_add

    If two verts are selected, creates an edge. If three or more verts are selected, creates face(s) as well.

#### bpy.ops.mesh.primitive_cube_add

    Adds a cube to the current mesh object. Other primitive_*_add functions exist.

#### bpy.ops.armature.bone_primitive_add(name="Bone")

    Adds a bone to the active armature.

#### bpy.ops.*.delete

    Deletes the selected objects, mesh, etc. Many versions exist for different types.

#### Manual object creation

If you need finer control than ops.object.add provides, or just return values, follow this example:
There is also add_armature, add_image, add_lamp, add_material and add_texture.

### Getting objects and data
#### bpy.data.*

    A group of collections of Python objects. There are many - one for each type. As with normal dictionaries you can pick objects out by name or by index, to add new datablocks use new or load for images, sounds and fonts.

#### object.data

    An object's datablock.

#### mesh.data.vertices

    A mesh's vertex collection. Read-only.

#### armature.data.edit_bones

    An armature's bone dict, in object and edit mode respectively. If you access the wrong object for the current context, it will appear empty.

### Context management
#### bpy.ops.object.mode_set(mode='EDIT')

    Set the current mode. Note that the mode may not end up exactly as you set it here: for instance, EDIT can become EDIT_ARMATURE.

#### bpy.context.active_base

    These functions return the user's currently active item, which is generally the last one of its type selected. active_base returns a generic Python type.
    To set the active item, assign a Python object to one of the following values:
   * scene.objects.active
   * armature.data.bones.active or armature.data.edit_bones.active
    The active object is highlighted white in the outliner.

#### bpy.context.selected_bases

    Returns an array of the currently-selected objects. Other functions exist for editbones, "editable objects" and pchans.

#### object.selected

    Boolean value defining whether the object is selected.

## Registering an operation

See .blender\scripts\templates\operator.py. With your script registered, you will be able to add it to the Tool shelf and launch it from the spacebar menu.

# Reference

Blender Python API Reference
DataBlock Wrapper Submodules
* Reference: Camera — Modify the properties of camera
* Reference: Curve — ...
* Reference: Image — Deals with Image objects loaded into Blender.
* Reference: Ipo — Animated curves used for controlling a veriety of properties.
* Reference: Lamp — Animated curves used for controlling a veriety of properties.
* Reference: Lattice — ...
* Reference: Material — ...
* Reference: Texture — ...
Blender Interface SubModules
* Reference: Draw — Access user interface elements.
* Reference: BGL — OpenGL Access inside blender.
* Reference: Window — Global events, user interactions.
Blender General SubModules
* Reference: Mathutils — 3D Math Functions
* Reference: Noise — Random/Noise/Turblence functions
* Reference: Registry — Global events, user interactions.
* Reference: Sys — Used instead of python sys, adds some blender specific functions.