mardi 6 mars 2012

Swig tutorial : gl2ps wrapper

Today I will explain you how to wrap a C file to call it from python.

I learned it by wrapping the C library from Christophe Geuzaine (http://geuz.org/gl2ps/) which allow you to export an OpenGL scene into a PostScript file (ps, eps, pdf or svg).
First you have to download and install a library called SWIG (http://www.swig.org/), if you are running on Ubuntu this can be easily done by taping the command line :

§ sudo apt-get install swig

Then you have to make a ".i" file to swig, which will be connected to the C header.
Start by opening a text editor and copy this :

%module gl2ps
%{
#include "gl2ps.h"
%}

%typemap(in) FILE* {
  $1 = (FILE *) PyFile_AsFile($input);
}


Here we indicate the future name of the module (gl2ps.py) and at which C header it will be linked.
Then you just have to copy all the necessary items from the header, in my case I copied all the lines starting from  /* Version number */ , I also removed if defined(_cplusplus) loops, endif /*__GL2PS_H__*/ statement and all the GL2PSDLL_API at the end of the header since I am on Ubuntu and will call this file from python. If you are running on Windows I think that you should past the entire file as it is but I haven't tried to swig on Windows so...
Once it is done just save the text file as gl2ps.i in the same folder than the header and C file. Then just run from the directory where all the files are :

§ swig -python gl2ps.i

This produce two files : gl2ps.py and gl2ps_wrap.c. After that you just have to create a little setup.py which uses distutils to help us compile the wrapped program. This tiny bit of code look like this (Note: to build this requires that OpenGL is currently installed in a common directory) :
from distutils.core import setup, Extension
setup(name="gl2ps",
      py_modules=["gl2ps"],
      ext_modules=[Extension("_gl2ps",
                             ["gl2ps.c","gl2ps_wrap.c"],
                             libraries=["GL"])]) 
That's it ! You just have to run...

§ python setup.py build or § python setup.py build install

...to begin to use your new gl2ps.py module (Note : if you are using it as standalone module in your application the _gl2ps.so file must be in the same folder than the gl2ps.py).

Example of use :
Just as a little key event in the pyglet graphics example.
@window.event
def on_key_press(symbol, modifiers):
    if symbol == key.S:
        print "let's test it !"
        state = GL2PS_OVERFLOW
        buffsize = 0
        fp = open("torus.eps", "wb")
        print "Writing... "
        while(state == GL2PS_OVERFLOW):
            buffsize += 1024*1024
            gl2psBeginPage("test", "gl2psTestSimple", None, GL2PS_EPS, GL2PS_SIMPLE_SORT,
                         GL2PS_DRAW_BACKGROUND | GL2PS_USE_CURRENT_VIEWPORT,
                         GL_RGBA, 0, None, 0, 0, 0, buffsize, fp, "torus.eps")
            batch.draw()
            state = gl2psEndPage()
        fp.close()
        print "Done!\n"
        return pyglet.event.EVENT_HANDLED

Aucun commentaire:

Enregistrer un commentaire