Recently I've been looking at Povray, pyprocessing, and cfdg (version 3.0) as tools for creating digital images. I have branched two separate blogs where I mainly explore jruby + processing and processing.py

Monday, 30 April 2012

StructureSynth revisited (menger variant)

I've been experimenting with various stochastic menger sponges in processing, so I thought I'd see what would work in StructureSynth, here is the resulting 'eisenscript' and ray traced image:-
set maxdepth 20000
R1 

rule R1 w 2 maxdepth 2 > c2 {
R2
}

rule R1 maxdepth 3 > c2 {
R2
}

rule R2{
  { s 1/3 x -1 y -1  } R1 
  { s 1/3 x -1 y -1  z -1 } R1 
  { s 1/3 x -1 y -1  z +1 } R1 
  { s 1/3 x 1 y -1  } R1 
  { s 1/3 x 1 y -1  z -1 } R1 
  { s 1/3 x 1 y -1  z +1 } R1 
  { s 1/3  y -1  z -1 } R1  
  { s 1/3  y -1  z +1 } R1 
  { s 1/3 x -1 y 1  } R1 
  { s 1/3 x -1 y 1  z -1 } R1 
  { s 1/3 x -1 y 1  z +1 } R1 
  { s 1/3 x 1 y 1  } R1 
  { s 1/3 x 1 y 1  z -1 } R1 
  { s 1/3 x 1 y 1  z +1 } R1 
  { s 1/3  y 1  z -1 } R1  
  { s 1/3  y 1  z +1 } R1 
  { s 1/3 x -1   z -1 } R1 
  { s 1/3 x -1   z +1 } R1 
  { s 1/3 x 1    z -1 } R1 
  { s 1/3 x 1    z +1 } R1 
}

rule c2  w 3{
{color blue} box
}

rule c2 {
 {color orange} sphere
}

Saturday, 28 April 2012

Philip Sutton RA at Richmond Hill Gallery

Now for something a bit different, my old mate Philip Sutton is exhibiting again at the Richmond Hill Gallery. Something else to look out for in this Olympic year, is cultural events celebrating William Shakespeare. According to Phil one of his series of paintings possibly this one, has been enlarged into a huge poster on canvas, elswhere I've seen some of some of the images cropping up on silk scarves.

Wednesday, 18 April 2012

Coffeescript-Mode for Processing

Well it had to happen really, thanks to Florian Jenett there is now a coffee-script mode for processing. Get it here. This is what it looks like in action (you will need processing-2.0a5 or greater) click on image to see full size:-
coffeescript mode in processing ide
sketch from ide running in browser

Monday, 16 April 2012

ArcBall for pyprocessing

Here is a sketch that demonstrates the use of my processing.py ArcBall class to create intuitive object rotation for pyprocessing.
from util.arcball import ArcBall

"""
test_arcball.py by Martin Prout a pyprocessing sketch
Sketch features the use of ArcBall class, provides intuitive manipulation of sketch object
ArcBall class uses Quaternions class for efficient calculation of rotation, hold down x, y or z
keys to constrain rotation to that plane otherwise drag mouse for smooth rotation
"""

def setup():
    size(600, 600, OPENGL)
    global arcball
    arcball = ArcBall(width/2.0, height/2.0, min(width - 20, height - 20) * 0.5)
    arcball.axis = -1

def draw():
    background(0xff66c0ff)
    translate(width/2.0, height/2.0, -height/4.0)
    defineLights()
    update()
    lights()
    stroke(0)
    cube(arcball.radius)
    
def update(): 
    theta, x, y, z = arcball.update()
    rotate(theta, x, y,  z)

def mousePressed():
    arcball.mousePressed(mouseX, mouseY)
  
def mouseDragged():
    arcball.mouseDragged(mouseX, mouseY) 

def defineLights():
    """
    Light up the cube
    """
    ambientLight(50, 50, 50)
    pointLight(150, 100, 0, 200, -150, 0)
    directionalLight(0, 102, 255, 1, 0, 0)
    spotLight(255, 255, 109, 0, 40, 200, 0, -0.5, -0.5, PI / 2, 2)

def keyPressed():
    """
    Fix axis of rotation by holding down key corresponding to axis
    """
    if (key == 'x'):
        arcball.selectAxis(0)
    if (key == 'y'):
        arcball.selectAxis(1)
    if (key == 'z'):
        arcball.selectAxis(2)

def keyReleased():
    arcball.selectAxis(-1)

def cube(sz):
    sz *= 0.5  
    fill(200,  200,  200,  255) 
    beginShape(QUADS)
    vertex(-sz, -sz, -sz)
    vertex(+sz, -sz, -sz)
    vertex(+sz, +sz, -sz)
    vertex(-sz, +sz, -sz)
    vertex(-sz, -sz, +sz)
    vertex(+sz, -sz, +sz)
    vertex(+sz, +sz, +sz)
    vertex(-sz, +sz, +sz)
    vertex(-sz, -sz, -sz)
    vertex(-sz, -sz, +sz)
    vertex(-sz, +sz, +sz)
    vertex(-sz, +sz, -sz)
    vertex(+sz, -sz, -sz)
    vertex(+sz, -sz, +sz)
    vertex(+sz, +sz, +sz)
    vertex(+sz, +sz, -sz)
    vertex(-sz, -sz, -sz)
    vertex(+sz, -sz, -sz)
    vertex(+sz, -sz, +sz)
    vertex(-sz, -sz, +sz)
    vertex(-sz, +sz, -sz)
    vertex(+sz, +sz, -sz)
    vertex(+sz, +sz, +sz)
    vertex(-sz, +sz, +sz)
    endShape()
For full code including quaternion.py and arcball.py go to github, where you can either clone my pyprocessing-experiments, or download them as a zip archive.

Friday, 6 April 2012

Using pypy to run pyprocessing sketches

Over on the pyprocessing discussion group, I posted my experience of fairly slow rendering of the menger in my previous post. I did not really expect a reply, as it was really only a part excuse for my creating an export to PovRAY. However Flavio Coelho, put me on to trying out pypy, which did lead to quite an improved performance. What I did on my linux box (64bit aptosid distro):-
  1.  I downloaded the 64 bit binary, as superuser I extracted it to the /opt folder, I used update-alternatives to create a symbolic link to /usr/local/bin/pypy 
  2. I reinstalled pyglet using pypy I reinstalled pyprocessing using pypy
  3.  I ran my sketches using pypy with much improvement.
 However I am sure an even greater performance improvement could be achieve if I used GLSL shaders with pyglet (this is the way vanilla processing is headed), but I think I will leave that to the pyprocessing developers. In the meanwhile I had already re-factored my menger2.py sketch to use a Box class (a generalization of cube), with the mesh logic extracted to a new Mesh class. This should reduce the memory usage somewhat as the instance of Box should be garbage collected, on translation to mesh? I use my Aptosid installation as a test bed, else I would not have so happily installed pypy on ubuntu where I do most of my development using Eric5 as my ide (requires python-3.2+).

Update 7 April 2012 some numbers for running menger2.py on my linux box:-

  1. on Apstosid using pypy 1.066 fps (min size 20) 
  2. on Ubuntu using python 0.142 fps (min size 20)
Quite an improvement I will have to say, on aptosid, started off slower 0.8fps and speeded up. ubuntu was painful (down to cpython).

Thursday, 5 April 2012

Exporting to PovRAY from pyprocessing

In my previous blog post, I published a menger pyprocessing sketch where the geometry was created on the fly. In this case the "cubes" of the menger were created with a beginShape(QUADS), endShape() block. I figured it might be quite interesting to create all the geometry (much in the same way as you do with toxiclibs) first then just do the rendering in the draw() loop. You can see the code at GitHub don't forget to look in the util folder, for the helper classes (Cube and Vec3D) in the util module. Most of the logic for rendering a cube is encapsulated in the cube.py file. The re-factored menger is now rendered in a beginShape(TRIANGLES) endShape() block, this made it pretty easy to apply the knowledge I picked up creating my povmesh library (that exports from toxiclibs sketches in vanilla processing to PovRAY) to exporting the menger as a union of PovRAY mesh 2 objects to a menger.inc file which rendered pretty damn quick (1.5 minutes) using the following menger.ini and menger.pov files.  The save file is configured for export alone,  a lower size of 10 is only suitable for export use say 40 for pyprocessing/pyglet rendering.

; menger.ini high quaility setting set quality = 5 say for preview

Input_File_Name=menger.pov
Output_File_Name=menger.png
Quality=11
Antialias=true
Sampling_Method=2
Width=1280
Height=1024





// Persistence Of Vision Ray Tracer Scene Description File
// File:  Simple Scene for pyprocessing export (geometry from menger.inc)
// Vers: 3.7
// Date: April 2012
// Auth: Martin Prout 

// +w1280 +h1024

#version 3.7;

global_settings{
  assumed_gamma 1.0
  radiosity{
    pretrace_start 0.04
    pretrace_end 0.01
    count 200
    recursion_limit 3
    nearest_count 10
    error_bound 0.5
  }
}

#include "colors.inc"
#include "skies.inc"

//----------------begin declare finish

#declare Finish0=finish{diffuse 0.75 emission 0}  // Stroke
#declare Finish1=finish{diffuse 0.78 emission 0}  // Cornell Box Light Patch
#declare Finish2=finish{emission 0.1 phong 0.5 phong_size 10.0}   // Processing object finish

//----------------end declare finish

//----------------begin declare texture

#declare WhiteT=texture{pigment{White} finish{Finish2}} //

//----------------end declare texture

//----------------declare scene Settings
#declare camera0 = camera {            // define additional cameras to suit viewing preferences
   location <-1.5, 30.0, -150.0>
   direction <0.0, 0.0, 2.0>
   up  <0.0, 1.0, 0.0>
   right <1.25, 0.0, 0.0>
   look_at <0.0, 25.0, 35.0>
}

#declare light0 = light_source { <100.0, 100.0, -200.0> colour White }

#declare ground0 = plane { <0.0, 1.0, 0.0>, 0.0  // a reflective ground plane
   pigment { NeonBlue }
   finish {reflection 0.15}
}

//------------------end of declare scene settings

// -----------------set the scene

camera { camera0 }              // ------------------------------------------
                                //  The use of declared values makes it possible to easily 
light_source{ light0 }          //  change the way the scene is rendered. Just define an
                                //  additional camera say for your template, and do the
sky_sphere{ S_Cloud3 }          //  substitution here. Retain the original definition and
                                //  you can easily backtrack. Definitions can also be saved
plane{ ground0 }                //  as included file see colors.inc for an example.
                                // ---------------------------------------------  
// -----------------end set the scene
#include "my_texture.inc"
#include "menger.inc"

object{
union{ mesh_objects
texture{ WhiteT }
}
scale<0.5, 0.5, 0.5>
rotate<20, 45, 0>
translate<0, 65, 400>
}
Here's the PovRAY rendered menger
Click on Image to see Full Size

Wednesday, 4 April 2012

A Menger Sponge in Pyprocessing

   1 from pyprocessing import *
   2 
   3 FOV = PI/3.0
   4 angle = 0.0
   5 ANGLE_STEP = PI / 180.0
   6 
   7              
   8 
   9 def setup():
  10     size(800,600)
  11     cameraZ = (height/2.0) / tan(FOV/ 2.0)
  12     perspective(FOV, float(width)/float(height), cameraZ/10.0, cameraZ*10.0)
  13     
  14 def draw():
  15     background(0,  0,  200)
  16     noStroke()
  17     stroke(0)
  18     lights()
  19     defineLights()
  20     translate(width/2.0, height/2.0, 0)
  21     global angle
  22     angle = (angle + ANGLE_STEP) % TWO_PI
  23     rotateZ(angle)
  24     rotateY(angle)
  25     create_menger(0, 0, 0, height/2.0)
  26 
  27 def my_cube(xx,  yy,  zz,  sz):
  28     """
  29     Draw a cube with centre xx, yy, zz and size sz
  30     """
  31     beginShape(QUADS)
  32     normal(0, 0, 1)
  33     vertex(-sz / 2.0 + xx, -sz / 2.0 + yy, -sz / 2.0 + zz)
  34     vertex(+sz / 2.0 + xx, -sz / 2.0 + yy, -sz / 2.0 + zz)
  35     vertex(+sz / 2.0 + xx, +sz / 2.0 + yy, -sz / 2.0 + zz)
  36     vertex(-sz / 2.0 + xx, +sz / 2.0 + yy, -sz / 2.0 + zz)
  37     
  38     #Back face    
  39     normal(0, 0, -1)
  40     vertex(-sz / 2.0 + xx, -sz / 2.0 + yy, +sz / 2.0 + zz)
  41     vertex(+sz / 2.0 + xx, -sz / 2.0 + yy, +sz / 2.0 + zz)
  42     vertex(+sz / 2.0 + xx, +sz / 2.0 + yy, +sz / 2.0 + zz)
  43     vertex(-sz / 2.0 + xx, +sz / 2.0 + yy, +sz / 2.0 + zz)
  44     
  45     #Left face    
  46     normal(1, 0, 0)
  47     vertex(-sz / 2.0 + xx, -sz / 2.0 + yy, -sz / 2.0 + zz)
  48     vertex(-sz / 2.0 + xx, -sz / 2.0 + yy, +sz / 2.0 + zz)
  49     vertex(-sz / 2.0 + xx, +sz / 2.0 + yy, +sz / 2.0 + zz)
  50     vertex(-sz / 2.0 + xx, +sz / 2.0 + yy, -sz / 2.0 + zz)
  51     
  52     #Right face    
  53     normal(-1, 0, 0)
  54     vertex(+sz / 2.0 + xx, -sz / 2.0 + yy, -sz / 2.0 + zz)
  55     vertex(+sz / 2.0 + xx, -sz / 2.0 + yy, +sz / 2.0 + zz)
  56     vertex(+sz / 2.0 + xx, +sz / 2.0 + yy, +sz / 2.0 + zz)
  57     vertex(+sz / 2.0 + xx, +sz / 2.0 + yy, -sz / 2.0 + zz)
  58     
  59     #Top face    
  60     normal(0, 1, 0)
  61     vertex(-sz / 2.0 + xx, -sz / 2.0 + yy, -sz / 2.0 + zz)
  62     vertex(+sz / 2.0 + xx, -sz / 2.0 + yy, -sz / 2.0 + zz)
  63     vertex(+sz / 2.0 + xx, -sz / 2.0 + yy, +sz / 2.0 + zz)
  64     vertex(-sz / 2.0 + xx, -sz / 2.0 + yy, +sz / 2.0 + zz)
  65     
  66     #Bottom face    
  67     normal(0, -1, 0)
  68     vertex(-sz / 2.0 + xx, +sz / 2.0 + yy, -sz / 2.0 + zz)
  69     vertex(+sz / 2.0 + xx, +sz / 2.0 + yy, -sz / 2.0 + zz)
  70     vertex(+sz / 2.0 + xx, +sz / 2.0 + yy, +sz / 2.0 + zz)
  71     vertex(-sz / 2.0 + xx, +sz / 2.0 + yy, +sz / 2.0 + zz)
  72     endShape()
  73 
  74 def create_menger(xx, yy, zz, sz):
  75     """
  76     Create a recursive menger sponge using my_cube
  77     """ 
  78     u = sz / 3.0
  79     if (sz < 40):
  80         my_cube(xx, yy, zz, sz)
  81     else:
  82         for i in xrange(-1, 2, 1):
  83             for j in xrange(-1, 2, 1):
  84                 for k in xrange(-1, 2, 1):
  85                     if ((abs(i) + abs(j) + abs(k)) > 1):
  86                         create_menger(xx + (i * u), yy + (j * u), zz + (k * u), u)
  87                         
  88 def defineLights():
  89     """
  90     Without lights you wouldn't see the menger
  91     """
  92     ambientLight(50, 50, 50)
  93     pointLight(150, 100, 0, 200, -150, 0)
  94     directionalLight(0, 102, 255, 1, 0, 0)
  95     spotLight(255, 255, 109, 0, 40, 200, 0, -0.5, -0.5, PI / 2, 2)     
  96  
  97 
  98 run()
  99     
 100 
Experimenting to see how a pyprocessing pyglet rendered sponge compares with processing-2.05a, you could easily see another level of recursion, if you set limit size to 20, but rotation gets a bit slow (no memory issues though), I might just look at PovRAY export from pyprocessing? Even though I know there is a brilliant iso-surface rendering of a menger in PovRAY, I fancy creating a hybrid shape, where some cubes get replaced by spheres (tricky to achieve as an iso-surface).

Followers

Blog Archive

About Me

My photo
Pembrokeshire, United Kingdom
I have developed JRubyArt and propane new versions of ruby-processing for JRuby-9.1.5.0 and processing-3.2.2