Table of Contents

HappyDoc Generated Documentation  

Python Blender module documentation // Wed Feb 6 14:23:27 CET 2002

This documentation is under development. Some things may not look good, please feedback at the documenation forum at www.blender.org

License

      Copyright (c)  2002  Stichting Blender Foundation.
      Permission is granted to copy, distribute and/or modify this document
      under the terms of the GNU Free Documentation License, Version 1.1
      or any later version published by the Free Software Foundation;
      with no  Invariant Sections, with no
      Front-Cover Texts, and with no  Back-Cover Texts.
      A copy of the license is included in the section entitled "GNU
      Free Documentation License".
GNU Free Documentation License

Introduction

This is the Developer Documentation for the Blender Python API. It is intented to be a reference only and meant for the experienced programmer and Blender user. It shall be a starting point for better organized documentation writers, and it will be up to them to create a nicer documentation with examples, etc. designed for the starter :-)

The Blender module is split up in several sub modules allowing to import only needed functionality.

Typical usage:

     import Blender
     ob = Blender.Object.get('Plane')  # get Object with name 'Plane'

or:

     from Blender import Object
     ob = Object.get('Plane')

...

Terminology

Blender Object

A Blender Object (BO) is the visible instance of a data block object (see below) in a 3D scene. The represented data (e.g. mesh data) is not stored in the Object's structure though, it is a separate DataBlock object pointed to by the Object structure. Therefore, data can be shared among several Objects, which can have different properties (location, size, color, etc.) Note: Blender Objects are normally spelled with a capital O. If the context requires explicity, we will use BObject.

Users

The number of users that a shared object in Blender has. See below.

DataBlock

A Blender DataBlock Object represents the BO's data and can have several users. For explicity, we will use BDataBlock. For example, a BObject of type "Mesh" refers to a Mesh DataBlock object -- so it is the User of the Mesh DataBlock. Deletion of the Mesh DataBlock is illegal, as long as it has a User count higher than 0.

Raw object

This is the general term for a raw object in Blender, directly referring to a C struct or C++ class.

Wrapper object

This is the general term for a descriptor or proxy object used to access a raw object through Python without copying data. The wrapper object usually specifies methods or member emulation to provide access to the raw object's data members. To denote a wrapped Object, we will use the prefix Py, e.g. PyBCamera for a wrapper object around a Blender Camera.

Owner

Often, objects are created on the heap as a single independent chunk of data. In many cases though, a container block - called Owner - is desired for data structures that occur in large numbers (such as vertices, etc.). ** Creation and deletion always happens through the Owner! **

Creation and deletion of Blender Objects

Implementation methods

This paragraph is rather technical, Python script writers can safely skip it, unless they're interested :-)

In Python, the common method is to create a free (non owned) instance of a data type (or class) first and then assign it to an owner. In Python itself, there is never a clear ownership and everything is done by reference counting. Deletion of objects happens when their reference count hits the zero.

In Blender, it is often desired to explicitely delete an object (which can still be referenced by another user). Reference counting is only wanted on objects which are not directly owned by a container, such as Mesh objects (which can have several users), or in cases, where the user wants to keep an object around (persistent data) outside of Blender. Keeping references around can easily introduce hardly visible memory shortages though, and requires the user to make sure that the complete namespace is released after the script ends.

To represent clear ownership of objects, there are 3 methods:

  1. Never expose owned objects to the script user. For example, a Vertex owned by a mesh could never be referenced directly, but via the owner.

    Example:

              m = Mesh.get('Plane')
              m.setVertexCoordinates(vertindex = 2, coo = (0.0, 1.0, 0.0))
    
    

    This does not really represent the Python'ish way of accessing data, but makes the access perfectly safe, as long as it is made sure, that the mesh is not being deleted by someone else during these calls.

    The slightly faster way of the above:

              setCurrentMesh(m)
              setVertexCoordinates(2, (0.0, 1.0, 0.0))
              releaseMesh(m)     # don't allow any more access
    
    

    This would be the rather "state machine" than the OO way.

    Speed: fastest, Memory: medium, Restrictiveness: highest

  2. Reference abstraction: The Wrapper object for the owned object contains a pointer to the owner (in C++: a wrapped SmartPointer). For a Vertex for example, the wrapper object would contain a pointer to the Owner mesh and a vertex index. For each access, validity would be checked by index. Again, mesh deletion must not happen during execution of the script (or be properly observed by method 2).

    Speed: slower, Memory: little, Restrictiveness: high

  3. Observe Wrappers: The Wrapper Object will do a validity check of the pointer to its raw object by using an "Observer", which actually holds the raw pointer. The Raw Object must notify the observer when it goes out of scope (NULL its pointer). On illegal access of an object, a Python exception will be thrown.

    Example:

              m = Mesh.get('Plane')
              v = m.vertices[2]
              v.loc = (0.0, 1.0, 0.0)
    
              #... here is some code which clears all vertices
    
              v.loc = (0.0, 2.0, 0.0) # This will throw an exception
              m.update()  # apply all changes, and lock the mesh
    
    

    Again, it will have to be made sure, that the mesh is not deleted by someone else during the access (use reference counting on the mesh)

    Speed: fast, Memory: medium, Restrictiveness: high

Due to Blender 2.x's architecture, it is currently not possible to thoroughly implement these methods (without having to change the low level structures). For the moment, methods 2 and 3 will be chosen where appropriate. For fast access, the method 1's syntax might be desired later on (gameEngine?).

Usage

As a first example, we create and delete an object with clear ownership; a Scene is always owned by Blender and must not be created freely or deleted by anyone else than its owner:

        import Blender
        scene = Blender.Scene.New('scene2')   # create new empty scene
        scene.makeCurrent()                   # make active scene
        Blender.Scene.unlink(scene)           # delete it
        print scene.getChildren()             # invalid access, this will
                                              # throw an exception

Now we create a Lamp, which is a free object (not owned by a container):

        from Blender import Lamp, Object, Scene
        lamp = Lamp.New('Spot')           # new lamp of type 'Spot'
        lamp.energy = 1.8
        lamp.spotSize = 30.0              # set some properties
        ob = Object.New('Lamp')           # create Lamp Object
        ob.link(lamp)                     # link lamp data to Object
        sc = Scene.getCurrent()           # current Scene
        sc.link(ob)                       # link object to Scene

        ob = Object.New('Lamp2')           # create another Lamp Object
        ob.setLocation(10.0, 0.0, 0.0)     # set location
        ob.link(lamp)                      # link with same Lamp data
        sc.link(ob)                        # and link Object to same scene   

For a new object, a DataBlock is always created, so the lamp data can be accessed another way:

        from Blender import Object, Scene
        ob = Object.New('Lamp')           # create Lamp Object
        la = Object.getData()             # get Datablock
        la.energy = 0.5
        Scene.getCurrent().link(ob)       # and make it visible in the Scene

...

Implementation details

To make the emulation of the old API possible in reasonable time, the whole Blender module is in fact a Python module, put on top of the existing (and slightly modified) C Python module.

A Blender object acquired by Python results in creation of two Wrappers:

     +--------------+    +------------------+    +-------------------+
     | Shadow Class | -> | Wrapper PyObject | -> | Blender datablock |
     +--------------+    +------------------+    +-------------------+

     <Blender module>     <_Blender module>         <Blender C API>

In this case, the Shadow classes also provide the docstrings used to generate this documentation. Each shadow object class is derived from one of the base classes defined in the shadow module (see documentation). These base classes also define common methods for certain object types.

PROPOSAL: Naming convention

Members

Member attributes should usually start with a lowercase character.

Uppercase start characters should only be used in special cases.

Underscore in names (_) should be avoided for public members. An underscore should denote a member which should not be used by high level code. Members starting with an underscore should not be used outside its owning class (in C++ terminology: protected)

Methods

If the attribute starts uppercase, the method creates an object and returns a reference to it. Otherwise, an action to the object is applied, and/or a simple value or reference to an existing object is created.

For objects closely emulating certain Python objects (such as lists) the Python syntax will be mimicked as most as logical.

All functions getting or setting object properties through a rather abstract data type (or if data hiding desired) start with get or set.

Methods doing conversion of class or object start with as or from.

It is now time for an example:

        matrix = ob.getMatrix()    # get matrix from object
        matrix.normalize()         # normalize matrix - this does *not* modify
                                   # the object's original matrix.
        q = m.asQuat()             # calculate quaternion from 'm'

Modules and Packages   

./

README.txt.html

Python Blender module documentation // Wed Feb 6 14:23:27 CET 2002

Camera

The Blender Camera module

Image

The Blender Image module

Ipo

The Blender Ipo module

Lamp

The Blender Lamp module

Material

The Blender Material module

Mesh

The Blender Mesh module

NMesh

The Blender NMesh module

Object

The Blender Object module

Scene

The Blender Scene module

Text

The Blender Text module

Window

The Blender Window module

shadow

Shadow class module


Table of Contents

This document was automatically generated on Mon Feb 25 13:52:14 2002 by HappyDoc version r1_5