mercredi 2 mai 2012

GLSL lighting and other changes

Today no more images or videos as my program is once again under massive changes...

Anyway I implemented a GLSL Phong lighting using the wrapper from Tristam Macdonald [1] but I wasn't really happy about the "plastic effect" that was generated so at the end I used a simple diffuse shader to light my scene and will use the Phong one only for the shinny parts (glass from lenses, metal from mirrors or for crystals such as beam splitters...)

I played a bit with the color picking module to move the lenses but it is rather slow and imprecise at the moment so I think I will just change the pyglet variable button to allow a constant change at a definite rate when the GUI button is pressed for now and will come back at the picking module in a bit to interact with slicing planes.

I also fixed the bugs in my ABCD script and made it modular, depending from a dictionary of dictionaries containing all the parameters from the set-up, in which one can add or remove components. This modularity must now be implemented at the GUI level.

I finally managed to "cut" one edge from the beam, as it was my problem for me to implement mirrors. It was at the end really simple when using the clipping plane from OpenGL, it consists of the following procedure :

Push a matrix so that everything remains untouched
glPushMatrix()
Declare the clip plane, 4 is the number of points determining the plan, 0.0 and 1.0 directions of cut (can be -1 for inverse direction), here it is a 45° plan that can be moved using the d parameter 
glClipPlane(GL_CLIP_PLANE0, (GLdouble*4)(1.0, 0.0, 1.0, d))
Enable it
glEnable (GL_CLIP_PLANE0)
Draw the model to be cut 
batch.draw()
Disable it  and pop the matrix to not cut the others elements 
glDisable (GL_CLIP_PLANE0)
glPopMatrix()

So now I have to finish to code all those changes and I will come next time with some images to show you how the project evolves.

[1] http://swiftcoder.wordpress.com/2008/12/19/simple-glsl-wrapper-for-pyglet/

dimanche 22 avril 2012

Components part 1



As I said in my previous post, I wanted to model the components. This is still a work in progress but I proudly present you the *new* lens and detector design. To construct them I wrote a class which take advantage of the pyglet batch system. God I love those batches... The two models are in fact made out of three new primitive forms (plus my old cube) which are cylinder, disk and hollow disk. I simply create them with appropriate dimensions and position and add them to the component's batch. That allows me to render the component in a single call !

This is especially interesting as I can therefore use the batch position when building the vertices, allowing me simple and fast manipulation of objects from my scene. This works by building the model each time that a position is altered, either by a call from the GUI or by user manipulation (through picking), the others batches aren't altered.
There is no lighting here it is just different coloring of the primitives. I will soon implement a GLSL lighting, I am currently testing it.
I also have a little color picking script that kinda work but that will wait a bit as I am not really happy with this solution. I think I will look more deeply into the ray picking technique maybe with bounding boxes to speed it up.

If I don't have too much work this week I will also design the source and I would like to include a mirror component into my project (I still have to figure out how to cut one end of the beam according to the angle of the mirror). Also still a long way to go...   

vendredi 20 avril 2012

Virtual Optics

Yesterday I put my hands again on the Virtual Optics project that I was telling about. I hadn't touched it in a month or so as I was busy with other things and I learned the hard way a very basic lesson of programming: cleaning and commenting the code is essential !!! Anyway I spent the last two days repairing my laziness and now it is a brand new project that I can work on, I reorganized all of my scripts and commented half of it, you can see the result in the video below:

 

It is not much, it is basically an ABCD matrix [1] program for a two lenses system. It allows to calculate the shape of a laser beam in such a system. The main goal of this project is at the end to be a possibility to quickly and interactively evaluate the feasibility and also some characteristics of an optical setup.

It is entirely written in python with pyglet and glydget libraries as only dependencies, the GUI window can be reduced to only display "Menu" and can be moved around. The frame rate displayed at the bottom left corner is only there for debug. To model the beam I used a parametric surface (altered function from the torus example of  pyglet).

That's it for the introduction, I spend approximatively a month coding it as a hobby but now I have a solid base to build on. In the near future I will redesign the components and implement others, I also want to make them pickable and It will be also great to be able to add or remove optical components on the fly.

More on this coming later... 
If interested I will happily give the code, it will be great for me to have feedbacks, just write me an email at: simulationplayground@gmail.com


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

lundi 5 mars 2012

Python, pyglet, OpenGL and OpenCL

Hello,
I started this blog to talk about a new hobby of mine : programming.
As I had a bit of time for me this summer and I also just had learned how to use Matlab (mainly for image processing), I decided to extend this experience with some little OpenCV experiments. I started in C++ but was not completely happy with the compiling process so I decided to switch to python and give it a try... And I fell in love with it, it is a language that is actually really easy and fun to develop with. I made a little program that allow to control the mouse with the web-cam (color tracking, no clicks) and in august I started to use OpenGL, the result gave this blog its name :






 







It represents 1M particles moving inside a cube with a little collision detection algorithm to maintain them inside. It uses pyglet (http://www.pyglet.org/,
for windowing and also as OpenGL wrapper, I particularly like the "batch" feature, see for yourself !

The GUI is done with a tiny library called glydget by Nicolas P. Rougier (http://www.loria.fr/~rougier/coding/python) I really like the design but there are some extending to do, I would especially need a slider (someday I'll make one of mine...).

Particles movement and collision detection at the edge of the cube run on the GPU (graphic card) thanks to PyOpenCL (http://wiki.tiker.net/PyOpenCL). The OpenCL kernels derivate from the outstanding tutorial from Ian Johnnson (http://enja.org/category/tutorial/advcl/). The particles are in fact a points cloud with geometry shader. The resource from dlampletest was particularly useful (http://sites.google.com/site/dlampetest/python/vectorized-particle-system-and-geometry-shaders) as long as the pyglet glsl wrapper from swiftcoding (http://swiftcoder.wordpress.com/2008/12/19/simple-glsl-wrapper-for-pyglet/) to build the system.

I also implemented a FPS-type camera and a trackball that I derived from this tutorial (http://www.siteduzero.com/tutoriel-3-4978-controle-avance-de-la-camera-partie-1-2.html). This is a French tutorial but an English tutorial, from swiftless (http://www.swiftless.com/) or others should not be too difficult to find on Google).

It is implemented on my personal laptop (Ubuntu 11.10, Intel i5, Geforce GT 330M, python 2.7.2) and runs at ~15FPS, I tried to post a video of it but the result was too flickery.

I will not release the code as it is a rather old project that I already rebuild from byte codes using uncompyle2 (https://github.com/wibiti/uncompyle2), a little tool that I recommend when you, as I, have lost your files and want to recover them from byte codes (.pyc). I also think that I already provide an exhaustive list of better resources than mine that can be use to develop pretty fast the same program. But I will stay open to discuss it with you if you are interested.
This will be the only post on this project but I will post soon on my new project that I started last month which I called "Virtual Optics".