As of revision number 1794 of July '09, the environment variables for building the python bindings have changed. Please read the linked section.
On the minus side, the new bindings can only be compiled at the moment with g++, which means MinGW on Win32. They've been built using SIP 4.7.3, 4.12.2, and 4.13.2 (4.10, on the other hand, has a bug that prevents the build from working); MinGW g++ 3.4.2 and 4.5.2 (and various other versions on Linux); and Python 2.4-2.7.
C:/Python24/include(yes, forward slashes).
python2.5; on Windows it should not include the decimal point, e.g.
python24. I know, it's ugly. This is the value for the -l linker argument.
C:/Python24/libs/python24.lib(also forward slashes).
cdto szg/python_sip and type
make cleancleans (deletes) things up. A number of files are generated/moved.
...You'll also need to install the Python OpenGL bindings package, PyOpenGL. We've tried PyOpenGL 2.0.1.09 and 3.0.1. For old-style OpenGL programs PyOpenGL 2 is much faster (follow the "View older releases" link on the SourceForge download page).
Um. Sorry, no Python API reference yet. Working on it.
There are a few demos in szg/python_sip/demos.
You can look at a webpage on Syzygy Python Programming. It's a bit out of date, e.g. referring to the old PySZG module instead szg, but mostly still accurate; eventually it'll be integrated with the Syzygy documentation. Refer to the corresponding programs in python_sip/demos/ to see how the new module works.
The only way to figure out what objects and methods exist is to look at the .sip source files
in szg/python_sip/src. They're very similar to C++ header files, with some additional
annotations. One thing to note, if a method parameter has the /Out/ annotation, it will
actually be returned by the Python wrapper method. For example, the
object has a method called
getAttributeVector3() that returns a Syzygy database
parameter as a 3-element vector. The entry in the file
szg/python_sip/src/szgclient.sip looks like this:
bool getAttributeVector3( const string& groupName, const string& parameterName, arVector3& value /Out/ );
This means that the Python method should be called e.g. like this:
(statusBool, value) = szgClient.getAttributeVector3( 'SZG_HEAD', 'mid_eye_offset' )
Besides looking in a standard location for imported modules (e.g.
on Windows), Python will search for modules in directories listed in the
variable. You must set this variable to the path to the directory containing szg.py and
_szg.pyd (or add the path to the variable if it already exists). Of course, it will
also look in the same directory as a program for modules imported by that particular program.
We suggest putting data, textures, and sounds used by an application in the same directory (or a subdirectory) and opening them using relative paths.
To understand this section, you should read about the Syzygy Cluster Mode.
The preferred way to do this is to set the Syzygy database variable
to the full path to the python executable, e.g. on Windows it might be
(omit the '.exe') and on Linux it could be the output of the
which python command.
It must begin with one of the
base paths passed as command-line arguments to szgd
(we suggest including the
entire path to Python in the base paths
szgd argument, minus the '.exe' on Windows).
There is a Syzygy database variable SZG_PYTHON/path that should be set to a semicolon-delimited
list of absolute paths to directories. Each of these paths must begin with one of the
base paths passed as command-line arguments to szgd.
search for your program in each directory in this list and in all directories each one contains.
This search only goes one level down the directory tree, i.e. it doesn't include subdirectories
of subdirectories of directories in the list. This allows you to place each program in a
separate directory together with its data, without having to modify
SZG_PYTHON/path for each
As mentioned above, Python uses the
PYTHONPATH environment variable as a search path for
imported modules. The following Syzygy database variables are dynamically prepended to
PYTHONPATH (i.e. their current values are prepended when a program is launched, then removed):
SZG_EXEC/path. These paths will be searched
in the order given. Note that only the directories listed are searched by Python, not
This depends on the type of program. For master/slave programs,
everything but sound files are read by the program itself in Cluster Mode; sound files need
to be read by the SoundRender program. When
szgd launches a program, it sets the
current directory to the one containing the program. This means that if you put texture maps, .obj 3-D
models, and other kinds of data in the same directory as your program or a subdirectory
thereof, as suggested above for Standalone Mode, you're good to go.
For sound files, you need to either (1) Copy them into a directory that's listed in the
Syzygy database variable
SZG_SOUND/path, or (2) Tell SoundRender where to find them
by calling the framework method
setDataBundlePath() as described in the
szgd identifies Python programs by suffix and invokes the Python interpreter. All
Python programs must have the suffix '.py'. To run a Python program named 'foo.py' with
command-line arguments <args> on a virtual computer named `vc`,
dex vc foo.py <args>
You should be very careful to put the line
from szg import *
before any imports of PyOpenGL modules in your Python code. This is because the PyOpenGL modules try to load the GLUT dynamic library themselves from their local installation and this may conflict with the version of GLUT linked to Syzygy.
The Python cPickle module (for persistent storage of Python objects, either files or in strings) seems to be less cross-platform than advertised. Actually, we're not sure if this is a platform or a version issue; a file generated with cPickle on a Windows machine running Python 2.2 can't be un-pickled on a Linux machine running Python 2.3. The Python master/slave framework uses cPickle in the setObject method, for packing an arbitrary Python object into a string for transfer from master to slaves, so this implies that Python master/slave applications may run into trouble running on mixed-platform or -version clusters. We've run into a few other cases in which cPickle behaves strangely, throwing exceptions for no apparent reason; some of these can be avoided by using the slower pickle module instead (pickle is written in Python, cPickle in C). Or if security is a concern, you could used twisted.spread.banana and twisted.spread.jelly from the Twisted package. Pickle is a security risk, because an attacker could insert arbitrary commands in a string that would be executed on un-pickling; only use pickle if you control both ends of a transaction.
Python input devices only work in Cluster Mode.
This feature is specific to the new (SIP) bindings. Tersely, you implement a
arPyDeviceServerFramework, minimally overriding the
configureInputNode() method. This method can do a few things:
arGenericDriverif you're going to do all of the actual event generation in Python code or
arSharedLibInputDriverif you want to load one of the C++ "ar..Driver" shared libaries. If it's an
arGenericDriver, you'll want to save a reference to it.
In general you'll also want to have a loop that generates the actual events. Of course, these can be based on any information that Python can access: a real device via serial connection, a GLUT or wxPython GUI, or a web page, to name a few possibilities. There are a few simple examples in szg/python_sip/demo/inputdevices:
To use one in the context of a virtual computer, you generally have to do three things:
SZG_PYTHON/executablefor the computer it's on.
SZG_PYTHON/path(or one level down, see Path Configuration).
virtual_computer SZG_INPUT0 map this_computer/glutjoystick.py
dex virtual_computer <app> should cause the Python input device to start on