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

Tuesday, 28 December 2010

Simple Export DXF example using a modified supercad library

The great thing about povray is it is very human readable, and providing that use declarations to declare say color / pigment / texture / material / finish you can readily post edit the file exported by processing (even easier if you have a template file that can be edited, rather than one that is hard coded). My modified supercad library has such a feature, here is a library example taken from the the processing core library that supports DXF export. Povray does complain a bit about degenerative triangles (but they just don't get drawn) with my modified library (no kludge factor), however sketch renders fine. However this sketch would render better if I translated the sphere primitives directly into a povray script, rather than as triangle mesh.
 I've been taking a look at the yafaray-xml renderer, which can be integrated into blender which should be much faster, haven't managed to compile a yafaray-xml that is integrated with blender yet!!!


import supercad.povwriter.*;
import supercad.*;

String cadSoftware, ext;
boolean record = false;

void setup() {
  size(400, 400, P3D);
  noStroke();
  sphereDetail(12);
}

void draw()
{  
  if(record) {
    noLoop();
    beginRaw("supercad."+cadSoftware, "output."+ext);
  }
  lights();
  background(0);
  translate(width / 3, height / 3, -200);
  rotateZ(map(mouseY, 0, height, 0, PI));
  rotateY(map(mouseX, 0, width, 0, HALF_PI));
  for (int y = -2; y < 2; y++) {
    for (int x = -2; x < 2; x++) {
      for (int z = -2; z < 2; z++) {
        pushMatrix();
        translate(120*x, 120*y, -120*z);
        sphere(30);
        popMatrix();
      }
    }
  }
  if (record) {
    endRaw();
    record = false;
    loop();
  }
}


void keyPressed() {

  switch(key) {
  case 'r': 
    cadSoftware = "Rhino"; 
    ext = "rvb"; 
    break;
  case 's': 
    cadSoftware = "SketchUP"; 
    ext = "rb";
    break;
  case 'a': 
    cadSoftware = "AutoLISP"; 
    ext = "lsp";
    break;
  case 'p': 
    cadSoftware = "PovRAY";    
    ext = "pov";  
    break;
  case 'm': 
    cadSoftware = "Maya"; 
    ext = "mel";
    break; 
  case 'o': 
    cadSoftware = "ObjFile"; 
    ext = "obj";
    break;       
  case 'c': 
    cadSoftware = "ArchiCAD"; 
    ext = "gdl";
    break;
  }  
  record = true;
}


Wednesday, 22 December 2010

Ben Tilbert rendered in povray from processing

The coloring of the povray rendered image bears no resemblance to the original processing sketch, though theoretically possible, I'm not sure there is any real advantage. The relationship between the processing sketch and the ray traced image vary in other ways. Just like the three processing/sunflow interface, the camera position bears from processing bears little resemblance to the pov file settings. StructureSynth in contrast actually manages a pretty good job with its sunflow template, but not the povray template.

import supercad.povwriter.*; // Latest edition of my customised supercad library
import supercad.*;

import lsystem.*;      // contributed libraries
import peasy.*;        //

float HALF = PI/360;   // introduce half a degree error
String axiom = "A";
String production;
float THETA = HALF_PI + HALF;
float PHI = HALF_PI - HALF;
PeasyCam cam;
Grammar grammar;
String cadSoftware, ext;
boolean record = false;

void setup()
{
  size(600, 600, P3D);
  cam = new PeasyCam(this, -70,70,-70,250);
  cam.rotateX(PI/5);
  cam.rotateY(PI/5);
  noStroke();
  grammar = new SimpleGrammar(this, axiom);
  grammar.addRule('A', "B>F<CFC<F>D+F-D>F<1+CFC<F<B1^");
  grammar.addRule('B', "A+F-CFB-F-D1->F>D-1>F-B1>FC-F-A1^");
  grammar.addRule('C', "1>D-1>F-B>F<C-F-A1+FA+F-C<F<B-F-D1^");
  grammar.addRule('D', "1>CFB>F<B1>FA+F-A1+FB>F<B1>FC1^");
  production = grammar.createGrammar(3);
}

void draw()
{  
  if(record) {
    noLoop();
    beginRaw("supercad."+cadSoftware, "output."+ext);
  }
  render();
  if (record) {
    endRaw();
    record = false;
    loop();
  }
}

void render() {
  int repeats = 1;
  int col = color(0, 225, 0);
  lights();
  directionalLight(128, 128, 128, 0, 0, 1);
  background(0);
  CharacterIterator it = grammar.getIterator(production);
  for (char ch = it.first(); ch != CharacterIterator.DONE; ch = it.next()) {
    switch (ch) {
    case 'F':
      fill(col);
      float len = 30;
      translate(0, 0, -len / 2);
      box(5, 5, len - 1.6);     
      translate(0, 0, -len / 2);
      box(5, 5, 5);
      break;
    case '+':
      rotateX(THETA * repeats);
      repeats = 1;
      break;
    case '-':
      rotateX(-THETA * repeats);
      repeats = 1;
      break; 
    case '>':
      rotateY(THETA * repeats);
      repeats = 1;
      break;
    case '<':
      rotateY(-THETA * repeats);
      repeats = 1;
      break;
    case '^':
      rotateZ(PHI * repeats);
      repeats = 1;
      break;
    case '1':
      repeats += 1; 
    case 'A':
    case 'B':
    case 'C':
    case 'D':
      break;
    default:
      System.err.println("character " + ch + " not in grammar");
    }
  }
}

void keyPressed() {

  switch(key) {
  case 'r': 
    cadSoftware = "Rhino"; 
    ext = "rvb"; 
    break;
  case 's': 
    cadSoftware = "SketchUP"; 
    ext = "rb";
    break;
  case 'a': 
    cadSoftware = "AutoLISP"; 
    ext = "lsp";
    break;
  case 'p': 
    cadSoftware = "PovRAY"; 
    ext = "pov";
    break;
  case 'm': 
    cadSoftware = "Maya"; 
    ext = "mel";
    break; 
  case 'o': 
    cadSoftware = "ObjFile"; 
    ext = "obj";
    break;       
  case 'c': 
    cadSoftware = "ArchiCAD"; 
    ext = "gdl";
    break;
  }  
  record = true;  
}

Tuesday, 21 December 2010

'F' Test for superCAD library

Here is little processing sketch designed to test the superCAD library, it should produce a 3D 'F'

import superCAD.*;
                                 // a modified superCad library
String cadSoftware, ext;
boolean record = false;

void setup() {
  noStroke();
  size(400, 400, P3D);
}

void draw()
{  
  if(record) {
    noLoop();
    beginRaw("superCAD."+cadSoftware, "output."+ext);
  }
  render();
  if (record) {
    endRaw();
    record = false;
    loop();
  }
}

void render() {
  translate(width/2, height*0.4);
  box(50);
  translate(0, -50, 0);
  box(50);
  translate(50, 0, 0);
  box(50);
  translate(-50, -50, 0);
  box(50);
  translate(0, -50, 0);  
  box(50);
  translate(50, 0, 0);
  box(50);
}

void keyPressed() {

  switch(key) {
  case 'r': 
    cadSoftware = "Rhino"; 
    ext = "rvb"; 
    break;
  case 's': 
    cadSoftware = "SketchUP"; 
    ext = "rb";
    break;
  case 'a': 
    cadSoftware = "AutoLISP"; 
    ext = "lsp";
    break;
  case 'p': 
    cadSoftware = "PovRAY";    
    ext = "pov";  
    break;
  case 'm': 
    cadSoftware = "Maya"; 
    ext = "mel";
    break; 
  case 'o': 
    cadSoftware = "ObjFile"; 
    ext = "obj";
    break;       
  case 'c': 
    cadSoftware = "ArchiCAD"; 
    ext = "gdl";
    break;
  }  
  record = true;
}















Here is the 'F' rendered using the original superCAD library with a modified toStringComa function, where the Y and Z vertices are multiplied by -1.


protected String toStringComa(float[] vertex){
    return vertex[X] + ", " + vertex[Y]*-1 + ", " + vertex[Z]*-1;
}

The "F" is the right way up, facing right, both reflection and shadow look right, what is not to like? Other solutions like scale(1, -1, 1) worked to correct 'Y' axis but scale(1, -1, -1) did not seem to work?

Of course without the proposed change to  toStringComa you get an inverted and reversed 'F'.

Monday, 20 December 2010

Translating processing coordinate to povray coordinates

Well this is extremely promising based on Dave Bollingers modified DXF export I think I've solved the translation problem, and it is very simple. In my startTriangle function of the PovTriangle class, for each coordinate of the triangle I multiply the Y and Z coordinates by -1.

 3   public StringBuilder startTriangle(float[][] point) {
 4     StringBuilder povString = new StringBuilder(getType());
 5     povString.append("\n{<");
 6     povString.append(point[0][0]);
 7     povString.append(", ");
 8     povString.append(point[0][1] * -1);
 9     povString.append(", ");
10     povString.append(point[0][2] * -1);
11     povString.append(">, <");
12     povString.append(point[1][0]);
13     povString.append(", ");
14     povString.append(point[1][1] * -1);
15     povString.append(", ");
16     povString.append(point[1][2] * -1);
17     povString.append(">, <");
18     povString.append(point[2][0]);
19     povString.append(", ");
20     povString.append(point[2][1] * -1);
21     povString.append(", ");
22     povString.append(point[2][2] * -1);
23     povString.append(">\n");
24     return povString;
25   }

Result is the pov file is now correct in the sense that normal camera positions (that are in front of screen) have a negative Z coordinate, and the test 'T' is displayed the right way up.

Processing to Povray with 'Y' axis correction?

This post has been superceded by the next post however it does include the test sketch, and the upside down test 'T' povray rendered image. 

I created a simple 'T' in processing (using box primitives) as a test file, here I am using my modified supercad library for a funkier look (should work just as well with th original supercad library):-

   1 import povwriter.*;               // a modified superCad library
   2                                   // povray export only draws mesh (ignores lines)
   3 String cadSoftware, ext;
   4 boolean record = false;
   5 
   6 void setup() {
   7   noStroke();
   8   size(400, 400, P3D);
   9 }
  10 
  11 void draw()
  12 {  
  13   if(record) {
  14     scale(1, -1, 1);              // perform Y axis inversion if record
  15     translate(0, height/4, 0);
  16     noLoop();
  17     beginRaw("povwriter."+cadSoftware, "output."+ext);
  18   }
  19   render();
  20   if (record) {
  21     endRaw();
  22     record = false;
  23     loop();
  24   }
  25 }
  26 
  27 void render() {
  28   pushMatrix();
  29   translate(width/2, height/2);
  30   box(100);
  31   translate(0, -100);
  32   box(100);
  33   translate(0, -100);
  34   box(100);
  35   translate(0, -100);
  36   box(100);
  37   translate(-100, 0);
  38   box(100);
  39   translate(200, 0);
  40   box(100);
  41   popMatrix();
  42 }
  43 
  44 void keyPressed() {
  45 
  46   switch(key) {
  47   case 'r': 
  48     cadSoftware = "Rhino"; 
  49     ext = "rvb"; 
  50     break;
  51   case 's': 
  52     cadSoftware = "SketchUP"; 
  53     ext = "rb";
  54     break;
  55   case 'a': 
  56     cadSoftware = "AutoLISP"; 
  57     ext = "lsp";
  58     break;
  59   case 'p': 
  60     cadSoftware = "PovRAY";    
  61     ext = "pov";  
  62     break;
  63   case 'm': 
  64     cadSoftware = "Maya"; 
  65     ext = "mel";
  66     break; 
  67   case 'o': 
  68     cadSoftware = "ObjFile"; 
  69     ext = "obj";
  70     break;       
  71   case 'c': 
  72     cadSoftware = "ArchiCAD"; 
  73     ext = "gdl";
  74     break;
  75   }  
  76   record = true;
  77 }

The "T" is upright in the processing sketch (albeit a bit over-sized). With the scale transformation the "T" is the right way up when rendered in povray without it is inverted. The "Z" direction does not want to play ball, and I don't understand why, but sometimes to view the object correctly I need to position the camera behind the screen (ie +ve 'Z' in povray).

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