Lithophanie
Lithophanie!
Non ca ne se mange pas. (Dommage crie Tuxun au fond)
Au détour d'un onglet sur instructables, je suis tombé sur un sketch Processing permettant de transformer des photos en fichier STL à imprimer en 3D.
Vu qu'on a deja quelques exemple grace au Captain mais vu que je n'en ai jamais fais, je me suis lancé. http://www.instructables.com/id/3D-Printed-Photograph/
préparation du sketch processing
- Installez Processing.
- Importez le sketch dispo sur cette page
import unlekker.util.*;
import unlekker.modelbuilder.*;
import unlekker.modelbuilder.filter.*;
import ec.util.*;
//image to 3d printable heightmap/lithophane
//by Amanda Ghassaei
//May 2013
//http://www.instructables.com/id/3D-Printed-Photograph/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*/
//libraries
import processing.opengl.*;
import unlekker.util.*;
import unlekker.modelbuilder.*;
import ec.util.*;
String name = "10897923_1024118977602140_6192734546186611880_n.jpg";//name of file (with extension, pngs will work too)
//storage for dimensions
int widthRes;
int heightRes;
float widthDim = 5;//width dimension (in inches)
float widthScaled;
float heightScaled;
float zDim = 0.1;//max vertical displacement (in inches)
float thickness = 0.02;//base thickness (in inches)
boolean invert = true;//if true, then white areas are lower than black, if not true white areas are taller
PImage img;//storage for image
float pixeldata[];//storage for pixel array
UVertexList v1,v2,v3,v4;//storage for verticies
UGeometry geo;//storage for stl geometry
void setup(){
img = loadImage(name);//load image
//get dimensions of image
widthRes = img.width;
heightRes =img.height;
size(widthRes,heightRes,P3D);//set dimensions of output
image(img, 0,0);//display image
loadPixels();//poad pixels into array
pixeldata = new float[widthRes*heightRes];//initialize storage for pixel data
for(int index=0;index<widthRes*heightRes;index++){
int getPixelData = pixels[index];//get data from pixels[] array
pixeldata[index] = getPixelData&255;//convert to greyscale byte (0-255)
}
//initialize storage for stl
geo = new UGeometry();
v1 = new UVertexList();
v2 = new UVertexList();
v3 = new UVertexList();
v4 = new UVertexList();
//draw stl
if(invert){
//draw top
for(int i=0;i<(heightRes-1);i++){
v1.reset();
v2.reset();
for(int j=0;j<widthRes;j++){
widthScaled = j/float(widthRes)*widthDim;
//top layer
v1.add(widthScaled,i/float(widthRes)*widthDim,(255-pixeldata[widthRes*i+j])*zDim/255+thickness);
v2.add(widthScaled,(i+1)/float(widthRes)*widthDim,(255-pixeldata[widthRes*(i+1)+j])*zDim/255+thickness);
}
geo.quadStrip(v1,v2);
}
//draw sides
v1.reset();
v2.reset();
v3.reset();
v4.reset();
for(int j=0;j<widthRes;j++){
widthScaled = j/float(widthRes)*widthDim;
v1.add(widthScaled,0,(255-pixeldata[j])*zDim/255+thickness);
v2.add(widthScaled,0,0);
v3.add(widthScaled,(heightRes-1)/float(widthRes)*widthDim,(255-pixeldata[widthRes*(heightRes-1)+j])*zDim/255+thickness);
v4.add(widthScaled,(heightRes-1)/float(widthRes)*widthDim,0);
}
geo.quadStrip(v2,v1);
geo.quadStrip(v3,v4);
//draw sides
v1.reset();
v2.reset();
v3.reset();
v4.reset();
for(int i=0;i<heightRes;i++){
heightScaled = i/float(widthRes)*widthDim;
v1.add(0,heightScaled,(255-pixeldata[widthRes*i])*zDim/255+thickness);
v2.add(0,heightScaled,0);
v3.add((widthRes-1)/float(widthRes)*widthDim,heightScaled,(255-pixeldata[widthRes*(i+1)-1])*zDim/255+thickness);
v4.add((widthRes-1)/float(widthRes)*widthDim,heightScaled,0);
}
geo.quadStrip(v1,v2);
geo.quadStrip(v4,v3);
}
else{
//draw top
for(int i=0;i<(heightRes-1);i++){
v1.reset();
v2.reset();
for(int j=0;j<widthRes;j++){
widthScaled = j/float(widthRes)*widthDim;
//top layer
v1.add(widthScaled,i/float(widthRes)*widthDim,(pixeldata[widthRes*i+j])*zDim/255+thickness);
v2.add(widthScaled,(i+1)/float(widthRes)*widthDim,(pixeldata[widthRes*(i+1)+j])*zDim/255+thickness);
}
geo.quadStrip(v1,v2);
}
//draw sides
v1.reset();
v2.reset();
v3.reset();
v4.reset();
for(int j=0;j<widthRes;j++){
widthScaled = j/float(widthRes)*widthDim;
v1.add(widthScaled,0,(pixeldata[j])*zDim/255+thickness);
v2.add(widthScaled,0,0);
v3.add(widthScaled,(heightRes-1)/float(widthRes)*widthDim,(pixeldata[widthRes*(heightRes-1)+j])*zDim/255+thickness);
v4.add(widthScaled,(heightRes-1)/float(widthRes)*widthDim,0);
}
geo.quadStrip(v2,v1);
geo.quadStrip(v3,v4);
//draw sides
v1.reset();
v2.reset();
v3.reset();
v4.reset();
for(int i=0;i<heightRes;i++){
heightScaled = i/float(widthRes)*widthDim;
v1.add(0,heightScaled,(pixeldata[widthRes*i])*zDim/255+thickness);
v2.add(0,heightScaled,0);
v3.add((widthRes-1)/float(widthRes)*widthDim,heightScaled,(pixeldata[widthRes*(i+1)-1])*zDim/255+thickness);
v4.add((widthRes-1)/float(widthRes)*widthDim,heightScaled,0);
}
geo.quadStrip(v1,v2);
geo.quadStrip(v4,v3);
}
//draw bottom
v1.reset();
v2.reset();
//add bottom four corners
v1.add(0,0,0);
v1.add(0,(heightRes-1)/float(widthRes)*widthDim,0);
v2.add((widthRes-1)/float(widthRes)*widthDim,0,0);
v2.add((widthRes-1)/float(widthRes)*widthDim,(heightRes-1)/float(widthRes)*widthDim,0);
geo.quadStrip(v1,v2);
//change extension of file name
int dotPos = name.lastIndexOf(".");
if (dotPos > 0)
name = name.substring(0, dotPos);
geo.writeSTL(this,name+".stl");
exit();
println("Finished");
}
- installez la lib suivante: Modelbuilder v0007a03 dans le dossier librairies de votre dossier sketchbook
- Vous devrez copier coller l'image voulu dans le dossier du sketch, ou bien utiliser l'outil de P5: sketch->add file
Enfin vous pourrez donner le nom de votre photo a manger au sketch P5 en modifiant cette ligne:
String name = "your_file_name_here.jpg"
execution
chez moi une fenetre vide s'est ouverte, j'en ai deduis que ma carte graphique était dans les choux ou non supporté (processing me disait d'ailleurs la même chose derrière, donc j'ai attendu,et genre 1 minute après la fenetre s'est fermée. laissant un STL dans son dossier et les messages dans processing:
libEGL warning: failed to create a pipe screen for i915
Smooth is not supported by this hardware (or driver)
03:58
03:58 ----------------------------------------------------------------------
03:58 Writing STL '10897923_1024118977602140_6192734546186611880_n.stl' 249806
03:58 Closing '10897923_1024118977602140_6192734546186611880_n.stl'. 249806 triangles written.
03:58
Finished
X11Util.Display: Shutdown (JVM shutdown: true, open (no close attempt): 1/1, reusable (open, marked uncloseable): 0, pending (open in creation order): 1)
X11Util: Open X11 Display Connections: 1
X11Util: Open[0]: NamedX11Display[:0.0, 0xffffffff9b7aef30, refCount 1, unCloseable false]
Et avec Cura?
Cura permet d'ouvrir des images et de le enregistrer en STL.