Friday, April 02, 2010

Fun with Processing

Building on the brilliant work done by guru, I made my first baby steps into Processing this week.

Guru's code generates a grayscale image and then creates a height map from that image. Then it allows the height field to be exported to STL. This of course means that we can attempt to print it out on our MakerBot or RepRap.

For me the obivious next step was to modify the code slightly to allow any grayscale image (or any image at all) as input to the program, building a 3D object from a 2D graphic.

Here's what I came up with:


/**
generate a stl file from a heightfield

by Guru

modified by Dave Menninger
*/

import processing.opengl.*;
import unlekker.data.*;

PImage img;
STL stl;

void setup() {


size(640,480,OPENGL );
smooth();

img = loadImage("kashmir2_elev.jpg");

}

float a = 0;
boolean imgmode = true;
boolean rot = true;

void draw() {
background(0);
if ( imgmode ) {
image(img, 0,0, width, height );
} else {
lights();
fill(128);
stroke(128);
noStroke();
a += 0.01;
pushMatrix();
if (rot) translate( width/2, height/2 );
if (rot) rotateX( PI/2 );
if (rot) rotateZ(a);
img.loadPixels();

float h = 100;
float l = 10;

translate( 0, 0, -h + l );


if ( !rot ) stl=(STL)beginRaw("unlekker.data.STL","guru.stl");

for( int x = 0; x < img.width; x++) {
beginShape(TRIANGLE_STRIP);
for( int y = 0; y < img.height; y++) {
float h1 = map(brightness(img.pixels[ x+y*img.width]), 0,255, 0, l);
float h2 = h1;
if ( x < img.width - 1 && y > 0 ) {
h2 = map(brightness(img.pixels[ x+1+y*img.width]), 0,255, 0, l);
}
if ( x == img.width - 1 ){
h2 = 0;
}
if ( y == img.height - 1 ){
h2 = h1 = 0;
}
if ( x == 0 ){
h1 = 0;
}
if ( y == 0 ){
h2 = h1 = 0;
}

float x1 = map( x, 0, img.width, -100, 100 );
float y1 = map( y, 0, img.height, -100, 100 );
float z1 = h1 + 10;
vertex( x1, y1, z1 );

float x2 = map( x+1, 0, img.width, -100, 100 );
float y2 = map( y, 0, img.height, -100, 100 );
float z2 = h2 + 10;
vertex( x2, y2, z2 );
}
endShape();
}


beginShape(QUAD_STRIP);
vertex(-100, -100, 0);
vertex(-100, -100, 10);
vertex(100, -100, 0);
vertex(100,-100, 10);
vertex(100, 100, 0);
vertex(100, 100, 10);
vertex(-100, 100, 0);
vertex(-100, 100, 10);
vertex(-100, -100, 0);
vertex(-100, -100, 10);
endShape();

beginShape(TRIANGLE_STRIP);
vertex(-100, -100, 0);
vertex(100, -100, 0);
vertex(-100, 100,0);
vertex(100, 100, 0);

endShape();


if (!rot)
endRaw();
popMatrix();

}
}

void keyPressed() {
if (key == 'e') {
noLoop();
redraw();
rot = false;
a = 0;
redraw();

} else {
imgmode = !imgmode;
rot = true;
loop();
}
}


Here are some of the results I'm getting:














I should note that I haven't actually tried to print any of these yet. I'm hoping to tweak it to get slightly better models before I take that step.