A Blog Exploring Digital Art

This blog started life as blog for "A Mass Writing Project" to produce a book on processing. This blog has since evolved into a more general exploration of digital art. Recently I've been looking at Povray, pyprocessing, and cfdg (version 3.0) as tools for creating digital images. I have branched a separate blog where I mainly explore ruby/rp5.

Monday, 19 March 2012

Exploring Iso-Surface generation in processing

Gerd Platl has done a great job creating an algebraic surface viewer in processing which can be seen in action at open processing. I have been hacking this sketch recently to export mesh2 objects to PovRAY using my povmesh library. Now this might seem entirely daft for at least two reasons:-
  1. Gerd has produced absolutely gorgeous graphics using the GLGraphics library
  2. There exist macros for creating isosurfaces in PovRAY
However I found the exercise a great way to explore using the toxiclibs library, further it possible to pre-process the mesh using the toxiclibs utilities (in the first instance I experimented with applying Laplace transforms).  Here is the result of one such surface smoothed using such transforms and exported to PovRAY, (I reduced the resolution from 100 to 64 in the sketch):-
"PG_Icosa_4 rendered in PovRAY"

Tuesday, 13 March 2012

Exporting generativedesign library sketch to PovRAY

Until I figure out how to do it better, here I use my povwriter library to export a processing sketch using the generativedesign library (http://www.generative-gestaltung.de) to PovRAY. This example is included with the generative design library, however I found I needed to define a constructor with a PApplet argument to get the sketch to run.....

   1 /**
   2  * Part of the example files of the generativedesign library.
   3  * Modified to actually work and to use my povwriter library
   4  */
   5 
   6 // imports
   7 import povexport.*;
   8 import povexport.povwriter.*;
   9 import generativedesign.*;
  10 import processing.opengl.*;
  11 
  12 PovExporter export;
  13 boolean record = false;
  14 Process povray = null;
  15 // mesh
  16 MyOwnMesh myMesh;
  17 
  18 
  19 void setup() {
  20   size(1000, 1000, OPENGL);
  21 
  22   // setup drawing style 
  23   hint(ENABLE_OPENGL_4X_SMOOTH);
  24   colorMode(HSB, 360, 100, 100, 100);
  25 
  26   // initialize mesh. class MyOwnMesh is defined below
  27   myMesh = new MyOwnMesh(this);
  28   export = new PovExporter(this);
  29   export.createIniFile(dataPath("meshC.ini"), Quality.HIGHEST);
  30   export.writeIniFile();
  31   myMesh.setUCount(100);
  32   myMesh.setVCount(100);
  33   myMesh.setColorRange(193, 193, 30, 30, 85, 85, 100);
  34 }
  35 
  36 
  37 void draw() {
  38   background(0); 
  39   lights();
  40 
  41   if (record) {
  42     noLights();
  43     noLoop();
  44     beginRaw(PovExporter.POV, dataPath("meshC.pov"));
  45   }
  46   try {  
  47     if (povray != null && povray.waitFor() == 0) {      
  48       display();
  49     }
  50     else
  51       render();
  52   }
  53   catch(InterruptedException e) {
  54     e.printStackTrace();
  55   }
  56   if (record) {
  57     endRaw();
  58     record = false;
  59     loop();
  60   }
  61 }
  62 
  63 
  64 void render() {
  65   background(255);
  66 
  67   // setup lights
  68   colorMode(RGB, 255, 255, 255, 100);
  69   lightSpecular(255, 255, 255); 
  70   directionalLight(255, 255, 255, 1, 1, -1); 
  71   shininess(5.0); 
  72 
  73   // setup view
  74   translate(width*0.5, height*0.5);
  75   scale(180);
  76   rotateX(radians(10)); 
  77   rotateY(radians(-10)); 
  78 
  79   // recalculate points and draw mesh
  80   myMesh.setParam(1, float(mouseX)/width);
  81   myMesh.update();
  82   myMesh.draw();
  83 }
  84 
  85 void display() {
  86   background(255);
  87   PImage img = loadImage(dataPath("meshC.png"));
  88   image(img, 0, 0);
  89 }
  90 
  91 void keyPressed() {
  92   switch(key) {
  93   case 'r':    // do this first 
  94   case 'R':
  95     record = true;
  96     break;
  97   case 't':  
  98   case 'T':  
  99     export.rayTrace();  
 100     break;
 101    }
 102 }
 103 
 104 // define your own class that extends the Mesh class 
 105 class MyOwnMesh extends Mesh {
 106   public MyOwnMesh(PApplet ap) {
 107     super(ap);
 108   }
 109   // just override this function and put your own formulas inside
 110   PVector calculatePoints(float u, float v) {
 111     float A = 2/3.0;
 112     float B = sqrt(2);
 113 
 114     float x = A * (cos(u) * cos(2*v) + B * sin(u) * cos(v)) * cos(u) / (B - sin(2*u) * sin(3*v));
 115     float y = A * (cos(u) * sin(2*v) - B * sin(u) * sin(v)) * cos(u) / (B - sin(2*u) * sin(3*v));
 116     float z = B * cos(u) * cos(u) / (B - sin(2*u) * sin(3*v)); 
 117 
 118     return new PVector(x, y, z);
 119   }
 120 }

Sunday, 11 March 2012

InflateMesh to PovRAY mesh2

Processing Sketch:-
   1 /**
   2  * <p>This example uses the attraction behavior to inflate a 3D mesh.
   3  * The mesh vertices are re-created as physics particles and connected
   4  * using springs. Upon mouse press the inflation force is applied,
   5  * counteracting the forces created by the springs, causing the mesh to
   6  * expand and deform.</p>
   7  * 
   8  * <p>Usage: Click and hold mouse button to inflate mesh</p>
   9  */
  10 
  11 /* 
  12  * Copyright (c) 2010 Karsten Schmidt (+ POVMesh export Martin Prout 2012)
  13  * 
  14  * This demo & library is free software; you can redistribute it and/or
  15  * modify it under the terms of the GNU Lesser General Public
  16  * License as published by the Free Software Foundation; either
  17  * version 2.1 of the License, or (at your option) any later version.
  18  * 
  19  * http://creativecommons.org/licenses/LGPL/2.1/
  20  * 
  21  * This library is distributed in the hope that it will be useful,
  22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  24  * Lesser General Public License for more details.
  25  * 
  26  * You should have received a copy of the GNU Lesser General Public
  27  * License along with this library; if not, write to the Free Software
  28  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  29  */
  30 
  31 import toxi.geom.*;
  32 import toxi.geom.mesh.subdiv.*;
  33 import toxi.geom.mesh.*;
  34 import toxi.physics.*;
  35 import toxi.physics.behaviors.*;
  36 import toxi.physics.constraints.*;
  37 import toxi.processing.*;
  38 import povmesh.mesh.*;
  39 
  40 VerletPhysics physics;
  41 AttractionBehavior inflate;
  42 WETriangleMesh box;
  43 boolean render = true;
  44 ToxiclibsSupport gfx;
  45 POVMesh pm;
  46 
  47 void setup() {
  48   size(680, 382, P3D);
  49   gfx = new ToxiclibsSupport(this);
  50   pm = new POVMesh(this);
  51   initPhysics();
  52 }
  53 
  54 void draw() {
  55   physics.update();
  56   for (Vertex v : box.vertices.values()) {
  57     v.set(physics.particles.get(v.id));
  58   }
  59   box.center(null);
  60   for (Vertex v : box.vertices.values()) {
  61     physics.particles.get(v.id).set(v);
  62   }
  63   box.computeFaceNormals();
  64   box.faceOutwards();
  65   box.computeVertexNormals();
  66   background(51);
  67   translate(width / 2, height / 2, 0);
  68   rotateX((height / 2 - mouseY) * 0.01f);
  69   rotateY((width / 2 - mouseX) * 0.01f);
  70   noFill();
  71   lights();
  72   directionalLight(255, 255, 255, -200, 1000, 500);
  73   specular(255);
  74   shininess(16);
  75   gfx.origin(new Vec3D(), 50);
  76   fill(192);
  77   noStroke();
  78   if (render) {
  79     gfx.mesh(box, true, 5);
  80   }
  81   else {
  82     noLoop();
  83     pm.beginSave(new File(sketchPath("box.inc")));
  84     pm.setTexture(Textures.GLASS); // sequential rainbow color 1st is a red?
  85     pm.saveAsPOV(box, true);
  86     pm.endSave();
  87     render = true;
  88     loop();    
  89   }
  90 }
  91 
  92 void initPhysics() {
  93   box = new WETriangleMesh();
  94   // create a simple start mesh
  95   //box.addMesh(new Cone(new Vec3D(0, 0, 0), new Vec3D(0, 1, 0), 10, 50, 100).toMesh(4));
  96   box.addMesh(new AABB(new Vec3D(), 50).toMesh());
  97   // then subdivide a few times...
  98   box.subdivide();
  99   box.subdivide();
 100   box.subdivide();
 101   box.subdivide();
 102   physics = new VerletPhysics();
 103   physics.setWorldBounds(new AABB(new Vec3D(), 180));
 104   // turn mesh vertices into physics particles
 105   for (Vertex v : box.vertices.values()) {
 106     physics.addParticle(new VerletParticle(v));
 107   }
 108   // turn mesh edges into springs
 109   for (WingedEdge e : box.edges.values()) {
 110     VerletParticle a = physics.particles.get(((WEVertex) e.a).id);
 111     VerletParticle b = physics.particles.get(((WEVertex) e.b).id);
 112     physics.addSpring(new VerletSpring(a, b, a.distanceTo(b), 0.005f));
 113   }
 114 }
 115 
 116 void keyPressed() {
 117   if (key == 'r') {
 118     initPhysics();
 119   }
 120   if (key == 's') {
 121     render = false;
 122   }
 123 }
 124 
 125 void mousePressed() {
 126   inflate=new AttractionBehavior(new Vec3D(), 400, -0.3f, 0.001f);
 127   physics.addBehavior(inflate);
 128 }
 129 
 130 void mouseReleased() {
 131   physics.removeBehavior(inflate);
 132 }
 133 
PovRAY ini file:-
   1 ; inflate.ini
   2  
   3 Input_File_Name=/home/tux/sketchbook/InflateMesh/inflate.pov
   4 Output_File_Name=/home/tux/inflate.png
   5 Width=1280
   6 Height=1024
   7 ;Declare=RotZP5=180
   8 ;Declare=RotYP5=90
   9 Quality=11
  10 Antialias=on
  11 Sampling_Method=2
  12 Output_File_Type=N8
PovRAY pov file:-
   1 #version 3.7;
   2 
   3 global_settings{
   4   assumed_gamma 1.0
   5   radiosity{
   6     pretrace_start 0.04
   7     pretrace_end 0.01
   8     count 200
   9     recursion_limit 3
  10     nearest_count 10
  11     error_bound 0.5
  12   }
  13 }
  14 
  15 #include "colors.inc"
  16 #include "skies.inc"
  17 #include "glass.inc"
  18 
  19 #ifndef (ASPECT_RATIO)
  20 #declare ASPECT_RATIO=1.25;
  21 #end
  22 
  23 //----------------declare scene Settings
  24 #declare camera0 = camera {            // define additional cameras to suit viewing preferences
  25    location <-1.5, 30.0, -150.0>
  26    direction <0.0, 0.0, 2.0>
  27    up  <0.0, 1.0, 0.0>
  28    right <ASPECT_RATIO, 0.0, 0.0>
  29    look_at <0.0, 25.0, 35.0>
  30 }
  31 
  32 #declare light0 = light_source { <100.0, 100.0, -200.0> colour White }
  33 
  34 #declare ground0 = plane { <0.0, 1.0, 0.0>, 0.0  // a reflective ground plane
  35    pigment { NeonBlue }
  36    finish {reflection 0.15}
  37 }
  38 
  39 //------------------end of declare scene settings
  40 
  41 // -----------------set the scene
  42 
  43 camera { camera0 }              // ------------------------------------------
  44                                 //  The use of declared values makes it possible to easily 
  45 light_source{ light0 }          //  change the way the scene is rendered. Just define an
  46                                 //  additional camera say for your template, and do the
  47 sky_sphere{ S_Cloud3 }          //  substitution here. Retain the original definition and
  48                                 //  you can easily backtrack. Definitions can also be saved
  49 plane{ ground0 }                //  as included file see colors.inc for an example.
  50                                 // ---------------------------------------------  
  51 // -----------------end set the scene
  52 
  53 
  54 
  55 #include "my_texture.inc"     // include texture before geometry
  56 #include "box.inc"
  57 
  58 
  59 object{
  60         mesh2{mesh_objects}
  61         scale<2, 2, 2>
  62         rotate<0, 0, 270>
  63         translate<0, 29, 70>
  64 }
  65 
  66 


The my_texture.inc and box.inc are generated by the povmesh library, for now the inflate.ini and inflate.pov are hand edited (but include much that can be reused, so you don't have to really create them from scratch) for greatest flexibility.


Result of PovRAY raytracing:-

Followers

Blog Archive

About Me

My Photo
Pembrokeshire, United Kingdom
Consolidating my online identity as monkstone. I am a 64 bit linux user and advocate of open source software, you can sometimes find me on the processing forum.